diff --git a/.factorypath b/.factorypath
new file mode 100644
index 0000000..22b58cf
--- /dev/null
+++ b/.factorypath
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..f811f6a
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+# Disable autocrlf on generated files, they always generate with LF
+# Add any extra files or paths here to make git stop saying they
+# are changed when only line endings change.
+src/generated/**/.cache/cache text eol=lf
+src/generated/**/*.json text eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2ded9a7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,27 @@
+# eclipse
+bin
+*.launch
+.settings
+.metadata
+.classpath
+.project
+
+# idea
+out
+*.ipr
+*.iws
+*.iml
+.idea
+
+# gradle
+build
+.gradle
+
+# other
+eclipse
+run
+
+# Files from Forge MDK
+forge*changelog.txt
+/.apt_generated/
+/Users/
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..0c24f84
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,171 @@
+buildscript {
+ repositories {
+ maven { url = 'https://files.minecraftforge.net/maven' }
+ jcenter()
+ mavenCentral()
+ maven {url='https://dist.creeper.host/Sponge/maven'}
+ }
+ dependencies {
+ classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
+ classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
+ }
+}
+apply plugin: 'net.minecraftforge.gradle'
+// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
+apply plugin: 'eclipse'
+apply plugin: 'maven-publish'
+apply plugin: 'org.spongepowered.mixin'
+
+version = '1.0'
+group = 'redd90.betternether' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
+archivesBaseName = 'betternether'
+
+sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
+
+println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
+minecraft {
+ // The mappings can be changed at any time, and must be in the following format.
+ // snapshot_YYYYMMDD Snapshot are built nightly.
+ // stable_# Stables are built at the discretion of the MCP team.
+ // Use non-default mappings at your own risk. they may not always work.
+ // Simply re-run your setup task after changing the mappings to update your workspace.
+ mappings channel: 'snapshot', version: '20201028-1.16.3'
+ // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
+
+ accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
+
+ // Default run configurations.
+ // These can be tweaked, removed, or duplicated as needed.
+ runs {
+ client {
+ property 'mixin.env.disableRefMap', 'true'
+ workingDirectory project.file('run')
+ arg "-mixin.config=betternether.mixins.json"
+
+ // Recommended logging data for a userdev environment
+ property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
+
+ // Recommended logging level for the console
+ property 'forge.logging.console.level', 'debug'
+
+ mods {
+ betternether {
+ source sourceSets.main
+ }
+ }
+ }
+
+ server {
+ property 'mixin.env.disableRefMap', 'true'
+ workingDirectory project.file('run')
+ arg "-mixin.config=betternether.mixins.json"
+
+ // Recommended logging data for a userdev environment
+ property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
+
+ // Recommended logging level for the console
+ property 'forge.logging.console.level', 'debug'
+
+ mods {
+ betternether {
+ source sourceSets.main
+ }
+ }
+ }
+
+ data {
+ property 'mixin.env.disableRefMap', 'true'
+ workingDirectory project.file('run')
+ arg "-mixin.config=betternether.mixins.json"
+
+ // Recommended logging data for a userdev environment
+ property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
+
+ // Recommended logging level for the console
+ property 'forge.logging.console.level', 'debug'
+
+ // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
+ args '--mod', 'betternether', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
+
+ mods {
+ betternether {
+ source sourceSets.main
+ }
+ }
+ }
+ }
+}
+
+// Include resources generated by data generators.
+sourceSets.main.resources { srcDir 'src/generated/resources' }
+
+repositories{
+ maven {url = "https://repo.spongepowered.org/maven/"}
+ maven {url = 'https://dist.creeper.host/Sponge/maven'}
+}
+
+dependencies {
+ // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
+ // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
+ // The userdev artifact is a special name and will get all sorts of transformations applied to it.
+ minecraft 'net.minecraftforge:forge:1.16.4-35.1.13'
+ compile 'org.spongepowered:mixin:0.8'
+ // 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
+
+ // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
+ // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
+
+ // These dependencies get remapped to your current MCP mappings
+ // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
+
+ // For more info...
+ // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
+ // http://www.gradle.org/docs/current/userguide/dependency_management.html
+
+}
+
+// Example for how to get properties into the manifest for reading by the runtime..
+jar {
+ manifest {
+ attributes([
+ "Specification-Title": "betternether",
+ "Specification-Vendor": "Redd90",
+ "Specification-Version": "1", // We are version 1 of ourselves
+ "Implementation-Title": project.name,
+ "Implementation-Version": "${version}",
+ "Implementation-Vendor" :"Redd90",
+ "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
+ "MixinConfigs": "betternether.mixins.json",
+ "MixinConnector":"redd90.betternether.mixin.MixinConnector"
+ ])
+ }
+}
+
+// Example configuration to allow publishing using the maven-publish task
+// This is the preferred method to reobfuscate your jar file
+jar.finalizedBy('reobfJar')
+// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
+//publish.dependsOn('reobfJar')
+
+publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ artifact jar
+ }
+ }
+ repositories {
+ maven {
+ url "file:///${project.projectDir}/mcmodsrepo"
+ }
+ }
+}
+
+mixin {
+ add sourceSets.main, "${modid}.refmap.json"
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..0c5c8ec
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,10 @@
+# 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=-Xmx3G
+org.gradle.daemon=false
+org.gradle.java.home=C:\\Program Files\\Java\\jdk-12.0.2
+
+mod_version=1.0
+modid=betternether
+mc_version=1.16.4
+forge_version=35.1.13
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
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 0000000..1d5b29f
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /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 0000000..f955316
--- /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/generated/resources/.cache/cache b/src/generated/resources/.cache/cache
new file mode 100644
index 0000000..5dd5e5b
--- /dev/null
+++ b/src/generated/resources/.cache/cache
@@ -0,0 +1,576 @@
+7fa0dfa9a0b883c8254f241fb56628141cc11e22 data/minecraft/advancements/recipes/betternether/anchor_tree_bark_from_anchor_tree_log.json
+e0908b06d66f354f1cb63c71fbd3dbb3a559a90d data/minecraft/advancements/recipes/betternether/anchor_tree_button_from_anchor_tree_planks.json
+4cfe6eec913915b61570f2510e3580779aa0d87d data/minecraft/advancements/recipes/betternether/anchor_tree_door_from_anchor_tree_planks.json
+6cbc1ad2f8d2721f88f89ef3633490ef064735fd data/minecraft/advancements/recipes/betternether/anchor_tree_fence_from_anchor_tree_planks.json
+6e03faa68e22c47585cf3773598776ea955ced28 data/minecraft/advancements/recipes/betternether/anchor_tree_gate_from_anchor_tree_planks.json
+d4297d4133d379dcc9c3b5455470b17113b412eb data/minecraft/advancements/recipes/betternether/anchor_tree_ladder_from_anchor_tree_planks.json
+857d85f42563a74a177343bd228a4f632def8f45 data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_bark.json
+ccf18b553c1a6e1359356e8007f9904d5a367e7b data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_log.json
+eaa162e38bcd3290bd80d9b6326035a1796e2f34 data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_bark_anchor_tree.json
+ae9e98cbc77fd21369e1c8222eb2bc271aea12aa data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_log_anchor_tree.json
+6d8ee57db709de01427e8bc85e6b2ef70c371ba5 data/minecraft/advancements/recipes/betternether/anchor_tree_plate_from_anchor_tree_planks.json
+66ca4126f5bddbc453e2b8ffc2ae6ecf0b73e60b data/minecraft/advancements/recipes/betternether/anchor_tree_slab_from_anchor_tree_planks.json
+502a2aa17f68f9ed34e423638a512e4f3b930121 data/minecraft/advancements/recipes/betternether/anchor_tree_stairs_from_anchor_tree_planks.json
+d554380266139f8ab679af1ea1f0ab757c3e3f49 data/minecraft/advancements/recipes/betternether/anchor_tree_trapdoor_from_anchor_tree_planks.json
+eb6ecc39361f68110eac821e08a3caf6a54e407e data/minecraft/advancements/recipes/betternether/bar_stool_acacia_from_acacia_slab.json
+d746cf14029e90a33ffbdb07bff3e043c7590631 data/minecraft/advancements/recipes/betternether/bar_stool_anchor_tree_from_anchor_tree_slab.json
+b724da326a62eedfd7a7caac30f294fdb288e7ba data/minecraft/advancements/recipes/betternether/bar_stool_birch_from_birch_slab.json
+54f90ab47281067b6ea7bef0be384e03365c0547 data/minecraft/advancements/recipes/betternether/bar_stool_cincinnasite_from_cincinnasite_slab.json
+1ccb9577583c1b683a7454e29fc03c595cde2989 data/minecraft/advancements/recipes/betternether/bar_stool_crimson_from_crimson_slab.json
+a013cca84495071abc260d87909d1d0758d1dcd9 data/minecraft/advancements/recipes/betternether/bar_stool_dark_oak_from_dark_oak_slab.json
+31775e45e2ee26ee8d45f9c81f9a85ddfaabd491 data/minecraft/advancements/recipes/betternether/bar_stool_jungle_from_jungle_slab.json
+16e6e80edf64206c9441ee48d3956ab285f09517 data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_fir_from_mushroom_fir_slab.json
+c875c3fbcf4e850232946e97b9f8096f50eb4226 data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_from_mushroom_slab.json
+6eadb58dff6537502a80fb604792c5a7911be036 data/minecraft/advancements/recipes/betternether/bar_stool_nether_sakura_from_nether_sakura_slab.json
+7b9ae203e930212a286adacd65843c03e44e6077 data/minecraft/advancements/recipes/betternether/bar_stool_oak_from_oak_slab.json
+9ede50d1f2bebfc45a5c1f843e6fc883a5a20853 data/minecraft/advancements/recipes/betternether/bar_stool_reeds_from_reeds_slab.json
+8d38fb34eb469d52afcbc4aea71efc8953de8d63 data/minecraft/advancements/recipes/betternether/bar_stool_rubeus_from_rubeus_slab.json
+8a53cb80a7d70c34e4ad2f145a35a9e09cb09e43 data/minecraft/advancements/recipes/betternether/bar_stool_spruce_from_spruce_slab.json
+e4f924aef9df749f4563014d2f0ea376beb0e8bd data/minecraft/advancements/recipes/betternether/bar_stool_stalagnate_from_stalagnate_planks_slab.json
+a97a89ce206017f892db439ac6dca41fa34f2c61 data/minecraft/advancements/recipes/betternether/bar_stool_warped_from_warped_slab.json
+06134110a19c08b7d6754b1881e4264aba7fbde1 data/minecraft/advancements/recipes/betternether/bar_stool_wart_from_wart_slab.json
+2f8549f5732d5f8f0bad05bf92650c988b3b85f5 data/minecraft/advancements/recipes/betternether/bar_stool_willow_from_willow_slab.json
+9814c422e15f4e7135ef12c631a0453a2474cd8e data/minecraft/advancements/recipes/betternether/barrel_anchor_tree_from_anchor_tree_planks.json
+ca6737e02c516b734cbe570ce167f9a1be4a0368 data/minecraft/advancements/recipes/betternether/barrel_crimson_from_crimson_planks.json
+2c24666fe9cc36ffc81e4947a617c37210fbb38d data/minecraft/advancements/recipes/betternether/barrel_mushroom_fir_from_mushroom_fir_planks.json
+eb349f6fa10c1f942281c9deb4654764bc87fe5d data/minecraft/advancements/recipes/betternether/barrel_mushroom_from_mushroom_planks.json
+d9b29ba067779fdbadaa24cbf5cb1489cd94c9a3 data/minecraft/advancements/recipes/betternether/barrel_nether_sakura_from_nether_sakura_planks.json
+e4b4b7c62c7fc190a4630575bb909ce5e257e2ed data/minecraft/advancements/recipes/betternether/barrel_reed_from_reeds_block.json
+f1038934bab5c13a247a70e45537a8368dccc371 data/minecraft/advancements/recipes/betternether/barrel_rubeus_from_rubeus_planks.json
+ecddc89128e7b5c81718334868486b8ed192c336 data/minecraft/advancements/recipes/betternether/barrel_stalagnate_from_stalagnate_planks.json
+b3f310c919e3b845e1dd211e84588aab8c020b82 data/minecraft/advancements/recipes/betternether/barrel_warped_from_warped_planks.json
+158a25ada7f229858320ec0ccad2dc7c428f80e7 data/minecraft/advancements/recipes/betternether/barrel_wart_from_wart_planks.json
+5c398de1f4e382fd5f19edd97a44f51d2f2f9d29 data/minecraft/advancements/recipes/betternether/barrel_willow_from_willow_planks.json
+f3c714628b858404df3fa269e4896fb8cfc31966 data/minecraft/advancements/recipes/betternether/basalt_bricks_from_polished_basalt.json
+558d5165fc479400ceda01fb2f286df686d94778 data/minecraft/advancements/recipes/betternether/basalt_bricks_slab_from_basalt_bricks.json
+d3e30af21eb0c22ad37c9bc0b55f5f7f18e4c193 data/minecraft/advancements/recipes/betternether/basalt_bricks_stairs_from_basalt_bricks.json
+9711de71d6c04fb7cc32db437719931f8e329f1d data/minecraft/advancements/recipes/betternether/basalt_bricks_wall_from_basalt_bricks.json
+9a389ea94b61587d6182eb656f6a0d886532ceb3 data/minecraft/advancements/recipes/betternether/basalt_furnace_from_basalt.json
+39e789435cf481776519e7179efc454272281c7a data/minecraft/advancements/recipes/betternether/basalt_slab_from_basalt.json
+01e809e8e55c390eec8c7600801b793357b06ae1 data/minecraft/advancements/recipes/betternether/basalt_stalactite_from_basalt.json
+c3990944bc35cd55fbc4586e06763feaa015083c data/minecraft/advancements/recipes/betternether/blackstone_furnace_from_blackstone.json
+669c6a4dfe6d48a172d2a4200ee22cc1582e0f33 data/minecraft/advancements/recipes/betternether/blackstone_stalactite_from_blackstone.json
+395c023d2bfef2c526cfa64a7c2561afcb539f05 data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json
+ba10e77553891dbaf56ec7e03167a21350dcfe2c data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json
+7f56337523422861337a9fec3ad11b1c813171eb data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json
+c4b2779c1d196e2275a2058878151475233b7425 data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json
+a4e3df2746ec352763ba2e43bb2f054732a96f09 data/minecraft/advancements/recipes/betternether/bone_button_from_bone_block.json
+3f313692db7cb0e3b3b29092eaebf0ff139df3dc data/minecraft/advancements/recipes/betternether/bone_plate_from_bone_block.json
+26685768695c5e8d1c5c3657c919ecd6f03ef922 data/minecraft/advancements/recipes/betternether/bone_slab_from_bone_block.json
+f0138c12723f97a85056c9fa97a95b4be4c2f131 data/minecraft/advancements/recipes/betternether/bone_stairs_from_bone_block.json
+86dba2e4af8a781534325c7e660cfab9b0cb7b7b data/minecraft/advancements/recipes/betternether/bone_stalactite_from_bone_block.json
+3be954dab4327bbb7cc5f0edb177b871f8a8028e data/minecraft/advancements/recipes/betternether/bone_wall_from_bone_block.json
+b4e94cf643aa1792e9750f1e4db3f30578af8832 data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_from_nether_brick_tile_large.json
+610e371a395716ebaf584f175eb6e110ab9247f5 data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_soul_from_nether_brick_tile_large.json
+16157f417257788b4290cae5cde7197a92d7a9aa data/minecraft/advancements/recipes/betternether/chair_acacia_from_acacia_slab.json
+5a4d3f8c8149e26d9bf07f4ebfc312f1f895b3bb data/minecraft/advancements/recipes/betternether/chair_anchor_tree_from_anchor_tree_slab.json
+4c5b424be45845f5a9ab43040d10fd2ac6ae21e7 data/minecraft/advancements/recipes/betternether/chair_birch_from_birch_slab.json
+a71d9372e93ab77e297ca3cbef8710d41d404da7 data/minecraft/advancements/recipes/betternether/chair_cincinnasite_from_cincinnasite_slab.json
+b64299cd91ec89d82a87160750b2862dcf5c99c1 data/minecraft/advancements/recipes/betternether/chair_crimson_from_crimson_slab.json
+b75c32828ad4ab5775402266f9172c6c43262c96 data/minecraft/advancements/recipes/betternether/chair_dark_oak_from_dark_oak_slab.json
+eab4bc7896d389ff89c4ee656e74ae9172ae8076 data/minecraft/advancements/recipes/betternether/chair_jungle_from_jungle_slab.json
+ce9aae5c0878ef71b5ad9eb4a2ed2d3ca537e24b data/minecraft/advancements/recipes/betternether/chair_mushroom_fir_from_mushroom_fir_slab.json
+29b20e7a99727720ff6cabe0b017dd4c9a474de6 data/minecraft/advancements/recipes/betternether/chair_mushroom_from_mushroom_slab.json
+dd21c7aefcb932417d60cad7b855602aed9131f1 data/minecraft/advancements/recipes/betternether/chair_nether_sakura_from_nether_sakura_slab.json
+f4fe67c3c53f43bc1b6bb29ff4c0c25b9406de0f data/minecraft/advancements/recipes/betternether/chair_oak_from_oak_slab.json
+84f70714366b30ded4af00ae41aeeeff2ed7c057 data/minecraft/advancements/recipes/betternether/chair_reeds_from_reeds_slab.json
+62009596b89a041fa8ec277110db8415e90cf143 data/minecraft/advancements/recipes/betternether/chair_rubeus_from_rubeus_slab.json
+e1cb886092f5121a3bcaa371893601ab8ae4f246 data/minecraft/advancements/recipes/betternether/chair_spruce_from_spruce_slab.json
+4ca99217f7dd09117da5d79f1e3616a9ef1cfb1d data/minecraft/advancements/recipes/betternether/chair_stalagnate_from_stalagnate_planks_slab.json
+cb6dd92322d5b6de7489a184308cb7ad6577759b data/minecraft/advancements/recipes/betternether/chair_warped_from_warped_slab.json
+a6c2336b20a1b313bdf44791361954e64b38c753 data/minecraft/advancements/recipes/betternether/chair_wart_from_wart_slab.json
+67e6efaeb3488cd87b3398d666993c322662ea12 data/minecraft/advancements/recipes/betternether/chair_willow_from_willow_slab.json
+32f6890fd4a422b2d6ac03da363676211c2fdd0a data/minecraft/advancements/recipes/betternether/chest_anchor_tree_from_anchor_tree_planks.json
+5ae882826468f245d6ae34b91ccda99af2003c59 data/minecraft/advancements/recipes/betternether/chest_crimson_from_crimson_planks.json
+a187d769e8d21960dd0ef0ec54f1381e06970059 data/minecraft/advancements/recipes/betternether/chest_mushroom_fir_from_mushroom_fir_planks.json
+f1b89aafa0134d04df6cb319559ec002dc42f48f data/minecraft/advancements/recipes/betternether/chest_mushroom_from_mushroom_planks.json
+7eff1734fd205802fc470485def94722c9e72c44 data/minecraft/advancements/recipes/betternether/chest_nether_sakura_from_nether_sakura_planks.json
+f5754d382a43543dd7ca841e36bdc9650f8fe5d0 data/minecraft/advancements/recipes/betternether/chest_reed_from_reeds_block.json
+48171136b51cd18a8df008e5fa75bc583d9f5a7a data/minecraft/advancements/recipes/betternether/chest_rubeus_from_rubeus_planks.json
+2e0439cc573a22468abecd2c981ef3fe58f666a0 data/minecraft/advancements/recipes/betternether/chest_stalagnate_from_stalagnate_planks.json
+067ea86cf21e487170ab563fd47fa16562639d2f data/minecraft/advancements/recipes/betternether/chest_warped_from_warped_planks.json
+561009e95b75c02cf94360672c1dc5fe7ed26572 data/minecraft/advancements/recipes/betternether/chest_wart_from_wart_planks.json
+366ff1d6df7134a69c17a5716de72aab4025ca4f data/minecraft/advancements/recipes/betternether/chest_willow_from_willow_planks.json
+0a0a6e27af183fdd35f41883d2ef039e0bec7334 data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_from_cincinnasite_forged.json
+2ecb01c4ed595b84857f26851563de87bd976ed5 data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json
+08bd7679f24bf1ce336a9eb736352c6ff57f0b09 data/minecraft/advancements/recipes/betternether/cincinnasite_plate_from_cincinnasite_forged.json
+e46c2a9f93c902a281105298ddbaec1779930078 data/minecraft/advancements/recipes/betternether/cincinnasite_slab_from_cincinnasite_forged.json
+01abae6b3c258278500e6faba3f0592ac78c7723 data/minecraft/advancements/recipes/betternether/cincinnasite_stairs_from_cincinnasite_forged.json
+bf310abc746c5fe60b749111ae1d9a3b2920e911 data/minecraft/advancements/recipes/betternether/cincinnasite_wall_from_cincinnasite_forged.json
+388652fb1f4d1ea01a4cd51a86296f22901d2078 data/minecraft/advancements/recipes/betternether/crafting_table_anchor_tree_from_anchor_tree_planks.json
+d44a3b74001144e39bb2752e1bac9a36fa889d03 data/minecraft/advancements/recipes/betternether/crafting_table_crimson_from_crimson_planks.json
+7d3840504f7bde5a7d8d1f51d3db8fbe7680b477 data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_fir_from_mushroom_fir_planks.json
+c8be81f64de0d30fed52bbe68c7915c29ac77982 data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_from_mushroom_planks.json
+58e55ce242dadc5e52d42df00172b4a6fd3c5e68 data/minecraft/advancements/recipes/betternether/crafting_table_nether_sakura_from_nether_sakura_planks.json
+6e4b6618ab6c9bd4050a185f452fdaafd0a5523c data/minecraft/advancements/recipes/betternether/crafting_table_reed_from_reeds_block.json
+29b703bf94dc25939731be4b63feb344c6f562ad data/minecraft/advancements/recipes/betternether/crafting_table_rubeus_from_rubeus_planks.json
+785fb5559cb04db65ef477f3664d6cd619cd440e data/minecraft/advancements/recipes/betternether/crafting_table_stalagnate_from_stalagnate_planks.json
+cad5101df28fccb065113d1900c32b54003ef65e data/minecraft/advancements/recipes/betternether/crafting_table_warped_from_warped_planks.json
+aa560078782452112d29bfbcc645f1410f1a0743 data/minecraft/advancements/recipes/betternether/crafting_table_wart_from_wart_planks.json
+3616220aea980ba20c5299e027ac039f16f30936 data/minecraft/advancements/recipes/betternether/crafting_table_willow_from_willow_planks.json
+4d9bc3fbcd136dfb74bd6aafabad375668602526 data/minecraft/advancements/recipes/betternether/crimson_ladder_from_crimson_planks.json
+6b791bb405885fce0570cc9f7a061f56f109b0a3 data/minecraft/advancements/recipes/betternether/glowstone_stalactite_from_glowstone.json
+068e07f7c67a558607da1c54d52d91b6986907fc data/minecraft/advancements/recipes/betternether/mushroom_button_from_mushroom_planks.json
+aa99aa3540ea5a05fccd5397a32b6ac7e417ad27 data/minecraft/advancements/recipes/betternether/mushroom_door_from_mushroom_planks.json
+8f604c572fd9cd09a87cf86ea4f96a68ba80b337 data/minecraft/advancements/recipes/betternether/mushroom_fence_from_mushroom_planks.json
+c17e181aa99d4f9ed09c1bd0ddac9980c5aeedf9 data/minecraft/advancements/recipes/betternether/mushroom_fir_button_from_mushroom_fir_planks.json
+f8533e526d078c3699df6d7492a1d3a6051345b8 data/minecraft/advancements/recipes/betternether/mushroom_fir_door_from_mushroom_fir_planks.json
+5607c52fae2f8ab527e7284cdfcd42bf00a5ddc3 data/minecraft/advancements/recipes/betternether/mushroom_fir_fence_from_mushroom_fir_planks.json
+dee52da82ac801f5f3ce9c9ad10a4d2dbafd82cc data/minecraft/advancements/recipes/betternether/mushroom_fir_gate_from_mushroom_fir_planks.json
+0ced1d92bbe8b448fbdf10bc47b87074b5e48885 data/minecraft/advancements/recipes/betternether/mushroom_fir_ladder_from_mushroom_fir_planks.json
+78df5c82891b00606c561cfbde17c6d2739a6d2f data/minecraft/advancements/recipes/betternether/mushroom_fir_log_from_mushroom_fir_stem.json
+b92701bb2d65bc90cd213580ad982e6415500ddd data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_log.json
+26a38dea24588378e3d2acb7877c6903896d147f data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_stem.json
+cca2f5bbb8749ef96d6a982c0fd9c019ef04fa1c data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_wood.json
+34d083848ee8f8954199f932cbde6a6568b54838 data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_log_mushroom_fir.json
+316ff20beda7f8bab460ee12141cdf475a90d7a1 data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_wood_mushroom_fir.json
+99e934e25e985e8d5cd264fe029de087d039b741 data/minecraft/advancements/recipes/betternether/mushroom_fir_plate_from_mushroom_fir_planks.json
+d5a7a5ddcac240404a8fbc51ceb520908878883e data/minecraft/advancements/recipes/betternether/mushroom_fir_slab_from_mushroom_fir_planks.json
+3b880b64660b675ba92f5ab70009ee087d217493 data/minecraft/advancements/recipes/betternether/mushroom_fir_stairs_from_mushroom_fir_planks.json
+f257b2ec2cd7226b29a0e8ef12651d48c9789228 data/minecraft/advancements/recipes/betternether/mushroom_fir_trapdoor_from_mushroom_fir_planks.json
+334687d02e309c7630a69d19c7073af7c6cd872b data/minecraft/advancements/recipes/betternether/mushroom_fir_wood_from_mushroom_fir_log.json
+e3750e62c04a2e0d71353dea549a5a188a910387 data/minecraft/advancements/recipes/betternether/mushroom_gate_from_mushroom_planks.json
+a5284269708944e1189191a518874fa4be3f33d5 data/minecraft/advancements/recipes/betternether/mushroom_ladder_from_mushroom_planks.json
+833b774a5c34da920de9a48c7aef39c1f1d5f93c data/minecraft/advancements/recipes/betternether/mushroom_planks_from_mushroom_stem.json
+ee27c989cc1dbe39dd878d776af293ccc6b1a5a9 data/minecraft/advancements/recipes/betternether/mushroom_plate_from_mushroom_planks.json
+ac8361314f67eedceed86b4341536a57d07bee50 data/minecraft/advancements/recipes/betternether/mushroom_slab_from_mushroom_planks.json
+b53390f9717eb8b5763fe0ac15859794e75013ce data/minecraft/advancements/recipes/betternether/mushroom_stairs_from_mushroom_planks.json
+1ef613745d3afb6b5cde29ff8013e7d2efc217b6 data/minecraft/advancements/recipes/betternether/mushroom_trapdoor_from_mushroom_planks.json
+e04ae18dbaa1a86fafdf08ca77bdc10d6e3504da data/minecraft/advancements/recipes/betternether/nether_brick_tile_slab_from_nether_brick_tile_small.json
+2666dbde1103ce732039e41fc809495b5c370f15 data/minecraft/advancements/recipes/betternether/nether_brick_tile_stairs_from_nether_brick_tile_small.json
+c95876ab9473c37994b92e917a96c7686a5265f5 data/minecraft/advancements/recipes/betternether/nether_brick_wall_from_nether_brick_tile_large.json
+5375215bf4b0958b89617af724eaf1a7df9b81b8 data/minecraft/advancements/recipes/betternether/nether_ruby_slab_from_nether_ruby_block.json
+49945f86dd19bf4d09a184dc4fad1e773507059e data/minecraft/advancements/recipes/betternether/nether_ruby_stairs_from_nether_ruby_block.json
+7671ddd59a381c0664bf26f36dfb34d4a01b18e4 data/minecraft/advancements/recipes/betternether/nether_sakura_bark_from_nether_sakura_log.json
+a401ba43b49587aa1c06cb051f58a79641b9689a data/minecraft/advancements/recipes/betternether/nether_sakura_button_from_nether_sakura_planks.json
+e660698b7d2da4bb1aeca4818963d0c5481ebd09 data/minecraft/advancements/recipes/betternether/nether_sakura_door_from_nether_sakura_planks.json
+3de2dd967de8d3a129afd73757eb816d643300c3 data/minecraft/advancements/recipes/betternether/nether_sakura_fence_from_nether_sakura_planks.json
+abdf6ad077980e1c493cd9406c994e8347f0ed7d data/minecraft/advancements/recipes/betternether/nether_sakura_gate_from_nether_sakura_planks.json
+2feb2a2f1afd732b54cdf5b26346ad55b4466997 data/minecraft/advancements/recipes/betternether/nether_sakura_ladder_from_nether_sakura_planks.json
+2f48bf31c30d7a96ad55562ade2c2a857d8a073b data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_bark.json
+0b477e165e54260cde2f1a6d891b834e632b96ae data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_log.json
+fbd223e1d3b9dacfdb98a2210f9d9194eb7cf57e data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_bark_nether_sakura.json
+e48ad2c5286a23fa7fdc5885d7157197180fda4e data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_log_nether_sakura.json
+0c40a2e5161e268c42816c0aeac93ec7e6ee9837 data/minecraft/advancements/recipes/betternether/nether_sakura_plate_from_nether_sakura_planks.json
+e87f6baa7d29d3bcf8dd947aa1f7937b3a32282e data/minecraft/advancements/recipes/betternether/nether_sakura_slab_from_nether_sakura_planks.json
+b78550ea3eed9ed89d5fa7c0eb9112e2e56c7cf1 data/minecraft/advancements/recipes/betternether/nether_sakura_stairs_from_nether_sakura_planks.json
+5eec17463a848a8db37d6993f49964f1e640d11d data/minecraft/advancements/recipes/betternether/nether_sakura_trapdoor_from_nether_sakura_planks.json
+6e09ef9d8d6cea10b02e8b8c383dfbc4edb06b9d data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_from_netherite_block.json
+55a96c7be31356792565d5634ea320dfb441d786 data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_soul_from_netherite_block.json
+b1de7754ca19558fcabbc498dbcd756430d400d7 data/minecraft/advancements/recipes/betternether/netherrack_furnace_from_netherrack.json
+e713becfdf1d2e1d5181e53bea919e442195ff7f data/minecraft/advancements/recipes/betternether/netherrack_stalactite_from_netherrack.json
+d192a1038817fc7dd9b8d7fcdd2657227c444ff8 data/minecraft/advancements/recipes/betternether/obsidian_bricks_slab_from_obsidian_bricks.json
+4fcde1a8ae773672fd7e5847945180f6a24b8f5e data/minecraft/advancements/recipes/betternether/obsidian_bricks_stairs_from_obsidian_bricks.json
+035c3c7d232d4a411c5eaac3a5eef699798b9777 data/minecraft/advancements/recipes/betternether/obsidian_tile_slab_from_obsidian_tile_small.json
+01e9d84bb0b8f2d546564df636795dbf0ab1b3d8 data/minecraft/advancements/recipes/betternether/obsidian_tile_stairs_from_obsidian_tile_small.json
+f4723846c7243dc3e6253e0a0071262afd1047a5 data/minecraft/advancements/recipes/betternether/reeds_button_from_reeds_block.json
+ee4da387402316eb0e7d0065ec5d24fa5a76b2f1 data/minecraft/advancements/recipes/betternether/reeds_door_from_reeds_block.json
+c1450e82d14ffa5e1802397ffa11fa55bc080545 data/minecraft/advancements/recipes/betternether/reeds_fence_from_reeds_block.json
+ed21490fe04dfae05099f16889a7c8997766ceb9 data/minecraft/advancements/recipes/betternether/reeds_gate_from_reeds_block.json
+faea2f52d0ee716052ca34ea66c149e98a13ef00 data/minecraft/advancements/recipes/betternether/reeds_ladder_from_reeds_block.json
+f45d20fa53c6d8fc351f995199505af91f425e08 data/minecraft/advancements/recipes/betternether/reeds_plate_from_reeds_block.json
+d581ec171cb0b0ef12fb6d5828f2cb6dfb03c815 data/minecraft/advancements/recipes/betternether/reeds_slab_from_reeds_block.json
+8f70df5b508d7181b4a8da45e183a5df0fe8eaf5 data/minecraft/advancements/recipes/betternether/reeds_stairs_from_reeds_block.json
+ec25803d0b3b2894b241d339d860605399aa83b3 data/minecraft/advancements/recipes/betternether/reeds_trapdoor_from_reeds_block.json
+73dcb8e93216b1a1c721b51ff5db97b00fd0d386 data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_from_cincinnasite_forged.json
+175aa4e87910854ea46ee6e1041b37fb74f3fefb data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json
+41d849256c04c1a149034facf0ff0b3221d85372 data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json
+a321cff883cd97e6b04905b11d51a3180801f96f data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_from_nether_bricks.json
+aab5dc6963c28241e5d389e9afca4aa07e3ff6eb data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json
+de11e6bba31dd88412115866a160e1c3c98f73ae data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json
+5cb3ac97e43a94fdaa726d5f8033bbdc847e944c data/minecraft/advancements/recipes/betternether/roof_tile_reeds_from_reeds_block.json
+5aae8fd51325dfa3762fbbaa0987493ddce70395 data/minecraft/advancements/recipes/betternether/roof_tile_reeds_slab_from_roof_tile_reeds.json
+befeabeaabd30b134369d011a829d3dd5b64d407 data/minecraft/advancements/recipes/betternether/roof_tile_reeds_stairs_from_roof_tile_reeds.json
+a9cf4d1650afd20095f55d83a8f849689e63cad9 data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_from_stalagnate_planks.json
+88b756a01b40019796780655f3c24cf6eab8d550 data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json
+db175c3675bbe9a93007c77e1451c1e5eabb87f2 data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json
+55d7b4a8331ec021df0571e6b122aec7b84143fe data/minecraft/advancements/recipes/betternether/roof_tile_wart_from_wart_planks.json
+afe65c1b7c0dfe27cce9431dbb0a230701817316 data/minecraft/advancements/recipes/betternether/roof_tile_wart_slab_from_roof_tile_wart.json
+3bffea5dcad40054d5b1969a79ddcfc81d286522 data/minecraft/advancements/recipes/betternether/roof_tile_wart_stairs_from_roof_tile_wart.json
+4eada6f02061c7e500827fadbd423156af02262b data/minecraft/advancements/recipes/betternether/roof_tile_willow_from_willow_planks.json
+ff1e109af92a01015915ff8fd5eb083639f4a392 data/minecraft/advancements/recipes/betternether/roof_tile_willow_slab_from_roof_tile_willow.json
+b8876adfcda13ed19f8b5a354b208a087e1d3458 data/minecraft/advancements/recipes/betternether/roof_tile_willow_stairs_from_roof_tile_willow.json
+41e6180f2b374739ee589c77635c23929bc816f3 data/minecraft/advancements/recipes/betternether/rubeus_bark_from_rubeus_log.json
+784a3084a1d2b00d1cb21940d74e7e167d43fc3d data/minecraft/advancements/recipes/betternether/rubeus_button_from_rubeus_planks.json
+6b9788c47aa430934ce8af94372857c9cf53788e data/minecraft/advancements/recipes/betternether/rubeus_door_from_rubeus_planks.json
+37179c35dc486b21b7b441ecc34e1f3328c79d10 data/minecraft/advancements/recipes/betternether/rubeus_fence_from_rubeus_planks.json
+edb7dcba2aa7e4a4b246fa4e9128d22570c69c48 data/minecraft/advancements/recipes/betternether/rubeus_gate_from_rubeus_planks.json
+b8d8ece15696cdf65b3540a03392e55642048f21 data/minecraft/advancements/recipes/betternether/rubeus_ladder_from_rubeus_planks.json
+581b546c59e8ad740d2c6d5dd84ad05af0a18265 data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_bark.json
+99f76035f09c1d1ebd28fde1fe5777da5815b7bb data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_log.json
+913281e913d614b648659294f74647f4d6ac6325 data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_bark_rubeus.json
+93d91fd2b6cc4642c0c386afc451bfdc410053bb data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_log_rubeus.json
+f99ca40638b1229df70271b050ab59a517a613d3 data/minecraft/advancements/recipes/betternether/rubeus_plate_from_rubeus_planks.json
+5c15dfdb490b049b2814654ce572eb1935c90633 data/minecraft/advancements/recipes/betternether/rubeus_slab_from_rubeus_planks.json
+e0edd2763c9a4a4a0e38917fe76d65cb8052ef2d data/minecraft/advancements/recipes/betternether/rubeus_stairs_from_rubeus_planks.json
+8f230fdc2d4010da56cf816f460c710e91a50ae4 data/minecraft/advancements/recipes/betternether/rubeus_trapdoor_from_rubeus_planks.json
+1340b44eb95720311c95ddc0c30377d496ddf379 data/minecraft/advancements/recipes/betternether/sign_anchor_tree_from_anchor_tree_planks.json
+19660a514ddfb2dbce9d23510cabfcd685956a81 data/minecraft/advancements/recipes/betternether/sign_mushroom_fir_from_mushroom_fir_planks.json
+14ae5e090d3a46b02d0cbec427b9732cd5268e25 data/minecraft/advancements/recipes/betternether/sign_mushroom_from_mushroom_planks.json
+6de3346cf4ffdfe06d6684f8b2da53b96e0f490e data/minecraft/advancements/recipes/betternether/sign_nether_sakura_from_nether_sakura_planks.json
+fe679188711e7e5607a1bc91c542edd5cfcad138 data/minecraft/advancements/recipes/betternether/sign_reed_from_reeds_block.json
+8c25e0d98de80866fb4ba2bfcb238173ca4250c4 data/minecraft/advancements/recipes/betternether/sign_rubeus_from_rubeus_planks.json
+5c33d35ed1a5600d7c4969c6a7d9d04502db8d3c data/minecraft/advancements/recipes/betternether/sign_stalagnate_from_stalagnate_planks.json
+2ad21ea1e2b53772f07865e22efad62eb6b66a5f data/minecraft/advancements/recipes/betternether/sign_wart_from_wart_planks.json
+da8027bb5631525d909b8a56b06a17d567dc6b41 data/minecraft/advancements/recipes/betternether/sign_willow_from_willow_planks.json
+4094f91fa686568f8d59529d36a6ceef9ab97069 data/minecraft/advancements/recipes/betternether/soul_sandstone_chiseled_from_soul_sandstone_smooth.json
+0dfcbec4a67374f5c97871ddb574301ca63ad732 data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_from_soul_sandstone.json
+42119bcebf6aec0bcb16ebb9c7ae3f5322db23ca data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_slab_from_soul_sandstone_cut.json
+fc96d10d7d04aabafb60e511866d4642b25b9f4b data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json
+f487f9c5ce4ec206dfc30acc6013f33ead33822a data/minecraft/advancements/recipes/betternether/soul_sandstone_slab_from_soul_sandstone.json
+2b9ad225f2644163947751b1e19fa5765ffc1fb0 data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_from_soul_sandstone_cut.json
+1dd0d537adb652eb6efb598935136689438cd9e9 data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json
+5a646cc5022017ea22f6d50aa24fc7a4d77f1fb6 data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json
+f3eed368d3fcdd94b19980c21f4b9e41dfd6de73 data/minecraft/advancements/recipes/betternether/soul_sandstone_stairs_from_soul_sandstone.json
+a5056111365d269b03cc43ca453e6afc0c24ec60 data/minecraft/advancements/recipes/betternether/soul_sandstone_wall_from_soul_sandstone_cut.json
+d64fcb341650aa6facb9031997cb87011a9ea3c8 data/minecraft/advancements/recipes/betternether/stalagnate_bark_from_stalagnate_log.json
+71b8394579c301692622e429beeae33c6f66e656 data/minecraft/advancements/recipes/betternether/stalagnate_ladder_from_stalagnate_planks.json
+36d8bfd4a89def27b7fe4f74934b69db642c60ae data/minecraft/advancements/recipes/betternether/stalagnate_log_from_stalagnate_stem.json
+df213cd2e9b532f313fddbf914bf21fc15eba9cf data/minecraft/advancements/recipes/betternether/stalagnate_planks_button_from_stalagnate_planks.json
+86e5d1c09daa651418d3ef126a7b2b5486f750f8 data/minecraft/advancements/recipes/betternether/stalagnate_planks_door_from_stalagnate_planks.json
+2eda63ab5bc1566c50507840d632395bc6068dfb data/minecraft/advancements/recipes/betternether/stalagnate_planks_fence_from_stalagnate_planks.json
+04d59c8fd07516ff364c2689e4a5cc3804a155ec data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_bark.json
+f46439743cbbae4451bf8d551012366b3af425b3 data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_log.json
+56b096276d54dba40bd4942b9fde5f8d64f36cc0 data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_stem.json
+66719b234d3d3b8da07c64b300456218e597c3ad data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_bark_stalagnate.json
+6daf1a1b3476eb394e5e1f13e250dad31f2fef88 data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_log_stalagnate.json
+7938a34ff803b076aff04451d62215be3dc818f6 data/minecraft/advancements/recipes/betternether/stalagnate_planks_gate_from_stalagnate_planks.json
+d5f3fa82ec327042cdcda6cd6601798ac11b1738 data/minecraft/advancements/recipes/betternether/stalagnate_planks_plate_from_stalagnate_planks.json
+2860016cf06ac909d698e09dadb961f8f327f24c data/minecraft/advancements/recipes/betternether/stalagnate_planks_slab_from_stalagnate_planks.json
+3e11fdee0d2bc0fc6129e6cc1ed97e3db94b5002 data/minecraft/advancements/recipes/betternether/stalagnate_planks_stairs_from_stalagnate_planks.json
+ac38296aefecd5190f6579fcfdcc54c5c975247d data/minecraft/advancements/recipes/betternether/stalagnate_planks_trapdoor_from_stalagnate_planks.json
+ed80ee2ae981c5afa2d2f364bda2913c43dc44d1 data/minecraft/advancements/recipes/betternether/taburet_acacia_from_acacia_slab.json
+8170202e4dc40a6af33797e08eb17b89a6319a3a data/minecraft/advancements/recipes/betternether/taburet_anchor_tree_from_anchor_tree_slab.json
+cf15fac8fdb181ded55c6b3a075ac6acc68747e8 data/minecraft/advancements/recipes/betternether/taburet_birch_from_birch_slab.json
+288e655895c870160f45240c9e8706f483af1358 data/minecraft/advancements/recipes/betternether/taburet_cincinnasite_from_cincinnasite_slab.json
+790d4c4a1c7229e2df414924141daa410623af12 data/minecraft/advancements/recipes/betternether/taburet_crimson_from_crimson_slab.json
+a091b6cff8755f0ceb37e4454421113e51344abb data/minecraft/advancements/recipes/betternether/taburet_dark_oak_from_dark_oak_slab.json
+35a3e1ab354c9aeb17e2d2e7bc747ad9b61ee02f data/minecraft/advancements/recipes/betternether/taburet_jungle_from_jungle_slab.json
+ae5f5ca02ffe947ef14ff5629e55b431cba8695b data/minecraft/advancements/recipes/betternether/taburet_mushroom_fir_from_mushroom_fir_slab.json
+c91e3c1f1771171e2824bf033dd9ae19d9ff50e2 data/minecraft/advancements/recipes/betternether/taburet_mushroom_from_mushroom_slab.json
+f85bde404da6e1503958b14a3ce18b78fcb578ae data/minecraft/advancements/recipes/betternether/taburet_nether_sakura_from_nether_sakura_slab.json
+9f4fdc9fe80177d910684c3d64897e42e27d1cdd data/minecraft/advancements/recipes/betternether/taburet_oak_from_oak_slab.json
+cfe24998d6639038dab4faa13fce24a17bbd68e7 data/minecraft/advancements/recipes/betternether/taburet_reeds_from_reeds_slab.json
+3d227b530dba9af072f99b95a5598ad7436352cb data/minecraft/advancements/recipes/betternether/taburet_rubeus_from_rubeus_slab.json
+04e97c9531dfaa7541519e9774dbdc5be35a61fe data/minecraft/advancements/recipes/betternether/taburet_spruce_from_spruce_slab.json
+65735e57309a476a4e5866a1ef478d4a9c9b2e39 data/minecraft/advancements/recipes/betternether/taburet_stalagnate_from_stalagnate_planks_slab.json
+c78f7ece01056f643e04992893097d4616a3a2ab data/minecraft/advancements/recipes/betternether/taburet_warped_from_warped_slab.json
+703e35e3847421fc0ec1786657d00e3dcebede6b data/minecraft/advancements/recipes/betternether/taburet_wart_from_wart_slab.json
+1fa6e9f40af3334298d8676326cd4b467efb326d data/minecraft/advancements/recipes/betternether/taburet_willow_from_willow_slab.json
+9a837646a0bdfe46ed1b25a23bd3fa382b5f52ac data/minecraft/advancements/recipes/betternether/warped_ladder_from_warped_planks.json
+bb26a5cd0f54614382524c154b00292ff7faabef data/minecraft/advancements/recipes/betternether/wart_bark_from_wart_log.json
+07bd69524bcda5c8b4cd352fd4a8a2e451f9876b data/minecraft/advancements/recipes/betternether/wart_button_from_wart_planks.json
+b220b21cf6eab86741394b6a8602c8f3a6fc8346 data/minecraft/advancements/recipes/betternether/wart_door_from_wart_planks.json
+b8fcf1a19d183fb2f280f9d037bc33953b17a62b data/minecraft/advancements/recipes/betternether/wart_fence_from_wart_planks.json
+fa0513cce9935988f3c00bb8ac5aa74990d04fd0 data/minecraft/advancements/recipes/betternether/wart_gate_from_wart_planks.json
+f81a988df0479cd9a4989536409b2846dd46a237 data/minecraft/advancements/recipes/betternether/wart_ladder_from_wart_planks.json
+270c5bd36b8979a42ea7f9c7316251489c943089 data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_bark_wart.json
+89952de7d8120443697140a48291ffd3d2249f06 data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_log_wart.json
+ce5b6e0ebe33061b6e837bad696a2d52bf558188 data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_bark.json
+1297da0c764b9d1dac248cf489c11ae840a947b0 data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_log.json
+5a486e00ae65ff67c98a34f300bdfde6aa419bba data/minecraft/advancements/recipes/betternether/wart_plate_from_wart_planks.json
+f39fff1849cc98ea36200c0ff27636c06db9301e data/minecraft/advancements/recipes/betternether/wart_slab_from_wart_planks.json
+451b46c80346aec9a5e8ad4555e211756135c485 data/minecraft/advancements/recipes/betternether/wart_stairs_from_wart_planks.json
+59ddcf95e093977bac90dd2eb6b9022384250554 data/minecraft/advancements/recipes/betternether/wart_trapdoor_from_wart_planks.json
+7657dde5940a3d0ef545a69a7e59800851f31e86 data/minecraft/advancements/recipes/betternether/willow_bark_from_willow_log.json
+2c335861daa7a893ae67d48873042dc84a08ba98 data/minecraft/advancements/recipes/betternether/willow_button_from_willow_planks.json
+fb808c1a340cbbe7e8642c33c0e86c0d730fc985 data/minecraft/advancements/recipes/betternether/willow_door_from_willow_planks.json
+e49f12c1166687c220df73ecdfb7a61fd78a3d9d data/minecraft/advancements/recipes/betternether/willow_fence_from_willow_planks.json
+08a4d44a581c25b955ed189cc3ac0b5863daadc6 data/minecraft/advancements/recipes/betternether/willow_gate_from_willow_planks.json
+c272385159d060fe70e8a2cadc3182f36f28b7d8 data/minecraft/advancements/recipes/betternether/willow_ladder_from_willow_planks.json
+c16f08a3ea827f2242796378320410974339628f data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_bark_willow.json
+3dd307636b8a6ab222575f2c94f2d2ac229040a1 data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_log_willow.json
+4d430d7013a4ce01c08214dd2d97beb19be28442 data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_bark.json
+3c5d2a493fc8724a655092dd9ab297304278654c data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_log.json
+ffce405b57ae8506e738eb99709405b917862f55 data/minecraft/advancements/recipes/betternether/willow_plate_from_willow_planks.json
+55b06d7b51351f329a8f724c3f7528e02bb0560b data/minecraft/advancements/recipes/betternether/willow_slab_from_willow_planks.json
+272edcb97d0844548ec6b868c0002782152e4ae8 data/minecraft/advancements/recipes/betternether/willow_stairs_from_willow_planks.json
+467462c6731c7312b7997824e6937d106cac72e6 data/minecraft/advancements/recipes/betternether/willow_trapdoor_from_willow_planks.json
+270e2342ddfd5fa0d9a3082843c5388c145c4b87 data/minecraft/recipes/anchor_tree_bark_from_anchor_tree_log.json
+3f484dcb30ff95a3950391922b87047e02cdd9cc data/minecraft/recipes/anchor_tree_button_from_anchor_tree_planks.json
+1084df1ac97960bf6512215b813bf7e4f7b031a2 data/minecraft/recipes/anchor_tree_door_from_anchor_tree_planks.json
+efefe8fac0b7d5220343aab9fde4c15959dc4dc9 data/minecraft/recipes/anchor_tree_fence_from_anchor_tree_planks.json
+a4bab1f9a8c48587b3c800ae32d7797835e19f6b data/minecraft/recipes/anchor_tree_gate_from_anchor_tree_planks.json
+a3c2927246fe74bd178632f8eea288c255ee77a8 data/minecraft/recipes/anchor_tree_ladder_from_anchor_tree_planks.json
+ec995e744a8573b03d9c803bd401d37a7aa50a2b data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_bark.json
+2423669d598bd338d8bc7af1c52cb2edcdc777fc data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_log.json
+2f183398f991f1603b4f4262d6a44d654cf085a4 data/minecraft/recipes/anchor_tree_planks_from_striped_bark_anchor_tree.json
+3acf8a770201b10d122e7a9a05783fa5b31f54bd data/minecraft/recipes/anchor_tree_planks_from_striped_log_anchor_tree.json
+8fb2835a22df0ef017994a7470bc3fc797a32cb5 data/minecraft/recipes/anchor_tree_plate_from_anchor_tree_planks.json
+fc77357b2e9b9e21bb3527fd2b2bdcb05963dad8 data/minecraft/recipes/anchor_tree_slab_from_anchor_tree_planks.json
+c98d5416126d4c933553cae519e516d38d1c43b1 data/minecraft/recipes/anchor_tree_stairs_from_anchor_tree_planks.json
+e28bfc44d03a2bc736d3fa07bc00a2a2319149a7 data/minecraft/recipes/anchor_tree_trapdoor_from_anchor_tree_planks.json
+12f292f8427226b0b98b636e41a31c63e87c3575 data/minecraft/recipes/bar_stool_acacia_from_acacia_slab.json
+ab5fd4f88935a1c8e52b46eda4be1849a1b12945 data/minecraft/recipes/bar_stool_anchor_tree_from_anchor_tree_slab.json
+990ac9fd5b4c4c326dd91dbe1c73083557d1d484 data/minecraft/recipes/bar_stool_birch_from_birch_slab.json
+7f76f42a5ce8a4c98c05388864677b7923f960c4 data/minecraft/recipes/bar_stool_cincinnasite_from_cincinnasite_slab.json
+326294361335e1e875181be38f5eec5be5ad344c data/minecraft/recipes/bar_stool_crimson_from_crimson_slab.json
+050df027992d3e27fc9ff378144fa932afb134f7 data/minecraft/recipes/bar_stool_dark_oak_from_dark_oak_slab.json
+dbf43f21e2275d58837c552b2ecfbf218932677c data/minecraft/recipes/bar_stool_jungle_from_jungle_slab.json
+bff85f2fa02454a79531ffdfb72eebd6c360d603 data/minecraft/recipes/bar_stool_mushroom_fir_from_mushroom_fir_slab.json
+7242a0508b17f90445201ba65e60d70b6c54b2ad data/minecraft/recipes/bar_stool_mushroom_from_mushroom_slab.json
+bf830ea69e607140e15c23a1126c06bed230fe3b data/minecraft/recipes/bar_stool_nether_sakura_from_nether_sakura_slab.json
+e2830c740a9ae8c9df5e58d32a6a106206ee6cef data/minecraft/recipes/bar_stool_oak_from_oak_slab.json
+20bbb6696045148d71dace1b34c5e82766f432cb data/minecraft/recipes/bar_stool_reeds_from_reeds_slab.json
+f68675c5a7112798a89d6ee3265837cdf550ee0c data/minecraft/recipes/bar_stool_rubeus_from_rubeus_slab.json
+4e1b4634674d96bf6b66bb62c8f5d1f5e1962a41 data/minecraft/recipes/bar_stool_spruce_from_spruce_slab.json
+26e8dba822ed3096b3c1c1f07d18411a84975a2f data/minecraft/recipes/bar_stool_stalagnate_from_stalagnate_planks_slab.json
+915e2e5414683f599d6ad2702661f365e8c4fac2 data/minecraft/recipes/bar_stool_warped_from_warped_slab.json
+150eb60eb4a785e36516ecc83a463a1b73c8eb4f data/minecraft/recipes/bar_stool_wart_from_wart_slab.json
+b24cdfde1aca0e9ff5bea9ca860707c65810ae9f data/minecraft/recipes/bar_stool_willow_from_willow_slab.json
+ce01d9911aef2ba837020b3258d63cb54c165183 data/minecraft/recipes/barrel_anchor_tree_from_anchor_tree_planks.json
+da76c5174a4659fdb58bfc671979cd4d7addcf6f data/minecraft/recipes/barrel_crimson_from_crimson_planks.json
+c43bd8ff7c3a12debe34a44a2e79b69980142c85 data/minecraft/recipes/barrel_mushroom_fir_from_mushroom_fir_planks.json
+3ea4f0d1dc89fb0d9c6caa73cd8a73084cd55a65 data/minecraft/recipes/barrel_mushroom_from_mushroom_planks.json
+090763dcd16ee67a1c15f04805ba51d718fea711 data/minecraft/recipes/barrel_nether_sakura_from_nether_sakura_planks.json
+f1cc1aec889a3df26ce532d75266ac334ad25fb6 data/minecraft/recipes/barrel_reed_from_reeds_block.json
+160ccfdbf0f295f87ca26f5cd5337f39862c9df9 data/minecraft/recipes/barrel_rubeus_from_rubeus_planks.json
+3e1d25160db03b8739045e7dca58837d8ec7f958 data/minecraft/recipes/barrel_stalagnate_from_stalagnate_planks.json
+528f263423ca5ccc9bc9aa74eb79d6d43e70940e data/minecraft/recipes/barrel_warped_from_warped_planks.json
+c12e679ebbeac3990f153d5368a2f29774fc084f data/minecraft/recipes/barrel_wart_from_wart_planks.json
+a6eb971e97c467841f77ea56e792d33b07288802 data/minecraft/recipes/barrel_willow_from_willow_planks.json
+3e41c08276344ea1bcaed75d05b52575638a45b3 data/minecraft/recipes/basalt_bricks_from_polished_basalt.json
+47e9d65601006fbfa4309b067343df451cb5eed1 data/minecraft/recipes/basalt_bricks_slab_from_basalt_bricks.json
+3d183d41c8e905ae92dab93f4fb3ad8ef4839471 data/minecraft/recipes/basalt_bricks_stairs_from_basalt_bricks.json
+39b4e7919a2ab346280edd070addf5a057aa374d data/minecraft/recipes/basalt_bricks_wall_from_basalt_bricks.json
+33acdf8cbe93d90a1aa8e59b7cb18f9ae02899c1 data/minecraft/recipes/basalt_furnace_from_basalt.json
+83b6854214049b308528a4cc24d9855bf69d393e data/minecraft/recipes/basalt_slab_from_basalt.json
+73e4e8a4574608c944daa98d79c744bad335bf2c data/minecraft/recipes/basalt_stalactite_from_basalt.json
+83a6b1f3debdaec4cee35c1972bf0ebb7155d957 data/minecraft/recipes/blackstone_furnace_from_blackstone.json
+67ca6477d9e996c7ecd87352ae5cfe1579bc3f68 data/minecraft/recipes/blackstone_stalactite_from_blackstone.json
+816e1663eb07f8777ef3d7349f6877fb49bda64d data/minecraft/recipes/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json
+14657e5fd0b7dbe38212a3279e80330b89eb1972 data/minecraft/recipes/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json
+7861e4c711bfb5dd564b48eb8d3fac74251893e8 data/minecraft/recipes/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json
+7b42ded31fbefca01bfd873cd15e8c51d9beb0ef data/minecraft/recipes/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json
+6817b3bbdb69695c9d64cf4aef2c3034224940fb data/minecraft/recipes/bone_button_from_bone_block.json
+83ba05827be2ee9ef72f8ece470d7df31ea8d1d8 data/minecraft/recipes/bone_plate_from_bone_block.json
+382f9517a31774dec2b98989ef7a2224152b001b data/minecraft/recipes/bone_slab_from_bone_block.json
+d289a47a6210bc9b65a88da87fb92b5194c42ff9 data/minecraft/recipes/bone_stairs_from_bone_block.json
+f30bb142ff45d476c6497411b0741f1807e89e44 data/minecraft/recipes/bone_stalactite_from_bone_block.json
+9793445ff90125d3c699e3be570fff76c76abab5 data/minecraft/recipes/bone_wall_from_bone_block.json
+be708199a2bd1df7f9531681d3fbcff9ce412966 data/minecraft/recipes/bricks_fire_bowl_from_nether_brick_tile_large.json
+b25c36f4747f0ca5ef071501521b38f62883a22f data/minecraft/recipes/bricks_fire_bowl_soul_from_nether_brick_tile_large.json
+f6bd5fdbba5f8682c25d4dd186d266aec8d3425a data/minecraft/recipes/chair_acacia_from_acacia_slab.json
+e4ffe43279baeb087878b06c8006d75e1b374bb9 data/minecraft/recipes/chair_anchor_tree_from_anchor_tree_slab.json
+228c228065e782818675c2e134374d815e6653cd data/minecraft/recipes/chair_birch_from_birch_slab.json
+43d687b0cb57e594aae45ecbe1e19680ccca8ee2 data/minecraft/recipes/chair_cincinnasite_from_cincinnasite_slab.json
+e76b179cc0fe8899e40d8ce89843e01b0fbb012a data/minecraft/recipes/chair_crimson_from_crimson_slab.json
+93982caef1f222a195c3bfd1929fb83e193678e9 data/minecraft/recipes/chair_dark_oak_from_dark_oak_slab.json
+aa68970a684ea492c116a815ed2ffa90a9339924 data/minecraft/recipes/chair_jungle_from_jungle_slab.json
+47d858716e8151a5e98b23649cd83a9a90e60302 data/minecraft/recipes/chair_mushroom_fir_from_mushroom_fir_slab.json
+38a263b4292d271e0f5041b1a4d8c1514ceaaf3d data/minecraft/recipes/chair_mushroom_from_mushroom_slab.json
+00ef9a6ea5b13e325226efd16780da69f7a3c0fe data/minecraft/recipes/chair_nether_sakura_from_nether_sakura_slab.json
+ec18d9870efd57bd6c3945eb21e196c613856bb4 data/minecraft/recipes/chair_oak_from_oak_slab.json
+b587f2d51d426b375d1f6f235f10beb9169aa833 data/minecraft/recipes/chair_reeds_from_reeds_slab.json
+d031b966d66ce850d9b4cee6c2eb65ec859bb30d data/minecraft/recipes/chair_rubeus_from_rubeus_slab.json
+c24ffca3949db1993da2ea8f73c517c6009376c5 data/minecraft/recipes/chair_spruce_from_spruce_slab.json
+52556d187f24e51c53e79f5ffc6ba42807e922a3 data/minecraft/recipes/chair_stalagnate_from_stalagnate_planks_slab.json
+ccf21a10310ed1ef68dd20ea6f88c358fbaafabc data/minecraft/recipes/chair_warped_from_warped_slab.json
+292d97eeb2864005dec2ff0dbbccb79360f1942c data/minecraft/recipes/chair_wart_from_wart_slab.json
+924ea406c07a3c45bc1e7b98f19cb7b4a8163711 data/minecraft/recipes/chair_willow_from_willow_slab.json
+07bb47c7b37b7d4d07ac4b832c98183605733a36 data/minecraft/recipes/chest_anchor_tree_from_anchor_tree_planks.json
+76af413f5788fc2e863848731ca8c8e86086f4a9 data/minecraft/recipes/chest_crimson_from_crimson_planks.json
+82cd59c597bd3410163b6c15292334cb06a4399e data/minecraft/recipes/chest_mushroom_fir_from_mushroom_fir_planks.json
+4a6b851c5997deff0ce570c8c827a0ed446e0394 data/minecraft/recipes/chest_mushroom_from_mushroom_planks.json
+b23016ce744114ba00d950474207e8db72ffb529 data/minecraft/recipes/chest_nether_sakura_from_nether_sakura_planks.json
+bd7f0ac47e86ddaef258746e67000ba4725624bc data/minecraft/recipes/chest_reed_from_reeds_block.json
+f417fb3f51752f6de2cfe75a5896fd7e6c47dd2d data/minecraft/recipes/chest_rubeus_from_rubeus_planks.json
+03e71a58914d672b3b0ac6fb5377aa5260b69ea5 data/minecraft/recipes/chest_stalagnate_from_stalagnate_planks.json
+96ec1a99c19da511f84b7e3f0982429daedaa8f2 data/minecraft/recipes/chest_warped_from_warped_planks.json
+82b335075bfff40364aea47199f7166127aa8753 data/minecraft/recipes/chest_wart_from_wart_planks.json
+a6721124a4d143ae7f6e56cf645a1734d0ecb3c8 data/minecraft/recipes/chest_willow_from_willow_planks.json
+097af43b6845f92ddcd354c616e37dde969a4b77 data/minecraft/recipes/cincinnasite_fire_bowl_from_cincinnasite_forged.json
+35331689d8519aaa7a521057b0eecd08f26c9dac data/minecraft/recipes/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json
+08452a13ff9a692e06cbf508abcae94c0d57dd28 data/minecraft/recipes/cincinnasite_plate_from_cincinnasite_forged.json
+1a27a456177beab9d6e98af21dd33cba36e90a91 data/minecraft/recipes/cincinnasite_slab_from_cincinnasite_forged.json
+fb53de5cc1da4504632ccd671f7c77052f0d6e0b data/minecraft/recipes/cincinnasite_stairs_from_cincinnasite_forged.json
+b24308e4e2845bbdd58b81d99271561ad8245519 data/minecraft/recipes/cincinnasite_wall_from_cincinnasite_forged.json
+85a52289e653e46715774cd169f34221ffe0fca0 data/minecraft/recipes/crafting_table_anchor_tree_from_anchor_tree_planks.json
+110e12012d83ea556f6906a8ba5db0a31956e7a7 data/minecraft/recipes/crafting_table_crimson_from_crimson_planks.json
+2c2c798ad3bca983aa338b53bdd82fc601f21a2f data/minecraft/recipes/crafting_table_mushroom_fir_from_mushroom_fir_planks.json
+0ce14322acb1a109ff77047c99c996b4d58ede23 data/minecraft/recipes/crafting_table_mushroom_from_mushroom_planks.json
+33d7a323d4681fef8a503c985bc7f1daeafc12ce data/minecraft/recipes/crafting_table_nether_sakura_from_nether_sakura_planks.json
+06667185c51f52868bd8834a30283e2dfb697e52 data/minecraft/recipes/crafting_table_reed_from_reeds_block.json
+bcaedbb1599eeb0af381d6c5c40294e5109dd870 data/minecraft/recipes/crafting_table_rubeus_from_rubeus_planks.json
+15283206be98addf25de69da6aee8c70b0ae96a3 data/minecraft/recipes/crafting_table_stalagnate_from_stalagnate_planks.json
+4b79e0887450b1efe941f9e54650c1331345ee7b data/minecraft/recipes/crafting_table_warped_from_warped_planks.json
+bfd4e2306c1fbce3782a4d540381331ae24f256c data/minecraft/recipes/crafting_table_wart_from_wart_planks.json
+16a6b212a1e809f36817f8ce0dd2d067690fc540 data/minecraft/recipes/crafting_table_willow_from_willow_planks.json
+2a8fd6589e4b435dc5a2cbcd6cf20b60768d4dfa data/minecraft/recipes/crimson_ladder_from_crimson_planks.json
+f9e4c03f2a5eb18d7c642208b25a317ea843ffac data/minecraft/recipes/glowstone_stalactite_from_glowstone.json
+f6ce39b73435285015002514a135e8e188254d68 data/minecraft/recipes/mushroom_button_from_mushroom_planks.json
+7e065475d24e85c7bbcff1bec5b9a70f9c6d0be6 data/minecraft/recipes/mushroom_door_from_mushroom_planks.json
+75b394e77fda763818aa5f14721a0f85f743ac15 data/minecraft/recipes/mushroom_fence_from_mushroom_planks.json
+08d101ec12a22bca08134212f99ab45870a9572e data/minecraft/recipes/mushroom_fir_button_from_mushroom_fir_planks.json
+217c605283ea5f34581cd7862634c4e26bab8a85 data/minecraft/recipes/mushroom_fir_door_from_mushroom_fir_planks.json
+80f10d2a3a3b94e6ca858c6a56afb4d1cf795231 data/minecraft/recipes/mushroom_fir_fence_from_mushroom_fir_planks.json
+c95b9853287ffa6d44e44d2ded3635314097b165 data/minecraft/recipes/mushroom_fir_gate_from_mushroom_fir_planks.json
+a4fa1e049e698c6a99ec8e26b8b05b400feb8a1b data/minecraft/recipes/mushroom_fir_ladder_from_mushroom_fir_planks.json
+85a7c44da2fe297a0b504bd6638d161410b095cc data/minecraft/recipes/mushroom_fir_log_from_mushroom_fir_stem.json
+b278b2b83bbbf4659b59894e2aebffd0c4a9631b data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_log.json
+fd321bf84678ddcb26f4a6c1b9c3a857e27675c9 data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_stem.json
+4a6d826c2cb29285ffdc9654780aeb3456db855d data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_wood.json
+09d797e24e970b9444baf76afb4afa539e2b8d15 data/minecraft/recipes/mushroom_fir_planks_from_striped_log_mushroom_fir.json
+0d8b4efd476d794473df94b17a480bbacea256ff data/minecraft/recipes/mushroom_fir_planks_from_striped_wood_mushroom_fir.json
+74c372cae4c0ce11cd6190526a6879460da59509 data/minecraft/recipes/mushroom_fir_plate_from_mushroom_fir_planks.json
+d95f799e490dcee8f18a6ea212874475570ab078 data/minecraft/recipes/mushroom_fir_slab_from_mushroom_fir_planks.json
+834d1352375c9fae8645819fe916e5ee4b88df9f data/minecraft/recipes/mushroom_fir_stairs_from_mushroom_fir_planks.json
+d9681ab15cbaaccb1197101a2a9080f46ddcc96a data/minecraft/recipes/mushroom_fir_trapdoor_from_mushroom_fir_planks.json
+084708d22b3f2768fc09530062d9dd655f030320 data/minecraft/recipes/mushroom_fir_wood_from_mushroom_fir_log.json
+b2e2c38400006973077b076cf199c83ef93df42b data/minecraft/recipes/mushroom_gate_from_mushroom_planks.json
+868703469cdb0f8b29845fd7503300f33b91268a data/minecraft/recipes/mushroom_ladder_from_mushroom_planks.json
+f005d4d91eb94f843a3966a6f902d722a11d481a data/minecraft/recipes/mushroom_planks_from_mushroom_stem.json
+1f0bf0d2a2dcd9c445e647a25e53da9586104d20 data/minecraft/recipes/mushroom_plate_from_mushroom_planks.json
+e0e1fbe3a17ba63be4cfca9aaf053cec18fbb3cd data/minecraft/recipes/mushroom_slab_from_mushroom_planks.json
+cdff007e27b49182e7bf8ece12d1d66240debe6a data/minecraft/recipes/mushroom_stairs_from_mushroom_planks.json
+2c04174e7e0cc4b3650bbefd10cbf0ffcbf3d8d2 data/minecraft/recipes/mushroom_trapdoor_from_mushroom_planks.json
+95b90fbed9e8229257e0cb0dc875a1229e632d72 data/minecraft/recipes/nether_brick_tile_slab_from_nether_brick_tile_small.json
+773e4c7a26d1117ae618ace62f21a365bc2baf6e data/minecraft/recipes/nether_brick_tile_stairs_from_nether_brick_tile_small.json
+8876461d85e0e6cfc09291fb5724337fc5452237 data/minecraft/recipes/nether_brick_wall_from_nether_brick_tile_large.json
+27a251320d9798d251dae2c48490458f054abf6e data/minecraft/recipes/nether_ruby_slab_from_nether_ruby_block.json
+f4ec59b59fc42d9714b0f569d5eff5ed3cc822ef data/minecraft/recipes/nether_ruby_stairs_from_nether_ruby_block.json
+1a8d3f378097ae2a856b273900c2979a8cd897c9 data/minecraft/recipes/nether_sakura_bark_from_nether_sakura_log.json
+0fea362146bc56f456769c4b71f2e9401c4acef9 data/minecraft/recipes/nether_sakura_button_from_nether_sakura_planks.json
+e891fa13c0feab9955bdf1cc182833a62aacf545 data/minecraft/recipes/nether_sakura_door_from_nether_sakura_planks.json
+1b7650a1c9f37134279beec9899ba2f282209433 data/minecraft/recipes/nether_sakura_fence_from_nether_sakura_planks.json
+6b906da2c79a327ea508c06f21afdd729bf76af7 data/minecraft/recipes/nether_sakura_gate_from_nether_sakura_planks.json
+7de53ca4b271fc64343393c4b1107a73af7fd39e data/minecraft/recipes/nether_sakura_ladder_from_nether_sakura_planks.json
+5379a65234de529939ffe278928f3d28604dc240 data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_bark.json
+7ed15d2f68b31f85a81d7027a02aa5bd9c14e58c data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_log.json
+1308dbe3ff971a55b6040e4cff9326a41a2bedec data/minecraft/recipes/nether_sakura_planks_from_striped_bark_nether_sakura.json
+566d1aed9235da6d1954384e729b3496051e232f data/minecraft/recipes/nether_sakura_planks_from_striped_log_nether_sakura.json
+38cd3076ef25602466d85d514b39876483f7ba2e data/minecraft/recipes/nether_sakura_plate_from_nether_sakura_planks.json
+3546f0f8f14483312faa8d9a1062b53879eea8be data/minecraft/recipes/nether_sakura_slab_from_nether_sakura_planks.json
+63c33677c1d28afc736ada5b79cd656cc4f4d2dc data/minecraft/recipes/nether_sakura_stairs_from_nether_sakura_planks.json
+462e10725be0a74c269dc7f9af0b1c29e2f70203 data/minecraft/recipes/nether_sakura_trapdoor_from_nether_sakura_planks.json
+0b54df5e8a3f23ef51ca73821cc19643cf159a17 data/minecraft/recipes/netherite_fire_bowl_from_netherite_block.json
+59ad8870dcd371c54e5256b1021fa4b88a58f637 data/minecraft/recipes/netherite_fire_bowl_soul_from_netherite_block.json
+11f3ade63a2ebc34ff96b4c5b2cf12a24d20fbce data/minecraft/recipes/netherrack_furnace_from_netherrack.json
+8cb4c6a9a017a676b1a10e2fe590d9deb246eb3c data/minecraft/recipes/netherrack_stalactite_from_netherrack.json
+0fd8e9cce0e65a46ebde85aeee038f8bf227a387 data/minecraft/recipes/obsidian_bricks_slab_from_obsidian_bricks.json
+8474d46f8da141725a838bf3c4cf4e39f3dc4f85 data/minecraft/recipes/obsidian_bricks_stairs_from_obsidian_bricks.json
+8a9c8d2f5f74e79620203cd38af20737bda0a52b data/minecraft/recipes/obsidian_tile_slab_from_obsidian_tile_small.json
+1a1bab7102781639a7c94efa39825d658fcb76d3 data/minecraft/recipes/obsidian_tile_stairs_from_obsidian_tile_small.json
+ffe0e1f899e4a527e17b8f30c1c874ddd46fa979 data/minecraft/recipes/reeds_button_from_reeds_block.json
+4e7ca60f7a0990fdd2a337afef2e5b32ef5dda0e data/minecraft/recipes/reeds_door_from_reeds_block.json
+1fe9ccfbde633a4541670c609acf632ce136aa97 data/minecraft/recipes/reeds_fence_from_reeds_block.json
+9ac23e023581f6561a48740c7ae19211812bf5f3 data/minecraft/recipes/reeds_gate_from_reeds_block.json
+e7d66166d80cd37b7e0557662efcda57cb36a466 data/minecraft/recipes/reeds_ladder_from_reeds_block.json
+a82afde6bca3a7d3acbcf9ed8dd0e65b141553bb data/minecraft/recipes/reeds_plate_from_reeds_block.json
+a7c43e8e3b396e41d5a483a329f147e752a32bea data/minecraft/recipes/reeds_slab_from_reeds_block.json
+3a8c515861a738298957ac3357c71f0820710356 data/minecraft/recipes/reeds_stairs_from_reeds_block.json
+00bc0a9aa3b30f847a4b697eb247a21c2848670b data/minecraft/recipes/reeds_trapdoor_from_reeds_block.json
+8c93c97fb3426a6e6fc06eef38b0a87840e40172 data/minecraft/recipes/roof_tile_cincinnasite_from_cincinnasite_forged.json
+b4b13b6198f12d59ecafdb8fe747817e48ab830e data/minecraft/recipes/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json
+160fa0bee112fcf434e91c49fb746f4354cbc2f7 data/minecraft/recipes/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json
+5cc0d3bfe98b6de9dc37622b561a1d3bdc0506aa data/minecraft/recipes/roof_tile_nether_bricks_from_nether_bricks.json
+9c7901e84827c1b6d3121c39b2403d46179f1b99 data/minecraft/recipes/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json
+d68ac0bd2f0464dd8f5d52f44f59b81cdb68d216 data/minecraft/recipes/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json
+b4afede2debef147b344bbf3a65fe6b232fffde0 data/minecraft/recipes/roof_tile_reeds_from_reeds_block.json
+a9acfbe05c700ed7399d021660d4c10938b87926 data/minecraft/recipes/roof_tile_reeds_slab_from_roof_tile_reeds.json
+db1aabbeb5cb8e08e663ca43eb3d31b651682ed7 data/minecraft/recipes/roof_tile_reeds_stairs_from_roof_tile_reeds.json
+997d31a723db5e824560ec03485083bcf0c9eb6c data/minecraft/recipes/roof_tile_stalagnate_from_stalagnate_planks.json
+7875c6dfb31cdbefd13a53f3e0fbadf74ae8ac2b data/minecraft/recipes/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json
+0fcf8b4d4e8a26ddc6f810d0cfe33af21496049c data/minecraft/recipes/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json
+8df01322b79d51a472d9994fe2f85a35c9825b43 data/minecraft/recipes/roof_tile_wart_from_wart_planks.json
+da0ae6b52447fd8c6b620d9091e3d043e1b38a23 data/minecraft/recipes/roof_tile_wart_slab_from_roof_tile_wart.json
+2cf8b22ff5273423e81f60e63dc427af5f245084 data/minecraft/recipes/roof_tile_wart_stairs_from_roof_tile_wart.json
+8b7a2b1f58af4f8e075cbb1de3e02643ba2ddfbb data/minecraft/recipes/roof_tile_willow_from_willow_planks.json
+01a50d9c55837483dfad2953103380f0ad738250 data/minecraft/recipes/roof_tile_willow_slab_from_roof_tile_willow.json
+9d8cd5e45b40ec612f8342a737eba5853edadae5 data/minecraft/recipes/roof_tile_willow_stairs_from_roof_tile_willow.json
+9962cf3ea69a6ae8ed341e7cb9fc73cbabfec607 data/minecraft/recipes/rubeus_bark_from_rubeus_log.json
+4a7a0f0a1e7faf3d854b86c4d1c881ee3da5550a data/minecraft/recipes/rubeus_button_from_rubeus_planks.json
+4231b3f9ac49ab41eb4097b6e75e7315bf46988c data/minecraft/recipes/rubeus_door_from_rubeus_planks.json
+f56395ec84c4552d1f1c884a85f5b850f2827040 data/minecraft/recipes/rubeus_fence_from_rubeus_planks.json
+9cbb4a5e593e4cb76a1c538e8a4027d446fcbd1d data/minecraft/recipes/rubeus_gate_from_rubeus_planks.json
+ca1fa12696cf3bc894a5ff8a9bc3af4caa3659c2 data/minecraft/recipes/rubeus_ladder_from_rubeus_planks.json
+c51bf407100f0393bfdb7a50b4ce3d92d223deeb data/minecraft/recipes/rubeus_planks_from_rubeus_bark.json
+2cb6c93987c6d23b3f6fb0da7e416937f1e6d98e data/minecraft/recipes/rubeus_planks_from_rubeus_log.json
+1ddaa727fb43701365ad534b6c6a9bb448fbc0ec data/minecraft/recipes/rubeus_planks_from_striped_bark_rubeus.json
+ced67a1a90d0ea7fbe06fa24d09e73b4d1bede9b data/minecraft/recipes/rubeus_planks_from_striped_log_rubeus.json
+5e680f1d089b6afe3ee8cedbeb4a8ff3c0185e09 data/minecraft/recipes/rubeus_plate_from_rubeus_planks.json
+41ce8e0e0ac50058e0c33e229ef4b8822c0ad161 data/minecraft/recipes/rubeus_slab_from_rubeus_planks.json
+62283c055daec4b7d539a6245997346a3c1e8aea data/minecraft/recipes/rubeus_stairs_from_rubeus_planks.json
+91c2e9fe63f5b76905d5d790226593f92ea7143b data/minecraft/recipes/rubeus_trapdoor_from_rubeus_planks.json
+a5ba63732e73ccbe7bf0027be8f993905f3a1218 data/minecraft/recipes/sign_anchor_tree_from_anchor_tree_planks.json
+17418d3a890721bafabaad7835e56153c7b143f2 data/minecraft/recipes/sign_mushroom_fir_from_mushroom_fir_planks.json
+b6a183155dfb31a1afcfe45abd165b0aa812b1c1 data/minecraft/recipes/sign_mushroom_from_mushroom_planks.json
+0bbe5d72a00f3f7c7b3fc0b9bce1abe4a21b52ab data/minecraft/recipes/sign_nether_sakura_from_nether_sakura_planks.json
+a3a3ec7770cd85ffda336091423c488e50d87f08 data/minecraft/recipes/sign_reed_from_reeds_block.json
+6eb85f8165e2bb578e905cceef62fab02b16457d data/minecraft/recipes/sign_rubeus_from_rubeus_planks.json
+e82cdf1cf627f6d6a65871de12a4c83b4aed53e4 data/minecraft/recipes/sign_stalagnate_from_stalagnate_planks.json
+26bfe69ebbb0b9abbd0f88dfb287514c2ab88afd data/minecraft/recipes/sign_wart_from_wart_planks.json
+10122522ce4ed7fcb744e0fa071266ff6409dd12 data/minecraft/recipes/sign_willow_from_willow_planks.json
+fe676b4130ecf7efbdd8b5898ec62c90dc952b6f data/minecraft/recipes/soul_sandstone_chiseled_from_soul_sandstone_smooth.json
+4d8d9feee3fe433edeee4a253c7872afb11467eb data/minecraft/recipes/soul_sandstone_cut_from_soul_sandstone.json
+76b4195181a9ef512b04d37843089b54acc62be8 data/minecraft/recipes/soul_sandstone_cut_slab_from_soul_sandstone_cut.json
+86c6809d117da26da0bbea8598e12dc1a806458b data/minecraft/recipes/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json
+9a8d9820d4c70767e812b21099d8a510112f8ca6 data/minecraft/recipes/soul_sandstone_slab_from_soul_sandstone.json
+692e994f512fcc8ad29344d99501bcc0772a4263 data/minecraft/recipes/soul_sandstone_smooth_from_soul_sandstone_cut.json
+5ecb02361340b373a4efd21f9c8b7c2a0195b6df data/minecraft/recipes/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json
+23d71439da40c850143846353b7065b2bf6c3a87 data/minecraft/recipes/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json
+c20fcd1edfe7207dd48f1f61b8ae55b01c2b3d99 data/minecraft/recipes/soul_sandstone_stairs_from_soul_sandstone.json
+fa44f0bc5ed6854d72b6e07016c28fb665aee0a8 data/minecraft/recipes/soul_sandstone_wall_from_soul_sandstone_cut.json
+0fbce8e04f1676a57ff5e17382d113adb70833d6 data/minecraft/recipes/stalagnate_bark_from_stalagnate_log.json
+7eb67e3f14598d56721c40ed886405f8a0ecfed6 data/minecraft/recipes/stalagnate_ladder_from_stalagnate_planks.json
+aea13cde8f52ac5e24b6b393eb19188a1f21f674 data/minecraft/recipes/stalagnate_log_from_stalagnate_stem.json
+49ad029c244ced78b1e3ee55ac79b93dc17f4339 data/minecraft/recipes/stalagnate_planks_button_from_stalagnate_planks.json
+3a7f1e20dce8e98604b60ffe2ad2086eee649274 data/minecraft/recipes/stalagnate_planks_door_from_stalagnate_planks.json
+c160463cc6ce88bbefe4b7138a68afe3cc536104 data/minecraft/recipes/stalagnate_planks_fence_from_stalagnate_planks.json
+d2bf551d8963b9a35a50e209db09fedf18f57756 data/minecraft/recipes/stalagnate_planks_from_stalagnate_bark.json
+52c2e2043e15d87f03d95d16e24dd6eedf1dee37 data/minecraft/recipes/stalagnate_planks_from_stalagnate_log.json
+b650b64fd83d048210ce4df73cb2edaee4bb7ccc data/minecraft/recipes/stalagnate_planks_from_stalagnate_stem.json
+968abc9fea36823aa636f77ca5f3b411833c5a4d data/minecraft/recipes/stalagnate_planks_from_striped_bark_stalagnate.json
+0e184b4fad8c4744417f02e882ce860d9effa22d data/minecraft/recipes/stalagnate_planks_from_striped_log_stalagnate.json
+765b2995377bffa0169b06aedf5d7b7129b178e6 data/minecraft/recipes/stalagnate_planks_gate_from_stalagnate_planks.json
+47df5af52e6e8d338db9c4542d49c44c95efa12c data/minecraft/recipes/stalagnate_planks_plate_from_stalagnate_planks.json
+ff4fe2685b828872284da28b8f85389c68d15938 data/minecraft/recipes/stalagnate_planks_slab_from_stalagnate_planks.json
+dd6ef2d098c52ea8fed556eea026b459ba00e751 data/minecraft/recipes/stalagnate_planks_stairs_from_stalagnate_planks.json
+a9f3e2f7b841b52f27c4022bd2d2b8d61f645257 data/minecraft/recipes/stalagnate_planks_trapdoor_from_stalagnate_planks.json
+8bd9a4a34a37da3b73fdb1bae22a0c2d767cbe4d data/minecraft/recipes/taburet_acacia_from_acacia_slab.json
+b95e37896414ae5e47b843ef694f249730f03f5b data/minecraft/recipes/taburet_anchor_tree_from_anchor_tree_slab.json
+41edd21a590e9a1e81e623be979ae3d1848b4119 data/minecraft/recipes/taburet_birch_from_birch_slab.json
+5367ff99b75138f040d548a559ab74b06b2e92f3 data/minecraft/recipes/taburet_cincinnasite_from_cincinnasite_slab.json
+699216ee290cee408ea191a4d8168d8f2007cbbf data/minecraft/recipes/taburet_crimson_from_crimson_slab.json
+a1a035a725f6b6e2b0dcbce323a7c15a11d9d4cb data/minecraft/recipes/taburet_dark_oak_from_dark_oak_slab.json
+e5fcebf16e8fd99a14d745d4173e0edb43d20f40 data/minecraft/recipes/taburet_jungle_from_jungle_slab.json
+6d1ca394c06fe5a5d700803fa08cd2f18aeb059f data/minecraft/recipes/taburet_mushroom_fir_from_mushroom_fir_slab.json
+0b59892d43841c91e3ded6ad981b54efe0427859 data/minecraft/recipes/taburet_mushroom_from_mushroom_slab.json
+cc9d176d3b7644527b11a2835c1276b0f90db53e data/minecraft/recipes/taburet_nether_sakura_from_nether_sakura_slab.json
+b2dc6c62eb36a72ac16453e353a7de4d97de5dfa data/minecraft/recipes/taburet_oak_from_oak_slab.json
+af01193ee15f7922c38b2822ba4c9830708fcdb9 data/minecraft/recipes/taburet_reeds_from_reeds_slab.json
+b3436fb3041ffe86c2fd1e41561e2d644258369a data/minecraft/recipes/taburet_rubeus_from_rubeus_slab.json
+89d28655a7cf2d5c5f1345643d7ec94c5189bc94 data/minecraft/recipes/taburet_spruce_from_spruce_slab.json
+d63bfe96a5cb3c159b9276c980066cce065199ea data/minecraft/recipes/taburet_stalagnate_from_stalagnate_planks_slab.json
+dadc0a22228b174d7646a23a6f330cef26095ec6 data/minecraft/recipes/taburet_warped_from_warped_slab.json
+2f4227cc52ef83b56b1218773e1f2dd28ae73a69 data/minecraft/recipes/taburet_wart_from_wart_slab.json
+b63d9fdae1aa4c9ccff2d92b9674c3171ea004e8 data/minecraft/recipes/taburet_willow_from_willow_slab.json
+05d4296766605ca26b779f1a6021d6cd7c998c3d data/minecraft/recipes/warped_ladder_from_warped_planks.json
+a669c90b56afc3b681075d37fd4f668a7141abe0 data/minecraft/recipes/wart_bark_from_wart_log.json
+5727c50a4ca7ab9741f9fec11a3d74cb9b01b4a0 data/minecraft/recipes/wart_button_from_wart_planks.json
+1ca5838f54ee170308b0061ea7fc88396d94224d data/minecraft/recipes/wart_door_from_wart_planks.json
+997e2aaeba6e3b1455c3e7c3805fb809bcbae381 data/minecraft/recipes/wart_fence_from_wart_planks.json
+91053b238c6bb12221ea0dbff18787d79fb79da6 data/minecraft/recipes/wart_gate_from_wart_planks.json
+c4a49ee016d87d5f7961652509ad22b072c19abd data/minecraft/recipes/wart_ladder_from_wart_planks.json
+e448316e6a9119a346e38806d7838c76a3192192 data/minecraft/recipes/wart_planks_from_striped_bark_wart.json
+9969cb8e925a9376ef7eafe759fa38b66b808d77 data/minecraft/recipes/wart_planks_from_striped_log_wart.json
+21c6d9e3d8ea97d2db7287ad07646ad7485d8fcf data/minecraft/recipes/wart_planks_from_wart_bark.json
+5a0b3bb79d7c445507ef143848c9272bb6069317 data/minecraft/recipes/wart_planks_from_wart_log.json
+73586c66484eecc5a661575db837050dc733fad5 data/minecraft/recipes/wart_plate_from_wart_planks.json
+378a3c8849eaf963c962a788dda684242ba0957a data/minecraft/recipes/wart_slab_from_wart_planks.json
+15973153a665166ce9746178e0e43aec5e0e4f89 data/minecraft/recipes/wart_stairs_from_wart_planks.json
+7fbe3d0f8a4c1d62c1919e9b69757e001cf42658 data/minecraft/recipes/wart_trapdoor_from_wart_planks.json
+5a67c27290e77579ee94a93ed88ff9de06a5e181 data/minecraft/recipes/willow_bark_from_willow_log.json
+7c45b5aca084aa8805a25353034f00bb64a71631 data/minecraft/recipes/willow_button_from_willow_planks.json
+889aa959747ac71c22c36f726f3eac812336b66e data/minecraft/recipes/willow_door_from_willow_planks.json
+b0ea2048d701d6f9c333d9e7d112b6efee7cd9d9 data/minecraft/recipes/willow_fence_from_willow_planks.json
+ebefb265022466f9bc424f8c8c50b6715af722c3 data/minecraft/recipes/willow_gate_from_willow_planks.json
+ec488a22435be32319ac13cf706ee0f68c6a1671 data/minecraft/recipes/willow_ladder_from_willow_planks.json
+310fe711f83118d43f41f7fde7311ee4c848d901 data/minecraft/recipes/willow_planks_from_striped_bark_willow.json
+e9471e7f0a65083a88cec37b4b65573be1bec659 data/minecraft/recipes/willow_planks_from_striped_log_willow.json
+68fcff91b35b692889d3ed35d530220e2da22418 data/minecraft/recipes/willow_planks_from_willow_bark.json
+bb76eff3679d1baf36e7758d39b01f328da8c69c data/minecraft/recipes/willow_planks_from_willow_log.json
+11016dec857f41eaae6c730fe0f636bfdaac081a data/minecraft/recipes/willow_plate_from_willow_planks.json
+b6f361bf481e0bf670a07670a6ebf98500b0e310 data/minecraft/recipes/willow_slab_from_willow_planks.json
+2c57e3fef1d492f8937728e0dbc8224e620452a5 data/minecraft/recipes/willow_stairs_from_willow_planks.json
+f968a4d5061d958dd6eb707bc7815b6d67a8310a data/minecraft/recipes/willow_trapdoor_from_willow_planks.json
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_bark_from_anchor_tree_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_bark_from_anchor_tree_log.json
new file mode 100644
index 0000000..046e90e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_bark_from_anchor_tree_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_bark_from_anchor_tree_log"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_bark_from_anchor_tree_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_button_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_button_from_anchor_tree_planks.json
new file mode 100644
index 0000000..8a38cd6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_button_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_button_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_button_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_door_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_door_from_anchor_tree_planks.json
new file mode 100644
index 0000000..363030c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_door_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_door_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_door_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_fence_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_fence_from_anchor_tree_planks.json
new file mode 100644
index 0000000..b607bdd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_fence_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_fence_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_fence_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_gate_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_gate_from_anchor_tree_planks.json
new file mode 100644
index 0000000..c95aa6d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_gate_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_gate_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_gate_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_ladder_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_ladder_from_anchor_tree_planks.json
new file mode 100644
index 0000000..cbf548d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_ladder_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_ladder_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_ladder_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_bark.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_bark.json
new file mode 100644
index 0000000..45623e3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_bark.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_planks_from_anchor_tree_bark"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_bark": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_bark"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_planks_from_anchor_tree_bark"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_bark",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_log.json
new file mode 100644
index 0000000..8fd3ccf
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_anchor_tree_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_planks_from_anchor_tree_log"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_planks_from_anchor_tree_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_bark_anchor_tree.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_bark_anchor_tree.json
new file mode 100644
index 0000000..0b76d87
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_bark_anchor_tree.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_planks_from_striped_bark_anchor_tree"
+ ]
+ },
+ "criteria": {
+ "striped_bark_anchor_tree": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_bark_anchor_tree"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_planks_from_striped_bark_anchor_tree"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_bark_anchor_tree",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_log_anchor_tree.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_log_anchor_tree.json
new file mode 100644
index 0000000..395ad16
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_planks_from_striped_log_anchor_tree.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_planks_from_striped_log_anchor_tree"
+ ]
+ },
+ "criteria": {
+ "striped_log_anchor_tree": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_anchor_tree"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_planks_from_striped_log_anchor_tree"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_anchor_tree",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_plate_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_plate_from_anchor_tree_planks.json
new file mode 100644
index 0000000..9d87d0b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_plate_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_plate_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_plate_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_slab_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_slab_from_anchor_tree_planks.json
new file mode 100644
index 0000000..e0ecf01
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_slab_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_slab_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_slab_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_stairs_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_stairs_from_anchor_tree_planks.json
new file mode 100644
index 0000000..a4ff6ac
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_stairs_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_stairs_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_stairs_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_trapdoor_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_trapdoor_from_anchor_tree_planks.json
new file mode 100644
index 0000000..d8d0ccd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/anchor_tree_trapdoor_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:anchor_tree_trapdoor_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:anchor_tree_trapdoor_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_acacia_from_acacia_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_acacia_from_acacia_slab.json
new file mode 100644
index 0000000..5a652db
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_acacia_from_acacia_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_acacia_from_acacia_slab"
+ ]
+ },
+ "criteria": {
+ "acacia_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:acacia_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_acacia_from_acacia_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "acacia_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_anchor_tree_from_anchor_tree_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_anchor_tree_from_anchor_tree_slab.json
new file mode 100644
index 0000000..4cc2505
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_anchor_tree_from_anchor_tree_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_anchor_tree_from_anchor_tree_slab"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_anchor_tree_from_anchor_tree_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_birch_from_birch_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_birch_from_birch_slab.json
new file mode 100644
index 0000000..8d743b3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_birch_from_birch_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_birch_from_birch_slab"
+ ]
+ },
+ "criteria": {
+ "birch_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:birch_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_birch_from_birch_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "birch_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_cincinnasite_from_cincinnasite_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_cincinnasite_from_cincinnasite_slab.json
new file mode 100644
index 0000000..2cb7c78
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_cincinnasite_from_cincinnasite_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_cincinnasite_from_cincinnasite_slab"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_cincinnasite_from_cincinnasite_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_crimson_from_crimson_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_crimson_from_crimson_slab.json
new file mode 100644
index 0000000..a028508
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_crimson_from_crimson_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_crimson_from_crimson_slab"
+ ]
+ },
+ "criteria": {
+ "crimson_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_crimson_from_crimson_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_dark_oak_from_dark_oak_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_dark_oak_from_dark_oak_slab.json
new file mode 100644
index 0000000..3e46e01
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_dark_oak_from_dark_oak_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_dark_oak_from_dark_oak_slab"
+ ]
+ },
+ "criteria": {
+ "dark_oak_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:dark_oak_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_dark_oak_from_dark_oak_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "dark_oak_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_jungle_from_jungle_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_jungle_from_jungle_slab.json
new file mode 100644
index 0000000..d5c2169
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_jungle_from_jungle_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_jungle_from_jungle_slab"
+ ]
+ },
+ "criteria": {
+ "jungle_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:jungle_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_jungle_from_jungle_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "jungle_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_fir_from_mushroom_fir_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_fir_from_mushroom_fir_slab.json
new file mode 100644
index 0000000..7674b64
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_fir_from_mushroom_fir_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_mushroom_fir_from_mushroom_fir_slab"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_mushroom_fir_from_mushroom_fir_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_from_mushroom_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_from_mushroom_slab.json
new file mode 100644
index 0000000..752a960
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_mushroom_from_mushroom_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_mushroom_from_mushroom_slab"
+ ]
+ },
+ "criteria": {
+ "mushroom_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_mushroom_from_mushroom_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_nether_sakura_from_nether_sakura_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_nether_sakura_from_nether_sakura_slab.json
new file mode 100644
index 0000000..10e1e1b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_nether_sakura_from_nether_sakura_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_nether_sakura_from_nether_sakura_slab"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_nether_sakura_from_nether_sakura_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_oak_from_oak_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_oak_from_oak_slab.json
new file mode 100644
index 0000000..3639be0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_oak_from_oak_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_oak_from_oak_slab"
+ ]
+ },
+ "criteria": {
+ "oak_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:oak_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_oak_from_oak_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "oak_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_reeds_from_reeds_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_reeds_from_reeds_slab.json
new file mode 100644
index 0000000..43fe0a7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_reeds_from_reeds_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_reeds_from_reeds_slab"
+ ]
+ },
+ "criteria": {
+ "reeds_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_reeds_from_reeds_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_rubeus_from_rubeus_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_rubeus_from_rubeus_slab.json
new file mode 100644
index 0000000..acd37c2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_rubeus_from_rubeus_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_rubeus_from_rubeus_slab"
+ ]
+ },
+ "criteria": {
+ "rubeus_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_rubeus_from_rubeus_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_spruce_from_spruce_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_spruce_from_spruce_slab.json
new file mode 100644
index 0000000..59a8d92
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_spruce_from_spruce_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_spruce_from_spruce_slab"
+ ]
+ },
+ "criteria": {
+ "spruce_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:spruce_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_spruce_from_spruce_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "spruce_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_stalagnate_from_stalagnate_planks_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_stalagnate_from_stalagnate_planks_slab.json
new file mode 100644
index 0000000..a374d90
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_stalagnate_from_stalagnate_planks_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_stalagnate_from_stalagnate_planks_slab"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_stalagnate_from_stalagnate_planks_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_warped_from_warped_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_warped_from_warped_slab.json
new file mode 100644
index 0000000..c62733d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_warped_from_warped_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_warped_from_warped_slab"
+ ]
+ },
+ "criteria": {
+ "warped_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_warped_from_warped_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_wart_from_wart_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_wart_from_wart_slab.json
new file mode 100644
index 0000000..3e55e90
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_wart_from_wart_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_wart_from_wart_slab"
+ ]
+ },
+ "criteria": {
+ "wart_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_wart_from_wart_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_willow_from_willow_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_willow_from_willow_slab.json
new file mode 100644
index 0000000..f791bff
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bar_stool_willow_from_willow_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bar_stool_willow_from_willow_slab"
+ ]
+ },
+ "criteria": {
+ "willow_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bar_stool_willow_from_willow_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..abda78c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_anchor_tree_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_anchor_tree_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_crimson_from_crimson_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_crimson_from_crimson_planks.json
new file mode 100644
index 0000000..cafcfec
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_crimson_from_crimson_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_crimson_from_crimson_planks"
+ ]
+ },
+ "criteria": {
+ "crimson_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_crimson_from_crimson_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..6175641
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_mushroom_fir_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_mushroom_fir_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..8a6c687
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_mushroom_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_mushroom_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_mushroom_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..4412b9e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_nether_sakura_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_nether_sakura_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_reed_from_reeds_block.json
new file mode 100644
index 0000000..3fc2636
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_reed_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_reed_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_reed_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..b5f35c9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_rubeus_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_rubeus_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_rubeus_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..5da5ced
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_stalagnate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_stalagnate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_warped_from_warped_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_warped_from_warped_planks.json
new file mode 100644
index 0000000..7bf9f41
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_warped_from_warped_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_warped_from_warped_planks"
+ ]
+ },
+ "criteria": {
+ "warped_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_warped_from_warped_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_wart_from_wart_planks.json
new file mode 100644
index 0000000..0fd5707
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_wart_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_wart_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_wart_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_willow_from_willow_planks.json
new file mode 100644
index 0000000..2b772cd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/barrel_willow_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:barrel_willow_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:barrel_willow_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_from_polished_basalt.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_from_polished_basalt.json
new file mode 100644
index 0000000..cd31b9f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_from_polished_basalt.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_bricks_from_polished_basalt"
+ ]
+ },
+ "criteria": {
+ "polished_basalt": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:polished_basalt"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_bricks_from_polished_basalt"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "polished_basalt",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_slab_from_basalt_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_slab_from_basalt_bricks.json
new file mode 100644
index 0000000..b2af3ea
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_slab_from_basalt_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_bricks_slab_from_basalt_bricks"
+ ]
+ },
+ "criteria": {
+ "basalt_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:basalt_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_bricks_slab_from_basalt_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "basalt_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_stairs_from_basalt_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_stairs_from_basalt_bricks.json
new file mode 100644
index 0000000..586addd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_stairs_from_basalt_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_bricks_stairs_from_basalt_bricks"
+ ]
+ },
+ "criteria": {
+ "basalt_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:basalt_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_bricks_stairs_from_basalt_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "basalt_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_wall_from_basalt_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_wall_from_basalt_bricks.json
new file mode 100644
index 0000000..4272e9e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_bricks_wall_from_basalt_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_bricks_wall_from_basalt_bricks"
+ ]
+ },
+ "criteria": {
+ "basalt_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:basalt_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_bricks_wall_from_basalt_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "basalt_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_furnace_from_basalt.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_furnace_from_basalt.json
new file mode 100644
index 0000000..18366ba
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_furnace_from_basalt.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_furnace_from_basalt"
+ ]
+ },
+ "criteria": {
+ "basalt": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:basalt"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_furnace_from_basalt"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "basalt",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_slab_from_basalt.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_slab_from_basalt.json
new file mode 100644
index 0000000..c84999c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_slab_from_basalt.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_slab_from_basalt"
+ ]
+ },
+ "criteria": {
+ "basalt": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:basalt"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_slab_from_basalt"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "basalt",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_stalactite_from_basalt.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_stalactite_from_basalt.json
new file mode 100644
index 0000000..da18337
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/basalt_stalactite_from_basalt.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:basalt_stalactite_from_basalt"
+ ]
+ },
+ "criteria": {
+ "basalt": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:basalt"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:basalt_stalactite_from_basalt"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "basalt",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/blackstone_furnace_from_blackstone.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blackstone_furnace_from_blackstone.json
new file mode 100644
index 0000000..781c655
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blackstone_furnace_from_blackstone.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:blackstone_furnace_from_blackstone"
+ ]
+ },
+ "criteria": {
+ "blackstone": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:blackstone"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:blackstone_furnace_from_blackstone"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blackstone",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/blackstone_stalactite_from_blackstone.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blackstone_stalactite_from_blackstone.json
new file mode 100644
index 0000000..4bff546
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blackstone_stalactite_from_blackstone.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:blackstone_stalactite_from_blackstone"
+ ]
+ },
+ "criteria": {
+ "blackstone": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:blackstone"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:blackstone_stalactite_from_blackstone"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blackstone",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json
new file mode 100644
index 0000000..649f4c5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:blue_obsidian_bricks_slab_from_blue_obsidian_bricks"
+ ]
+ },
+ "criteria": {
+ "blue_obsidian_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:blue_obsidian_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:blue_obsidian_bricks_slab_from_blue_obsidian_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blue_obsidian_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json
new file mode 100644
index 0000000..228dfae
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:blue_obsidian_bricks_stairs_from_blue_obsidian_bricks"
+ ]
+ },
+ "criteria": {
+ "blue_obsidian_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:blue_obsidian_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:blue_obsidian_bricks_stairs_from_blue_obsidian_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blue_obsidian_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json
new file mode 100644
index 0000000..0fdb318
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:blue_obsidian_tile_slab_from_blue_obsidian_tile_small"
+ ]
+ },
+ "criteria": {
+ "blue_obsidian_tile_small": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:blue_obsidian_tile_small"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:blue_obsidian_tile_slab_from_blue_obsidian_tile_small"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blue_obsidian_tile_small",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json
new file mode 100644
index 0000000..91f6bcb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:blue_obsidian_tile_stairs_from_blue_obsidian_tile_small"
+ ]
+ },
+ "criteria": {
+ "blue_obsidian_tile_small": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:blue_obsidian_tile_small"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:blue_obsidian_tile_stairs_from_blue_obsidian_tile_small"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "blue_obsidian_tile_small",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_button_from_bone_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_button_from_bone_block.json
new file mode 100644
index 0000000..19cb002
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_button_from_bone_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bone_button_from_bone_block"
+ ]
+ },
+ "criteria": {
+ "bone_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bone_button_from_bone_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "bone_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_plate_from_bone_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_plate_from_bone_block.json
new file mode 100644
index 0000000..5548f48
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_plate_from_bone_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bone_plate_from_bone_block"
+ ]
+ },
+ "criteria": {
+ "bone_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bone_plate_from_bone_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "bone_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_slab_from_bone_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_slab_from_bone_block.json
new file mode 100644
index 0000000..c4d21df
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_slab_from_bone_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bone_slab_from_bone_block"
+ ]
+ },
+ "criteria": {
+ "bone_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bone_slab_from_bone_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "bone_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_stairs_from_bone_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_stairs_from_bone_block.json
new file mode 100644
index 0000000..abb3a34
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_stairs_from_bone_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bone_stairs_from_bone_block"
+ ]
+ },
+ "criteria": {
+ "bone_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bone_stairs_from_bone_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "bone_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_stalactite_from_bone_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_stalactite_from_bone_block.json
new file mode 100644
index 0000000..c43ea76
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_stalactite_from_bone_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bone_stalactite_from_bone_block"
+ ]
+ },
+ "criteria": {
+ "bone_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bone_stalactite_from_bone_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "bone_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_wall_from_bone_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_wall_from_bone_block.json
new file mode 100644
index 0000000..cb2ff57
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bone_wall_from_bone_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bone_wall_from_bone_block"
+ ]
+ },
+ "criteria": {
+ "bone_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bone_wall_from_bone_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "bone_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_from_nether_brick_tile_large.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_from_nether_brick_tile_large.json
new file mode 100644
index 0000000..161fac3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_from_nether_brick_tile_large.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bricks_fire_bowl_from_nether_brick_tile_large"
+ ]
+ },
+ "criteria": {
+ "nether_brick_tile_large": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_brick_tile_large"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bricks_fire_bowl_from_nether_brick_tile_large"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_brick_tile_large",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_soul_from_nether_brick_tile_large.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_soul_from_nether_brick_tile_large.json
new file mode 100644
index 0000000..ba08e75
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/bricks_fire_bowl_soul_from_nether_brick_tile_large.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:bricks_fire_bowl_soul_from_nether_brick_tile_large"
+ ]
+ },
+ "criteria": {
+ "nether_brick_tile_large": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_brick_tile_large"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:bricks_fire_bowl_soul_from_nether_brick_tile_large"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_brick_tile_large",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_acacia_from_acacia_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_acacia_from_acacia_slab.json
new file mode 100644
index 0000000..a3bd1a3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_acacia_from_acacia_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_acacia_from_acacia_slab"
+ ]
+ },
+ "criteria": {
+ "acacia_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:acacia_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_acacia_from_acacia_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "acacia_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_anchor_tree_from_anchor_tree_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_anchor_tree_from_anchor_tree_slab.json
new file mode 100644
index 0000000..e670974
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_anchor_tree_from_anchor_tree_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_anchor_tree_from_anchor_tree_slab"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_anchor_tree_from_anchor_tree_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_birch_from_birch_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_birch_from_birch_slab.json
new file mode 100644
index 0000000..cf974fd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_birch_from_birch_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_birch_from_birch_slab"
+ ]
+ },
+ "criteria": {
+ "birch_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:birch_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_birch_from_birch_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "birch_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_cincinnasite_from_cincinnasite_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_cincinnasite_from_cincinnasite_slab.json
new file mode 100644
index 0000000..6b43394
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_cincinnasite_from_cincinnasite_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_cincinnasite_from_cincinnasite_slab"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_cincinnasite_from_cincinnasite_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_crimson_from_crimson_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_crimson_from_crimson_slab.json
new file mode 100644
index 0000000..5790032
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_crimson_from_crimson_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_crimson_from_crimson_slab"
+ ]
+ },
+ "criteria": {
+ "crimson_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_crimson_from_crimson_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_dark_oak_from_dark_oak_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_dark_oak_from_dark_oak_slab.json
new file mode 100644
index 0000000..d8fa59c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_dark_oak_from_dark_oak_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_dark_oak_from_dark_oak_slab"
+ ]
+ },
+ "criteria": {
+ "dark_oak_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:dark_oak_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_dark_oak_from_dark_oak_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "dark_oak_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_jungle_from_jungle_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_jungle_from_jungle_slab.json
new file mode 100644
index 0000000..4326c5d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_jungle_from_jungle_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_jungle_from_jungle_slab"
+ ]
+ },
+ "criteria": {
+ "jungle_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:jungle_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_jungle_from_jungle_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "jungle_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_mushroom_fir_from_mushroom_fir_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_mushroom_fir_from_mushroom_fir_slab.json
new file mode 100644
index 0000000..ed0b635
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_mushroom_fir_from_mushroom_fir_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_mushroom_fir_from_mushroom_fir_slab"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_mushroom_fir_from_mushroom_fir_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_mushroom_from_mushroom_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_mushroom_from_mushroom_slab.json
new file mode 100644
index 0000000..6a0b25a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_mushroom_from_mushroom_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_mushroom_from_mushroom_slab"
+ ]
+ },
+ "criteria": {
+ "mushroom_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_mushroom_from_mushroom_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_nether_sakura_from_nether_sakura_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_nether_sakura_from_nether_sakura_slab.json
new file mode 100644
index 0000000..aa60f4c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_nether_sakura_from_nether_sakura_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_nether_sakura_from_nether_sakura_slab"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_nether_sakura_from_nether_sakura_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_oak_from_oak_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_oak_from_oak_slab.json
new file mode 100644
index 0000000..aa4fef0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_oak_from_oak_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_oak_from_oak_slab"
+ ]
+ },
+ "criteria": {
+ "oak_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:oak_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_oak_from_oak_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "oak_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_reeds_from_reeds_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_reeds_from_reeds_slab.json
new file mode 100644
index 0000000..0f0c662
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_reeds_from_reeds_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_reeds_from_reeds_slab"
+ ]
+ },
+ "criteria": {
+ "reeds_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_reeds_from_reeds_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_rubeus_from_rubeus_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_rubeus_from_rubeus_slab.json
new file mode 100644
index 0000000..aa4add7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_rubeus_from_rubeus_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_rubeus_from_rubeus_slab"
+ ]
+ },
+ "criteria": {
+ "rubeus_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_rubeus_from_rubeus_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_spruce_from_spruce_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_spruce_from_spruce_slab.json
new file mode 100644
index 0000000..05f9217
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_spruce_from_spruce_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_spruce_from_spruce_slab"
+ ]
+ },
+ "criteria": {
+ "spruce_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:spruce_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_spruce_from_spruce_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "spruce_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_stalagnate_from_stalagnate_planks_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_stalagnate_from_stalagnate_planks_slab.json
new file mode 100644
index 0000000..2acde93
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_stalagnate_from_stalagnate_planks_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_stalagnate_from_stalagnate_planks_slab"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_stalagnate_from_stalagnate_planks_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_warped_from_warped_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_warped_from_warped_slab.json
new file mode 100644
index 0000000..8587fe0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_warped_from_warped_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_warped_from_warped_slab"
+ ]
+ },
+ "criteria": {
+ "warped_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_warped_from_warped_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_wart_from_wart_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_wart_from_wart_slab.json
new file mode 100644
index 0000000..b652faf
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_wart_from_wart_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_wart_from_wart_slab"
+ ]
+ },
+ "criteria": {
+ "wart_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_wart_from_wart_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_willow_from_willow_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_willow_from_willow_slab.json
new file mode 100644
index 0000000..613ccb2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chair_willow_from_willow_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chair_willow_from_willow_slab"
+ ]
+ },
+ "criteria": {
+ "willow_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chair_willow_from_willow_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..58f875c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_anchor_tree_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_anchor_tree_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_crimson_from_crimson_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_crimson_from_crimson_planks.json
new file mode 100644
index 0000000..44f1108
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_crimson_from_crimson_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_crimson_from_crimson_planks"
+ ]
+ },
+ "criteria": {
+ "crimson_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_crimson_from_crimson_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..0813e25
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_mushroom_fir_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_mushroom_fir_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..88dd367
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_mushroom_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_mushroom_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_mushroom_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..b260820
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_nether_sakura_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_nether_sakura_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_reed_from_reeds_block.json
new file mode 100644
index 0000000..0063ca2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_reed_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_reed_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_reed_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..99c5ba8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_rubeus_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_rubeus_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_rubeus_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..337f7a7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_stalagnate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_stalagnate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_warped_from_warped_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_warped_from_warped_planks.json
new file mode 100644
index 0000000..14fc41b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_warped_from_warped_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_warped_from_warped_planks"
+ ]
+ },
+ "criteria": {
+ "warped_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_warped_from_warped_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_wart_from_wart_planks.json
new file mode 100644
index 0000000..eb370bb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_wart_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_wart_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_wart_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_willow_from_willow_planks.json
new file mode 100644
index 0000000..ae5e3ce
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/chest_willow_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:chest_willow_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:chest_willow_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_from_cincinnasite_forged.json
new file mode 100644
index 0000000..6d77da3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:cincinnasite_fire_bowl_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:cincinnasite_fire_bowl_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json
new file mode 100644
index 0000000..0efd0c4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:cincinnasite_fire_bowl_soul_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:cincinnasite_fire_bowl_soul_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_plate_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_plate_from_cincinnasite_forged.json
new file mode 100644
index 0000000..d03f138
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_plate_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:cincinnasite_plate_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:cincinnasite_plate_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_slab_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_slab_from_cincinnasite_forged.json
new file mode 100644
index 0000000..261a735
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_slab_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:cincinnasite_slab_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:cincinnasite_slab_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_stairs_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_stairs_from_cincinnasite_forged.json
new file mode 100644
index 0000000..46b156f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_stairs_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:cincinnasite_stairs_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:cincinnasite_stairs_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_wall_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_wall_from_cincinnasite_forged.json
new file mode 100644
index 0000000..d0a89d0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/cincinnasite_wall_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:cincinnasite_wall_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:cincinnasite_wall_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..6515888
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_anchor_tree_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_anchor_tree_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_crimson_from_crimson_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_crimson_from_crimson_planks.json
new file mode 100644
index 0000000..1f9a8fe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_crimson_from_crimson_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_crimson_from_crimson_planks"
+ ]
+ },
+ "criteria": {
+ "crimson_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_crimson_from_crimson_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..23ba714
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_mushroom_fir_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_mushroom_fir_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..b0ab33d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_mushroom_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_mushroom_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_mushroom_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..234cd6d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_nether_sakura_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_nether_sakura_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_reed_from_reeds_block.json
new file mode 100644
index 0000000..8545eeb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_reed_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_reed_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_reed_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..02b4e9b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_rubeus_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_rubeus_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_rubeus_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..2669bf4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_stalagnate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_stalagnate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_warped_from_warped_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_warped_from_warped_planks.json
new file mode 100644
index 0000000..bd20863
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_warped_from_warped_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_warped_from_warped_planks"
+ ]
+ },
+ "criteria": {
+ "warped_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_warped_from_warped_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_wart_from_wart_planks.json
new file mode 100644
index 0000000..00754e8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_wart_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_wart_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_wart_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_willow_from_willow_planks.json
new file mode 100644
index 0000000..3fbf3af
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crafting_table_willow_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crafting_table_willow_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crafting_table_willow_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/crimson_ladder_from_crimson_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crimson_ladder_from_crimson_planks.json
new file mode 100644
index 0000000..22f87eb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/crimson_ladder_from_crimson_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:crimson_ladder_from_crimson_planks"
+ ]
+ },
+ "criteria": {
+ "crimson_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:crimson_ladder_from_crimson_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/glowstone_stalactite_from_glowstone.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/glowstone_stalactite_from_glowstone.json
new file mode 100644
index 0000000..81d3dbb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/glowstone_stalactite_from_glowstone.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:glowstone_stalactite_from_glowstone"
+ ]
+ },
+ "criteria": {
+ "glowstone": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:glowstone"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:glowstone_stalactite_from_glowstone"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "glowstone",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_button_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_button_from_mushroom_planks.json
new file mode 100644
index 0000000..44bc339
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_button_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_button_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_button_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_door_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_door_from_mushroom_planks.json
new file mode 100644
index 0000000..2f203d8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_door_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_door_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_door_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fence_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fence_from_mushroom_planks.json
new file mode 100644
index 0000000..7c4a568
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fence_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fence_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fence_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_button_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_button_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..1f90883
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_button_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_button_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_button_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_door_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_door_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..a9a3af3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_door_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_door_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_door_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_fence_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_fence_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..979d5cb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_fence_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_fence_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_fence_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_gate_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_gate_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..dc860ec
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_gate_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_gate_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_gate_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_ladder_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_ladder_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..f29ae39
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_ladder_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_ladder_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_ladder_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_log_from_mushroom_fir_stem.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_log_from_mushroom_fir_stem.json
new file mode 100644
index 0000000..8002d29
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_log_from_mushroom_fir_stem.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_log_from_mushroom_fir_stem"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_stem": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_stem"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_log_from_mushroom_fir_stem"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_stem",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_log.json
new file mode 100644
index 0000000..866c4f9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_planks_from_mushroom_fir_log"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_planks_from_mushroom_fir_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_stem.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_stem.json
new file mode 100644
index 0000000..686ba3a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_stem.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_planks_from_mushroom_fir_stem"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_stem": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_stem"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_planks_from_mushroom_fir_stem"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_stem",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_wood.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_wood.json
new file mode 100644
index 0000000..7b32c79
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_mushroom_fir_wood.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_planks_from_mushroom_fir_wood"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_wood": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_wood"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_planks_from_mushroom_fir_wood"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_wood",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_log_mushroom_fir.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_log_mushroom_fir.json
new file mode 100644
index 0000000..df3ce16
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_log_mushroom_fir.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_planks_from_striped_log_mushroom_fir"
+ ]
+ },
+ "criteria": {
+ "striped_log_mushroom_fir": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_mushroom_fir"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_planks_from_striped_log_mushroom_fir"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_mushroom_fir",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_wood_mushroom_fir.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_wood_mushroom_fir.json
new file mode 100644
index 0000000..eccb440
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_planks_from_striped_wood_mushroom_fir.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_planks_from_striped_wood_mushroom_fir"
+ ]
+ },
+ "criteria": {
+ "striped_wood_mushroom_fir": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_wood_mushroom_fir"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_planks_from_striped_wood_mushroom_fir"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_wood_mushroom_fir",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_plate_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_plate_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..a0b39b0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_plate_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_plate_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_plate_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_slab_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_slab_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..413bca3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_slab_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_slab_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_slab_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_stairs_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_stairs_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..11547c6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_stairs_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_stairs_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_stairs_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_trapdoor_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_trapdoor_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..ecae080
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_trapdoor_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_trapdoor_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_trapdoor_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_wood_from_mushroom_fir_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_wood_from_mushroom_fir_log.json
new file mode 100644
index 0000000..6ff6716
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_fir_wood_from_mushroom_fir_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_fir_wood_from_mushroom_fir_log"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_fir_wood_from_mushroom_fir_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_gate_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_gate_from_mushroom_planks.json
new file mode 100644
index 0000000..d089228
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_gate_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_gate_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_gate_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_ladder_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_ladder_from_mushroom_planks.json
new file mode 100644
index 0000000..100902e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_ladder_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_ladder_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_ladder_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_planks_from_mushroom_stem.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_planks_from_mushroom_stem.json
new file mode 100644
index 0000000..6cfdf32
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_planks_from_mushroom_stem.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_planks_from_mushroom_stem"
+ ]
+ },
+ "criteria": {
+ "mushroom_stem": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_stem"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_planks_from_mushroom_stem"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_stem",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_plate_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_plate_from_mushroom_planks.json
new file mode 100644
index 0000000..ad02a7a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_plate_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_plate_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_plate_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_slab_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_slab_from_mushroom_planks.json
new file mode 100644
index 0000000..10c258d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_slab_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_slab_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_slab_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_stairs_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_stairs_from_mushroom_planks.json
new file mode 100644
index 0000000..2f7c3de
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_stairs_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_stairs_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_stairs_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_trapdoor_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_trapdoor_from_mushroom_planks.json
new file mode 100644
index 0000000..6af2693
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/mushroom_trapdoor_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:mushroom_trapdoor_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:mushroom_trapdoor_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_tile_slab_from_nether_brick_tile_small.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_tile_slab_from_nether_brick_tile_small.json
new file mode 100644
index 0000000..dd23b3b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_tile_slab_from_nether_brick_tile_small.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_brick_tile_slab_from_nether_brick_tile_small"
+ ]
+ },
+ "criteria": {
+ "nether_brick_tile_small": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_brick_tile_small"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_brick_tile_slab_from_nether_brick_tile_small"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_brick_tile_small",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_tile_stairs_from_nether_brick_tile_small.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_tile_stairs_from_nether_brick_tile_small.json
new file mode 100644
index 0000000..20ff83f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_tile_stairs_from_nether_brick_tile_small.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_brick_tile_stairs_from_nether_brick_tile_small"
+ ]
+ },
+ "criteria": {
+ "nether_brick_tile_small": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_brick_tile_small"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_brick_tile_stairs_from_nether_brick_tile_small"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_brick_tile_small",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_wall_from_nether_brick_tile_large.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_wall_from_nether_brick_tile_large.json
new file mode 100644
index 0000000..80853a8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_brick_wall_from_nether_brick_tile_large.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_brick_wall_from_nether_brick_tile_large"
+ ]
+ },
+ "criteria": {
+ "nether_brick_tile_large": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_brick_tile_large"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_brick_wall_from_nether_brick_tile_large"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_brick_tile_large",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_ruby_slab_from_nether_ruby_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_ruby_slab_from_nether_ruby_block.json
new file mode 100644
index 0000000..65367c6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_ruby_slab_from_nether_ruby_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_ruby_slab_from_nether_ruby_block"
+ ]
+ },
+ "criteria": {
+ "nether_ruby_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_ruby_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_ruby_slab_from_nether_ruby_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_ruby_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_ruby_stairs_from_nether_ruby_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_ruby_stairs_from_nether_ruby_block.json
new file mode 100644
index 0000000..b36e780
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_ruby_stairs_from_nether_ruby_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_ruby_stairs_from_nether_ruby_block"
+ ]
+ },
+ "criteria": {
+ "nether_ruby_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_ruby_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_ruby_stairs_from_nether_ruby_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_ruby_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_bark_from_nether_sakura_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_bark_from_nether_sakura_log.json
new file mode 100644
index 0000000..f812914
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_bark_from_nether_sakura_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_bark_from_nether_sakura_log"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_bark_from_nether_sakura_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_button_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_button_from_nether_sakura_planks.json
new file mode 100644
index 0000000..6a977ca
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_button_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_button_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_button_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_door_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_door_from_nether_sakura_planks.json
new file mode 100644
index 0000000..8c07003
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_door_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_door_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_door_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_fence_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_fence_from_nether_sakura_planks.json
new file mode 100644
index 0000000..62c6e14
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_fence_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_fence_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_fence_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_gate_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_gate_from_nether_sakura_planks.json
new file mode 100644
index 0000000..271b839
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_gate_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_gate_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_gate_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_ladder_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_ladder_from_nether_sakura_planks.json
new file mode 100644
index 0000000..9371cdd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_ladder_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_ladder_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_ladder_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_bark.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_bark.json
new file mode 100644
index 0000000..b184feb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_bark.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_planks_from_nether_sakura_bark"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_bark": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_bark"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_planks_from_nether_sakura_bark"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_bark",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_log.json
new file mode 100644
index 0000000..2e56d63
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_nether_sakura_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_planks_from_nether_sakura_log"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_planks_from_nether_sakura_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_bark_nether_sakura.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_bark_nether_sakura.json
new file mode 100644
index 0000000..1445934
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_bark_nether_sakura.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_planks_from_striped_bark_nether_sakura"
+ ]
+ },
+ "criteria": {
+ "striped_bark_nether_sakura": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_bark_nether_sakura"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_planks_from_striped_bark_nether_sakura"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_bark_nether_sakura",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_log_nether_sakura.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_log_nether_sakura.json
new file mode 100644
index 0000000..af7b40d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_planks_from_striped_log_nether_sakura.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_planks_from_striped_log_nether_sakura"
+ ]
+ },
+ "criteria": {
+ "striped_log_nether_sakura": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_nether_sakura"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_planks_from_striped_log_nether_sakura"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_nether_sakura",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_plate_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_plate_from_nether_sakura_planks.json
new file mode 100644
index 0000000..3385a56
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_plate_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_plate_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_plate_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_slab_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_slab_from_nether_sakura_planks.json
new file mode 100644
index 0000000..87a55c3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_slab_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_slab_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_slab_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_stairs_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_stairs_from_nether_sakura_planks.json
new file mode 100644
index 0000000..4b1da55
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_stairs_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_stairs_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_stairs_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_trapdoor_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_trapdoor_from_nether_sakura_planks.json
new file mode 100644
index 0000000..5547409
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/nether_sakura_trapdoor_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:nether_sakura_trapdoor_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:nether_sakura_trapdoor_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_from_netherite_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_from_netherite_block.json
new file mode 100644
index 0000000..711f6f3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_from_netherite_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:netherite_fire_bowl_from_netherite_block"
+ ]
+ },
+ "criteria": {
+ "netherite_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:netherite_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:netherite_fire_bowl_from_netherite_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "netherite_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_soul_from_netherite_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_soul_from_netherite_block.json
new file mode 100644
index 0000000..b664943
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherite_fire_bowl_soul_from_netherite_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:netherite_fire_bowl_soul_from_netherite_block"
+ ]
+ },
+ "criteria": {
+ "netherite_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:netherite_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:netherite_fire_bowl_soul_from_netherite_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "netherite_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherrack_furnace_from_netherrack.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherrack_furnace_from_netherrack.json
new file mode 100644
index 0000000..661e611
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherrack_furnace_from_netherrack.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:netherrack_furnace_from_netherrack"
+ ]
+ },
+ "criteria": {
+ "netherrack": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:netherrack"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:netherrack_furnace_from_netherrack"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "netherrack",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherrack_stalactite_from_netherrack.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherrack_stalactite_from_netherrack.json
new file mode 100644
index 0000000..559a333
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/netherrack_stalactite_from_netherrack.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:netherrack_stalactite_from_netherrack"
+ ]
+ },
+ "criteria": {
+ "netherrack": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:netherrack"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:netherrack_stalactite_from_netherrack"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "netherrack",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_bricks_slab_from_obsidian_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_bricks_slab_from_obsidian_bricks.json
new file mode 100644
index 0000000..b5d55f9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_bricks_slab_from_obsidian_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:obsidian_bricks_slab_from_obsidian_bricks"
+ ]
+ },
+ "criteria": {
+ "obsidian_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:obsidian_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:obsidian_bricks_slab_from_obsidian_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "obsidian_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_bricks_stairs_from_obsidian_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_bricks_stairs_from_obsidian_bricks.json
new file mode 100644
index 0000000..ef6495a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_bricks_stairs_from_obsidian_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:obsidian_bricks_stairs_from_obsidian_bricks"
+ ]
+ },
+ "criteria": {
+ "obsidian_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:obsidian_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:obsidian_bricks_stairs_from_obsidian_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "obsidian_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_tile_slab_from_obsidian_tile_small.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_tile_slab_from_obsidian_tile_small.json
new file mode 100644
index 0000000..f9e248e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_tile_slab_from_obsidian_tile_small.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:obsidian_tile_slab_from_obsidian_tile_small"
+ ]
+ },
+ "criteria": {
+ "obsidian_tile_small": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:obsidian_tile_small"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:obsidian_tile_slab_from_obsidian_tile_small"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "obsidian_tile_small",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_tile_stairs_from_obsidian_tile_small.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_tile_stairs_from_obsidian_tile_small.json
new file mode 100644
index 0000000..6695849
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/obsidian_tile_stairs_from_obsidian_tile_small.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:obsidian_tile_stairs_from_obsidian_tile_small"
+ ]
+ },
+ "criteria": {
+ "obsidian_tile_small": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:obsidian_tile_small"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:obsidian_tile_stairs_from_obsidian_tile_small"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "obsidian_tile_small",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_button_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_button_from_reeds_block.json
new file mode 100644
index 0000000..9002040
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_button_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_button_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_button_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_door_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_door_from_reeds_block.json
new file mode 100644
index 0000000..a1e9c5c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_door_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_door_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_door_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_fence_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_fence_from_reeds_block.json
new file mode 100644
index 0000000..80604ab
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_fence_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_fence_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_fence_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_gate_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_gate_from_reeds_block.json
new file mode 100644
index 0000000..08b1640
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_gate_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_gate_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_gate_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_ladder_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_ladder_from_reeds_block.json
new file mode 100644
index 0000000..252f6d6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_ladder_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_ladder_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_ladder_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_plate_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_plate_from_reeds_block.json
new file mode 100644
index 0000000..bc8f984
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_plate_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_plate_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_plate_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_slab_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_slab_from_reeds_block.json
new file mode 100644
index 0000000..30407cc
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_slab_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_slab_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_slab_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_stairs_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_stairs_from_reeds_block.json
new file mode 100644
index 0000000..c99c176
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_stairs_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_stairs_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_stairs_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_trapdoor_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_trapdoor_from_reeds_block.json
new file mode 100644
index 0000000..348c111
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/reeds_trapdoor_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:reeds_trapdoor_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:reeds_trapdoor_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_from_cincinnasite_forged.json
new file mode 100644
index 0000000..1929a7c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_from_cincinnasite_forged.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_cincinnasite_from_cincinnasite_forged"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_forged": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_forged"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_cincinnasite_from_cincinnasite_forged"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_forged",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json
new file mode 100644
index 0000000..dbcc1a4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite"
+ ]
+ },
+ "criteria": {
+ "roof_tile_cincinnasite": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_cincinnasite"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_cincinnasite",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json
new file mode 100644
index 0000000..b3bdd67
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite"
+ ]
+ },
+ "criteria": {
+ "roof_tile_cincinnasite": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_cincinnasite"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_cincinnasite",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_from_nether_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_from_nether_bricks.json
new file mode 100644
index 0000000..277930f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_from_nether_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_nether_bricks_from_nether_bricks"
+ ]
+ },
+ "criteria": {
+ "nether_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:nether_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_nether_bricks_from_nether_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json
new file mode 100644
index 0000000..0085e86
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks"
+ ]
+ },
+ "criteria": {
+ "roof_tile_nether_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_nether_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_nether_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json
new file mode 100644
index 0000000..6b12a4d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks"
+ ]
+ },
+ "criteria": {
+ "roof_tile_nether_bricks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_nether_bricks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_nether_bricks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_from_reeds_block.json
new file mode 100644
index 0000000..98ed5f3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_reeds_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_reeds_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_slab_from_roof_tile_reeds.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_slab_from_roof_tile_reeds.json
new file mode 100644
index 0000000..55851c1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_slab_from_roof_tile_reeds.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_reeds_slab_from_roof_tile_reeds"
+ ]
+ },
+ "criteria": {
+ "roof_tile_reeds": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_reeds"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_reeds_slab_from_roof_tile_reeds"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_reeds",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_stairs_from_roof_tile_reeds.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_stairs_from_roof_tile_reeds.json
new file mode 100644
index 0000000..4943e05
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_reeds_stairs_from_roof_tile_reeds.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_reeds_stairs_from_roof_tile_reeds"
+ ]
+ },
+ "criteria": {
+ "roof_tile_reeds": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_reeds"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_reeds_stairs_from_roof_tile_reeds"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_reeds",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..1dda8b2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_stalagnate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_stalagnate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json
new file mode 100644
index 0000000..780113e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_stalagnate_slab_from_roof_tile_stalagnate"
+ ]
+ },
+ "criteria": {
+ "roof_tile_stalagnate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_stalagnate"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_stalagnate_slab_from_roof_tile_stalagnate"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_stalagnate",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json
new file mode 100644
index 0000000..0cfb8e7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_stalagnate_stairs_from_roof_tile_stalagnate"
+ ]
+ },
+ "criteria": {
+ "roof_tile_stalagnate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_stalagnate"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_stalagnate_stairs_from_roof_tile_stalagnate"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_stalagnate",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_from_wart_planks.json
new file mode 100644
index 0000000..0391f1d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_wart_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_wart_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_slab_from_roof_tile_wart.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_slab_from_roof_tile_wart.json
new file mode 100644
index 0000000..cd85ba2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_slab_from_roof_tile_wart.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_wart_slab_from_roof_tile_wart"
+ ]
+ },
+ "criteria": {
+ "roof_tile_wart": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_wart"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_wart_slab_from_roof_tile_wart"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_wart",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_stairs_from_roof_tile_wart.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_stairs_from_roof_tile_wart.json
new file mode 100644
index 0000000..b7bc7c7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_wart_stairs_from_roof_tile_wart.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_wart_stairs_from_roof_tile_wart"
+ ]
+ },
+ "criteria": {
+ "roof_tile_wart": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_wart"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_wart_stairs_from_roof_tile_wart"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_wart",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_from_willow_planks.json
new file mode 100644
index 0000000..e65de74
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_willow_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_willow_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_slab_from_roof_tile_willow.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_slab_from_roof_tile_willow.json
new file mode 100644
index 0000000..bc21149
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_slab_from_roof_tile_willow.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_willow_slab_from_roof_tile_willow"
+ ]
+ },
+ "criteria": {
+ "roof_tile_willow": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_willow"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_willow_slab_from_roof_tile_willow"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_willow",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_stairs_from_roof_tile_willow.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_stairs_from_roof_tile_willow.json
new file mode 100644
index 0000000..53f2215
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/roof_tile_willow_stairs_from_roof_tile_willow.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:roof_tile_willow_stairs_from_roof_tile_willow"
+ ]
+ },
+ "criteria": {
+ "roof_tile_willow": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:roof_tile_willow"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:roof_tile_willow_stairs_from_roof_tile_willow"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "roof_tile_willow",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_bark_from_rubeus_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_bark_from_rubeus_log.json
new file mode 100644
index 0000000..e492cf7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_bark_from_rubeus_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_bark_from_rubeus_log"
+ ]
+ },
+ "criteria": {
+ "rubeus_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_bark_from_rubeus_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_button_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_button_from_rubeus_planks.json
new file mode 100644
index 0000000..e717986
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_button_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_button_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_button_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_door_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_door_from_rubeus_planks.json
new file mode 100644
index 0000000..4215535
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_door_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_door_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_door_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_fence_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_fence_from_rubeus_planks.json
new file mode 100644
index 0000000..07f0d44
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_fence_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_fence_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_fence_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_gate_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_gate_from_rubeus_planks.json
new file mode 100644
index 0000000..053b79c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_gate_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_gate_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_gate_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_ladder_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_ladder_from_rubeus_planks.json
new file mode 100644
index 0000000..8623511
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_ladder_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_ladder_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_ladder_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_bark.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_bark.json
new file mode 100644
index 0000000..ea3c9f3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_bark.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_planks_from_rubeus_bark"
+ ]
+ },
+ "criteria": {
+ "rubeus_bark": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_bark"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_planks_from_rubeus_bark"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_bark",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_log.json
new file mode 100644
index 0000000..75cf9f6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_rubeus_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_planks_from_rubeus_log"
+ ]
+ },
+ "criteria": {
+ "rubeus_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_planks_from_rubeus_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_bark_rubeus.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_bark_rubeus.json
new file mode 100644
index 0000000..579b7d4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_bark_rubeus.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_planks_from_striped_bark_rubeus"
+ ]
+ },
+ "criteria": {
+ "striped_bark_rubeus": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_bark_rubeus"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_planks_from_striped_bark_rubeus"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_bark_rubeus",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_log_rubeus.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_log_rubeus.json
new file mode 100644
index 0000000..a692b7b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_planks_from_striped_log_rubeus.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_planks_from_striped_log_rubeus"
+ ]
+ },
+ "criteria": {
+ "striped_log_rubeus": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_rubeus"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_planks_from_striped_log_rubeus"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_rubeus",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_plate_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_plate_from_rubeus_planks.json
new file mode 100644
index 0000000..7fbc03d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_plate_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_plate_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_plate_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_slab_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_slab_from_rubeus_planks.json
new file mode 100644
index 0000000..2590298
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_slab_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_slab_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_slab_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_stairs_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_stairs_from_rubeus_planks.json
new file mode 100644
index 0000000..58fc247
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_stairs_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_stairs_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_stairs_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_trapdoor_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_trapdoor_from_rubeus_planks.json
new file mode 100644
index 0000000..ebbc4b6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/rubeus_trapdoor_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:rubeus_trapdoor_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:rubeus_trapdoor_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..0293b86
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_anchor_tree_from_anchor_tree_planks"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_anchor_tree_from_anchor_tree_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..8579f3a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_mushroom_fir_from_mushroom_fir_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_mushroom_fir_from_mushroom_fir_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..293027f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_mushroom_from_mushroom_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_mushroom_from_mushroom_planks"
+ ]
+ },
+ "criteria": {
+ "mushroom_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_mushroom_from_mushroom_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..defe31d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_nether_sakura_from_nether_sakura_planks"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_nether_sakura_from_nether_sakura_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_reed_from_reeds_block.json
new file mode 100644
index 0000000..278564f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_reed_from_reeds_block.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_reed_from_reeds_block"
+ ]
+ },
+ "criteria": {
+ "reeds_block": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_reed_from_reeds_block"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_block",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..92a8cbf
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_rubeus_from_rubeus_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_rubeus_from_rubeus_planks"
+ ]
+ },
+ "criteria": {
+ "rubeus_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_rubeus_from_rubeus_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..58bf1a7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_stalagnate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_stalagnate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_wart_from_wart_planks.json
new file mode 100644
index 0000000..57c5abe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_wart_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_wart_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_wart_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_willow_from_willow_planks.json
new file mode 100644
index 0000000..be25fd0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/sign_willow_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:sign_willow_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:sign_willow_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_chiseled_from_soul_sandstone_smooth.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_chiseled_from_soul_sandstone_smooth.json
new file mode 100644
index 0000000..bfddf5d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_chiseled_from_soul_sandstone_smooth.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_chiseled_from_soul_sandstone_smooth"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_smooth": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_smooth"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_chiseled_from_soul_sandstone_smooth"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_smooth",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_from_soul_sandstone.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_from_soul_sandstone.json
new file mode 100644
index 0000000..8616a24
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_from_soul_sandstone.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_cut_from_soul_sandstone"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_cut_from_soul_sandstone"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_slab_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_slab_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..16c5836
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_slab_from_soul_sandstone_cut.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_cut_slab_from_soul_sandstone_cut"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_cut": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_cut_slab_from_soul_sandstone_cut"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_cut",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..955bf4c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_cut_stairs_from_soul_sandstone_cut"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_cut": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_cut_stairs_from_soul_sandstone_cut"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_cut",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_slab_from_soul_sandstone.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_slab_from_soul_sandstone.json
new file mode 100644
index 0000000..55e20fd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_slab_from_soul_sandstone.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_slab_from_soul_sandstone"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_slab_from_soul_sandstone"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..3ad6906
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_from_soul_sandstone_cut.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_smooth_from_soul_sandstone_cut"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_cut": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_smooth_from_soul_sandstone_cut"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_cut",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json
new file mode 100644
index 0000000..a6bad61
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_smooth_slab_from_soul_sandstone_smooth"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_smooth": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_smooth"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_smooth_slab_from_soul_sandstone_smooth"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_smooth",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json
new file mode 100644
index 0000000..91c3cd3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_smooth_stairs_from_soul_sandstone_smooth"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_smooth": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_smooth"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_smooth_stairs_from_soul_sandstone_smooth"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_smooth",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_stairs_from_soul_sandstone.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_stairs_from_soul_sandstone.json
new file mode 100644
index 0000000..8606f8b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_stairs_from_soul_sandstone.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_stairs_from_soul_sandstone"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_stairs_from_soul_sandstone"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_wall_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_wall_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..6b306ff
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/soul_sandstone_wall_from_soul_sandstone_cut.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:soul_sandstone_wall_from_soul_sandstone_cut"
+ ]
+ },
+ "criteria": {
+ "soul_sandstone_cut": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:soul_sandstone_wall_from_soul_sandstone_cut"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "soul_sandstone_cut",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_bark_from_stalagnate_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_bark_from_stalagnate_log.json
new file mode 100644
index 0000000..241fdcf
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_bark_from_stalagnate_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_bark_from_stalagnate_log"
+ ]
+ },
+ "criteria": {
+ "stalagnate_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_bark_from_stalagnate_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_ladder_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_ladder_from_stalagnate_planks.json
new file mode 100644
index 0000000..91706c7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_ladder_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_ladder_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_ladder_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_log_from_stalagnate_stem.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_log_from_stalagnate_stem.json
new file mode 100644
index 0000000..a73bce2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_log_from_stalagnate_stem.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_log_from_stalagnate_stem"
+ ]
+ },
+ "criteria": {
+ "stalagnate_stem": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_stem"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_log_from_stalagnate_stem"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_stem",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_button_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_button_from_stalagnate_planks.json
new file mode 100644
index 0000000..9c6d626
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_button_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_button_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_button_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_door_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_door_from_stalagnate_planks.json
new file mode 100644
index 0000000..697dd70
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_door_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_door_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_door_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_fence_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_fence_from_stalagnate_planks.json
new file mode 100644
index 0000000..aecf460
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_fence_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_fence_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_fence_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_bark.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_bark.json
new file mode 100644
index 0000000..c44a16b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_bark.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_from_stalagnate_bark"
+ ]
+ },
+ "criteria": {
+ "stalagnate_bark": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_bark"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_from_stalagnate_bark"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_bark",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_log.json
new file mode 100644
index 0000000..b8fc56c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_from_stalagnate_log"
+ ]
+ },
+ "criteria": {
+ "stalagnate_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_from_stalagnate_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_stem.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_stem.json
new file mode 100644
index 0000000..b6b8a18
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_stalagnate_stem.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_from_stalagnate_stem"
+ ]
+ },
+ "criteria": {
+ "stalagnate_stem": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_stem"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_from_stalagnate_stem"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_stem",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_bark_stalagnate.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_bark_stalagnate.json
new file mode 100644
index 0000000..b299f0b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_bark_stalagnate.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_from_striped_bark_stalagnate"
+ ]
+ },
+ "criteria": {
+ "striped_bark_stalagnate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_bark_stalagnate"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_from_striped_bark_stalagnate"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_bark_stalagnate",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_log_stalagnate.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_log_stalagnate.json
new file mode 100644
index 0000000..a3cc591
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_from_striped_log_stalagnate.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_from_striped_log_stalagnate"
+ ]
+ },
+ "criteria": {
+ "striped_log_stalagnate": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_stalagnate"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_from_striped_log_stalagnate"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_stalagnate",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_gate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_gate_from_stalagnate_planks.json
new file mode 100644
index 0000000..945c597
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_gate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_gate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_gate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_plate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_plate_from_stalagnate_planks.json
new file mode 100644
index 0000000..114ed65
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_plate_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_plate_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_plate_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_slab_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_slab_from_stalagnate_planks.json
new file mode 100644
index 0000000..5c8556b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_slab_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_slab_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_slab_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_stairs_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_stairs_from_stalagnate_planks.json
new file mode 100644
index 0000000..7adab52
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_stairs_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_stairs_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_stairs_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_trapdoor_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_trapdoor_from_stalagnate_planks.json
new file mode 100644
index 0000000..9fd8bdd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/stalagnate_planks_trapdoor_from_stalagnate_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:stalagnate_planks_trapdoor_from_stalagnate_planks"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:stalagnate_planks_trapdoor_from_stalagnate_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_acacia_from_acacia_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_acacia_from_acacia_slab.json
new file mode 100644
index 0000000..801fd44
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_acacia_from_acacia_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_acacia_from_acacia_slab"
+ ]
+ },
+ "criteria": {
+ "acacia_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:acacia_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_acacia_from_acacia_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "acacia_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_anchor_tree_from_anchor_tree_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_anchor_tree_from_anchor_tree_slab.json
new file mode 100644
index 0000000..be389e2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_anchor_tree_from_anchor_tree_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_anchor_tree_from_anchor_tree_slab"
+ ]
+ },
+ "criteria": {
+ "anchor_tree_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:anchor_tree_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_anchor_tree_from_anchor_tree_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "anchor_tree_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_birch_from_birch_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_birch_from_birch_slab.json
new file mode 100644
index 0000000..bd3fc50
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_birch_from_birch_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_birch_from_birch_slab"
+ ]
+ },
+ "criteria": {
+ "birch_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:birch_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_birch_from_birch_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "birch_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_cincinnasite_from_cincinnasite_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_cincinnasite_from_cincinnasite_slab.json
new file mode 100644
index 0000000..38c70b9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_cincinnasite_from_cincinnasite_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_cincinnasite_from_cincinnasite_slab"
+ ]
+ },
+ "criteria": {
+ "cincinnasite_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:cincinnasite_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_cincinnasite_from_cincinnasite_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "cincinnasite_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_crimson_from_crimson_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_crimson_from_crimson_slab.json
new file mode 100644
index 0000000..17cb67b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_crimson_from_crimson_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_crimson_from_crimson_slab"
+ ]
+ },
+ "criteria": {
+ "crimson_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:crimson_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_crimson_from_crimson_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "crimson_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_dark_oak_from_dark_oak_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_dark_oak_from_dark_oak_slab.json
new file mode 100644
index 0000000..0ad138e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_dark_oak_from_dark_oak_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_dark_oak_from_dark_oak_slab"
+ ]
+ },
+ "criteria": {
+ "dark_oak_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:dark_oak_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_dark_oak_from_dark_oak_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "dark_oak_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_jungle_from_jungle_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_jungle_from_jungle_slab.json
new file mode 100644
index 0000000..f4cf4d4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_jungle_from_jungle_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_jungle_from_jungle_slab"
+ ]
+ },
+ "criteria": {
+ "jungle_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:jungle_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_jungle_from_jungle_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "jungle_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_mushroom_fir_from_mushroom_fir_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_mushroom_fir_from_mushroom_fir_slab.json
new file mode 100644
index 0000000..e0665c2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_mushroom_fir_from_mushroom_fir_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_mushroom_fir_from_mushroom_fir_slab"
+ ]
+ },
+ "criteria": {
+ "mushroom_fir_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_fir_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_mushroom_fir_from_mushroom_fir_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_fir_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_mushroom_from_mushroom_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_mushroom_from_mushroom_slab.json
new file mode 100644
index 0000000..76a3574
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_mushroom_from_mushroom_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_mushroom_from_mushroom_slab"
+ ]
+ },
+ "criteria": {
+ "mushroom_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:mushroom_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_mushroom_from_mushroom_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "mushroom_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_nether_sakura_from_nether_sakura_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_nether_sakura_from_nether_sakura_slab.json
new file mode 100644
index 0000000..3824007
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_nether_sakura_from_nether_sakura_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_nether_sakura_from_nether_sakura_slab"
+ ]
+ },
+ "criteria": {
+ "nether_sakura_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:nether_sakura_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_nether_sakura_from_nether_sakura_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "nether_sakura_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_oak_from_oak_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_oak_from_oak_slab.json
new file mode 100644
index 0000000..b5f9dc6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_oak_from_oak_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_oak_from_oak_slab"
+ ]
+ },
+ "criteria": {
+ "oak_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:oak_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_oak_from_oak_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "oak_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_reeds_from_reeds_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_reeds_from_reeds_slab.json
new file mode 100644
index 0000000..9c4005a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_reeds_from_reeds_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_reeds_from_reeds_slab"
+ ]
+ },
+ "criteria": {
+ "reeds_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:reeds_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_reeds_from_reeds_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "reeds_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_rubeus_from_rubeus_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_rubeus_from_rubeus_slab.json
new file mode 100644
index 0000000..dcd16f4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_rubeus_from_rubeus_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_rubeus_from_rubeus_slab"
+ ]
+ },
+ "criteria": {
+ "rubeus_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:rubeus_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_rubeus_from_rubeus_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "rubeus_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_spruce_from_spruce_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_spruce_from_spruce_slab.json
new file mode 100644
index 0000000..ceb9af2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_spruce_from_spruce_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_spruce_from_spruce_slab"
+ ]
+ },
+ "criteria": {
+ "spruce_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:spruce_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_spruce_from_spruce_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "spruce_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_stalagnate_from_stalagnate_planks_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_stalagnate_from_stalagnate_planks_slab.json
new file mode 100644
index 0000000..3bce566
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_stalagnate_from_stalagnate_planks_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_stalagnate_from_stalagnate_planks_slab"
+ ]
+ },
+ "criteria": {
+ "stalagnate_planks_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:stalagnate_planks_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_stalagnate_from_stalagnate_planks_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "stalagnate_planks_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_warped_from_warped_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_warped_from_warped_slab.json
new file mode 100644
index 0000000..ab1ac6e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_warped_from_warped_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_warped_from_warped_slab"
+ ]
+ },
+ "criteria": {
+ "warped_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_warped_from_warped_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_wart_from_wart_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_wart_from_wart_slab.json
new file mode 100644
index 0000000..e75e2e8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_wart_from_wart_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_wart_from_wart_slab"
+ ]
+ },
+ "criteria": {
+ "wart_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_wart_from_wart_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_willow_from_willow_slab.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_willow_from_willow_slab.json
new file mode 100644
index 0000000..89f6665
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/taburet_willow_from_willow_slab.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:taburet_willow_from_willow_slab"
+ ]
+ },
+ "criteria": {
+ "willow_slab": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_slab"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:taburet_willow_from_willow_slab"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_slab",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/warped_ladder_from_warped_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/warped_ladder_from_warped_planks.json
new file mode 100644
index 0000000..bf0b192
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/warped_ladder_from_warped_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:warped_ladder_from_warped_planks"
+ ]
+ },
+ "criteria": {
+ "warped_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "minecraft:warped_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:warped_ladder_from_warped_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "warped_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_bark_from_wart_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_bark_from_wart_log.json
new file mode 100644
index 0000000..02e019e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_bark_from_wart_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_bark_from_wart_log"
+ ]
+ },
+ "criteria": {
+ "wart_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_bark_from_wart_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_button_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_button_from_wart_planks.json
new file mode 100644
index 0000000..08a2a9c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_button_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_button_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_button_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_door_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_door_from_wart_planks.json
new file mode 100644
index 0000000..6eed9e2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_door_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_door_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_door_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_fence_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_fence_from_wart_planks.json
new file mode 100644
index 0000000..1b8c114
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_fence_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_fence_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_fence_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_gate_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_gate_from_wart_planks.json
new file mode 100644
index 0000000..bb52f74
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_gate_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_gate_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_gate_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_ladder_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_ladder_from_wart_planks.json
new file mode 100644
index 0000000..6b74851
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_ladder_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_ladder_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_ladder_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_bark_wart.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_bark_wart.json
new file mode 100644
index 0000000..86df51a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_bark_wart.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_planks_from_striped_bark_wart"
+ ]
+ },
+ "criteria": {
+ "striped_bark_wart": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_bark_wart"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_planks_from_striped_bark_wart"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_bark_wart",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_log_wart.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_log_wart.json
new file mode 100644
index 0000000..5f69857
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_striped_log_wart.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_planks_from_striped_log_wart"
+ ]
+ },
+ "criteria": {
+ "striped_log_wart": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_wart"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_planks_from_striped_log_wart"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_wart",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_bark.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_bark.json
new file mode 100644
index 0000000..d035427
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_bark.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_planks_from_wart_bark"
+ ]
+ },
+ "criteria": {
+ "wart_bark": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_bark"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_planks_from_wart_bark"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_bark",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_log.json
new file mode 100644
index 0000000..916bc74
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_planks_from_wart_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_planks_from_wart_log"
+ ]
+ },
+ "criteria": {
+ "wart_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_planks_from_wart_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_plate_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_plate_from_wart_planks.json
new file mode 100644
index 0000000..a1725dd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_plate_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_plate_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_plate_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_slab_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_slab_from_wart_planks.json
new file mode 100644
index 0000000..8fd4365
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_slab_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_slab_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_slab_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_stairs_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_stairs_from_wart_planks.json
new file mode 100644
index 0000000..cefe131
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_stairs_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_stairs_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_stairs_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_trapdoor_from_wart_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_trapdoor_from_wart_planks.json
new file mode 100644
index 0000000..c9ce761
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/wart_trapdoor_from_wart_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:wart_trapdoor_from_wart_planks"
+ ]
+ },
+ "criteria": {
+ "wart_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:wart_trapdoor_from_wart_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "wart_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_bark_from_willow_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_bark_from_willow_log.json
new file mode 100644
index 0000000..827a2c5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_bark_from_willow_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_bark_from_willow_log"
+ ]
+ },
+ "criteria": {
+ "willow_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_bark_from_willow_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_button_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_button_from_willow_planks.json
new file mode 100644
index 0000000..dc7e867
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_button_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_button_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_button_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_door_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_door_from_willow_planks.json
new file mode 100644
index 0000000..5ce543c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_door_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_door_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_door_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_fence_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_fence_from_willow_planks.json
new file mode 100644
index 0000000..519f1b7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_fence_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_fence_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_fence_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_gate_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_gate_from_willow_planks.json
new file mode 100644
index 0000000..77da375
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_gate_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_gate_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_gate_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_ladder_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_ladder_from_willow_planks.json
new file mode 100644
index 0000000..e6349b6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_ladder_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_ladder_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_ladder_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_bark_willow.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_bark_willow.json
new file mode 100644
index 0000000..771ef81
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_bark_willow.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_planks_from_striped_bark_willow"
+ ]
+ },
+ "criteria": {
+ "striped_bark_willow": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_bark_willow"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_planks_from_striped_bark_willow"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_bark_willow",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_log_willow.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_log_willow.json
new file mode 100644
index 0000000..36ee260
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_striped_log_willow.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_planks_from_striped_log_willow"
+ ]
+ },
+ "criteria": {
+ "striped_log_willow": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:striped_log_willow"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_planks_from_striped_log_willow"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "striped_log_willow",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_bark.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_bark.json
new file mode 100644
index 0000000..746188f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_bark.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_planks_from_willow_bark"
+ ]
+ },
+ "criteria": {
+ "willow_bark": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_bark"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_planks_from_willow_bark"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_bark",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_log.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_log.json
new file mode 100644
index 0000000..8c40c4a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_planks_from_willow_log.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_planks_from_willow_log"
+ ]
+ },
+ "criteria": {
+ "willow_log": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_log"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_planks_from_willow_log"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_log",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_plate_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_plate_from_willow_planks.json
new file mode 100644
index 0000000..bc9ba23
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_plate_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_plate_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_plate_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_slab_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_slab_from_willow_planks.json
new file mode 100644
index 0000000..e078eae
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_slab_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_slab_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_slab_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_stairs_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_stairs_from_willow_planks.json
new file mode 100644
index 0000000..4de0515
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_stairs_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_stairs_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_stairs_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_trapdoor_from_willow_planks.json b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_trapdoor_from_willow_planks.json
new file mode 100644
index 0000000..e5ecfee
--- /dev/null
+++ b/src/generated/resources/data/minecraft/advancements/recipes/betternether/willow_trapdoor_from_willow_planks.json
@@ -0,0 +1,32 @@
+{
+ "parent": "minecraft:recipes/root",
+ "rewards": {
+ "recipes": [
+ "minecraft:willow_trapdoor_from_willow_planks"
+ ]
+ },
+ "criteria": {
+ "willow_planks": {
+ "trigger": "minecraft:inventory_changed",
+ "conditions": {
+ "items": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ]
+ }
+ },
+ "has_the_recipe": {
+ "trigger": "minecraft:recipe_unlocked",
+ "conditions": {
+ "recipe": "minecraft:willow_trapdoor_from_willow_planks"
+ }
+ }
+ },
+ "requirements": [
+ [
+ "willow_planks",
+ "has_the_recipe"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_bark_from_anchor_tree_log.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_bark_from_anchor_tree_log.json
new file mode 100644
index 0000000..070a183
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_bark_from_anchor_tree_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_log"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_bark",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_button_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_button_from_anchor_tree_planks.json
new file mode 100644
index 0000000..7f8d0a5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_button_from_anchor_tree_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:anchor_tree_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:anchor_tree_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_door_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_door_from_anchor_tree_planks.json
new file mode 100644
index 0000000..fe416b7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_door_from_anchor_tree_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_fence_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_fence_from_anchor_tree_planks.json
new file mode 100644
index 0000000..6cd026b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_fence_from_anchor_tree_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_gate_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_gate_from_anchor_tree_planks.json
new file mode 100644
index 0000000..236d4f4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_gate_from_anchor_tree_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_ladder_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_ladder_from_anchor_tree_planks.json
new file mode 100644
index 0000000..c8bf576
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_ladder_from_anchor_tree_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_bark.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_bark.json
new file mode 100644
index 0000000..c3d7562
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_bark.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:anchor_tree_bark"
+ }
+ ],
+ "result": {
+ "item": "betternether:anchor_tree_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_log.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_log.json
new file mode 100644
index 0000000..36ba5e4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_anchor_tree_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:anchor_tree_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:anchor_tree_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_striped_bark_anchor_tree.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_striped_bark_anchor_tree.json
new file mode 100644
index 0000000..f26ba77
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_striped_bark_anchor_tree.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_bark_anchor_tree"
+ }
+ ],
+ "result": {
+ "item": "betternether:anchor_tree_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_striped_log_anchor_tree.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_striped_log_anchor_tree.json
new file mode 100644
index 0000000..24a76d7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_planks_from_striped_log_anchor_tree.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_anchor_tree"
+ }
+ ],
+ "result": {
+ "item": "betternether:anchor_tree_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_plate_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_plate_from_anchor_tree_planks.json
new file mode 100644
index 0000000..991f886
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_plate_from_anchor_tree_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_slab_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_slab_from_anchor_tree_planks.json
new file mode 100644
index 0000000..fee7de7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_slab_from_anchor_tree_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_stairs_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_stairs_from_anchor_tree_planks.json
new file mode 100644
index 0000000..8125159
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_stairs_from_anchor_tree_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/anchor_tree_trapdoor_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/anchor_tree_trapdoor_from_anchor_tree_planks.json
new file mode 100644
index 0000000..1cf033e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/anchor_tree_trapdoor_from_anchor_tree_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:anchor_tree_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_acacia_from_acacia_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_acacia_from_acacia_slab.json
new file mode 100644
index 0000000..5121361
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_acacia_from_acacia_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:acacia_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_acacia"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_anchor_tree_from_anchor_tree_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_anchor_tree_from_anchor_tree_slab.json
new file mode 100644
index 0000000..ec92a29
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_anchor_tree_from_anchor_tree_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_birch_from_birch_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_birch_from_birch_slab.json
new file mode 100644
index 0000000..8ecce7d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_birch_from_birch_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:birch_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_birch"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_cincinnasite_from_cincinnasite_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_cincinnasite_from_cincinnasite_slab.json
new file mode 100644
index 0000000..b68d79a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_cincinnasite_from_cincinnasite_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_cincinnasite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_crimson_from_crimson_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_crimson_from_crimson_slab.json
new file mode 100644
index 0000000..43d238b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_crimson_from_crimson_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_crimson"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_dark_oak_from_dark_oak_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_dark_oak_from_dark_oak_slab.json
new file mode 100644
index 0000000..02c6cd0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_dark_oak_from_dark_oak_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:dark_oak_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_dark_oak"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_jungle_from_jungle_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_jungle_from_jungle_slab.json
new file mode 100644
index 0000000..9163dfe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_jungle_from_jungle_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:jungle_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_jungle"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_mushroom_fir_from_mushroom_fir_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_mushroom_fir_from_mushroom_fir_slab.json
new file mode 100644
index 0000000..3f6d67a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_mushroom_fir_from_mushroom_fir_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_mushroom_from_mushroom_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_mushroom_from_mushroom_slab.json
new file mode 100644
index 0000000..83c323d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_mushroom_from_mushroom_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_nether_sakura_from_nether_sakura_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_nether_sakura_from_nether_sakura_slab.json
new file mode 100644
index 0000000..65b7472
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_nether_sakura_from_nether_sakura_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_oak_from_oak_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_oak_from_oak_slab.json
new file mode 100644
index 0000000..4934895
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_oak_from_oak_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:oak_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_oak"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_reeds_from_reeds_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_reeds_from_reeds_slab.json
new file mode 100644
index 0000000..a8be818
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_reeds_from_reeds_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_reeds"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_rubeus_from_rubeus_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_rubeus_from_rubeus_slab.json
new file mode 100644
index 0000000..0f3f0d8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_rubeus_from_rubeus_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_spruce_from_spruce_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_spruce_from_spruce_slab.json
new file mode 100644
index 0000000..b5a4ded
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_spruce_from_spruce_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:spruce_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_spruce"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_stalagnate_from_stalagnate_planks_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_stalagnate_from_stalagnate_planks_slab.json
new file mode 100644
index 0000000..4ff1935
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_stalagnate_from_stalagnate_planks_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_warped_from_warped_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_warped_from_warped_slab.json
new file mode 100644
index 0000000..c9558d6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_warped_from_warped_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_warped"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_wart_from_wart_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_wart_from_wart_slab.json
new file mode 100644
index 0000000..f1c8f08
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_wart_from_wart_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bar_stool_willow_from_willow_slab.json b/src/generated/resources/data/minecraft/recipes/bar_stool_willow_from_willow_slab.json
new file mode 100644
index 0000000..51a847c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bar_stool_willow_from_willow_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:bar_stool_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..513b180
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ },
+ "S": {
+ "item": "betternether:anchor_tree_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_crimson_from_crimson_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_crimson_from_crimson_planks.json
new file mode 100644
index 0000000..b57b37d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_crimson_from_crimson_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_planks"
+ },
+ "S": {
+ "item": "minecraft:crimson_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_crimson"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..dd9a4b5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ },
+ "S": {
+ "item": "betternether:mushroom_fir_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..37eab79
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_mushroom_from_mushroom_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ },
+ "S": {
+ "item": "betternether:mushroom_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..49bc61d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ },
+ "S": {
+ "item": "betternether:nether_sakura_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/barrel_reed_from_reeds_block.json
new file mode 100644
index 0000000..94e4027
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_reed_from_reeds_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ },
+ "S": {
+ "item": "betternether:reeds_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_reed"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..7135385
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_rubeus_from_rubeus_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ },
+ "S": {
+ "item": "betternether:rubeus_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..482e939
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ },
+ "S": {
+ "item": "betternether:stalagnate_planks_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_warped_from_warped_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_warped_from_warped_planks.json
new file mode 100644
index 0000000..b53432c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_warped_from_warped_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_planks"
+ },
+ "S": {
+ "item": "minecraft:warped_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_warped"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_wart_from_wart_planks.json
new file mode 100644
index 0000000..ca9dfda
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_wart_from_wart_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ },
+ "S": {
+ "item": "betternether:wart_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/barrel_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/barrel_willow_from_willow_planks.json
new file mode 100644
index 0000000..668cfed
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/barrel_willow_from_willow_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#S#",
+ "# #",
+ "#S#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ },
+ "S": {
+ "item": "betternether:willow_slab"
+ }
+ },
+ "result": {
+ "item": "betternether:barrel_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_bricks_from_polished_basalt.json b/src/generated/resources/data/minecraft/recipes/basalt_bricks_from_polished_basalt.json
new file mode 100644
index 0000000..21d37ce
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_bricks_from_polished_basalt.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:polished_basalt"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_bricks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_bricks_slab_from_basalt_bricks.json b/src/generated/resources/data/minecraft/recipes/basalt_bricks_slab_from_basalt_bricks.json
new file mode 100644
index 0000000..e07b19e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_bricks_slab_from_basalt_bricks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:basalt_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_bricks_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_bricks_stairs_from_basalt_bricks.json b/src/generated/resources/data/minecraft/recipes/basalt_bricks_stairs_from_basalt_bricks.json
new file mode 100644
index 0000000..c8ffa08
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_bricks_stairs_from_basalt_bricks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:basalt_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_bricks_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_bricks_wall_from_basalt_bricks.json b/src/generated/resources/data/minecraft/recipes/basalt_bricks_wall_from_basalt_bricks.json
new file mode 100644
index 0000000..5dcf5c0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_bricks_wall_from_basalt_bricks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:basalt_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_bricks_wall",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_furnace_from_basalt.json b/src/generated/resources/data/minecraft/recipes/basalt_furnace_from_basalt.json
new file mode 100644
index 0000000..3502144
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_furnace_from_basalt.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:basalt"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_furnace"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_slab_from_basalt.json b/src/generated/resources/data/minecraft/recipes/basalt_slab_from_basalt.json
new file mode 100644
index 0000000..664d1fc
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_slab_from_basalt.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:basalt"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/basalt_stalactite_from_basalt.json b/src/generated/resources/data/minecraft/recipes/basalt_stalactite_from_basalt.json
new file mode 100644
index 0000000..bf120f1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/basalt_stalactite_from_basalt.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:basalt"
+ }
+ },
+ "result": {
+ "item": "betternether:basalt_stalactite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/blackstone_furnace_from_blackstone.json b/src/generated/resources/data/minecraft/recipes/blackstone_furnace_from_blackstone.json
new file mode 100644
index 0000000..48b9246
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/blackstone_furnace_from_blackstone.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:blackstone"
+ }
+ },
+ "result": {
+ "item": "betternether:blackstone_furnace"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/blackstone_stalactite_from_blackstone.json b/src/generated/resources/data/minecraft/recipes/blackstone_stalactite_from_blackstone.json
new file mode 100644
index 0000000..64a991f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/blackstone_stalactite_from_blackstone.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:blackstone"
+ }
+ },
+ "result": {
+ "item": "betternether:blackstone_stalactite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json b/src/generated/resources/data/minecraft/recipes/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json
new file mode 100644
index 0000000..54ab456
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/blue_obsidian_bricks_slab_from_blue_obsidian_bricks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:blue_obsidian_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:blue_obsidian_bricks_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json b/src/generated/resources/data/minecraft/recipes/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json
new file mode 100644
index 0000000..2d72ef8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/blue_obsidian_bricks_stairs_from_blue_obsidian_bricks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:blue_obsidian_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:blue_obsidian_bricks_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json b/src/generated/resources/data/minecraft/recipes/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json
new file mode 100644
index 0000000..e763158
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/blue_obsidian_tile_slab_from_blue_obsidian_tile_small.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:blue_obsidian_tile_small"
+ }
+ },
+ "result": {
+ "item": "betternether:blue_obsidian_tile_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json b/src/generated/resources/data/minecraft/recipes/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json
new file mode 100644
index 0000000..dab5bfd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/blue_obsidian_tile_stairs_from_blue_obsidian_tile_small.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:blue_obsidian_tile_small"
+ }
+ },
+ "result": {
+ "item": "betternether:blue_obsidian_tile_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bone_button_from_bone_block.json b/src/generated/resources/data/minecraft/recipes/bone_button_from_bone_block.json
new file mode 100644
index 0000000..7eb3a99
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bone_button_from_bone_block.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:bone_block"
+ }
+ ],
+ "result": {
+ "item": "betternether:bone_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bone_plate_from_bone_block.json b/src/generated/resources/data/minecraft/recipes/bone_plate_from_bone_block.json
new file mode 100644
index 0000000..b977857
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bone_plate_from_bone_block.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:bone_block"
+ }
+ },
+ "result": {
+ "item": "betternether:bone_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bone_slab_from_bone_block.json b/src/generated/resources/data/minecraft/recipes/bone_slab_from_bone_block.json
new file mode 100644
index 0000000..0663df7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bone_slab_from_bone_block.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:bone_block"
+ }
+ },
+ "result": {
+ "item": "betternether:bone_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bone_stairs_from_bone_block.json b/src/generated/resources/data/minecraft/recipes/bone_stairs_from_bone_block.json
new file mode 100644
index 0000000..424bdc8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bone_stairs_from_bone_block.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:bone_block"
+ }
+ },
+ "result": {
+ "item": "betternether:bone_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bone_stalactite_from_bone_block.json b/src/generated/resources/data/minecraft/recipes/bone_stalactite_from_bone_block.json
new file mode 100644
index 0000000..325d579
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bone_stalactite_from_bone_block.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:bone_block"
+ }
+ },
+ "result": {
+ "item": "betternether:bone_stalactite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bone_wall_from_bone_block.json b/src/generated/resources/data/minecraft/recipes/bone_wall_from_bone_block.json
new file mode 100644
index 0000000..9f08509
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bone_wall_from_bone_block.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:bone_block"
+ }
+ },
+ "result": {
+ "item": "betternether:bone_wall",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bricks_fire_bowl_from_nether_brick_tile_large.json b/src/generated/resources/data/minecraft/recipes/bricks_fire_bowl_from_nether_brick_tile_large.json
new file mode 100644
index 0000000..cfbf0b6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bricks_fire_bowl_from_nether_brick_tile_large.json
@@ -0,0 +1,23 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ " # ",
+ "L L"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_brick_tile_large"
+ },
+ "I": {
+ "item": "minecraft:nether_brick"
+ },
+ "L": {
+ "item": "minecraft:netherrack"
+ }
+ },
+ "result": {
+ "item": "betternether:bricks_fire_bowl"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/bricks_fire_bowl_soul_from_nether_brick_tile_large.json b/src/generated/resources/data/minecraft/recipes/bricks_fire_bowl_soul_from_nether_brick_tile_large.json
new file mode 100644
index 0000000..19225d9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/bricks_fire_bowl_soul_from_nether_brick_tile_large.json
@@ -0,0 +1,23 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ " # ",
+ "L L"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_brick_tile_large"
+ },
+ "I": {
+ "item": "minecraft:nether_brick"
+ },
+ "L": {
+ "item": "minecraft:soul_sand"
+ }
+ },
+ "result": {
+ "item": "betternether:bricks_fire_bowl_soul"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_acacia_from_acacia_slab.json b/src/generated/resources/data/minecraft/recipes/chair_acacia_from_acacia_slab.json
new file mode 100644
index 0000000..eef975b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_acacia_from_acacia_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:acacia_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_acacia"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_anchor_tree_from_anchor_tree_slab.json b/src/generated/resources/data/minecraft/recipes/chair_anchor_tree_from_anchor_tree_slab.json
new file mode 100644
index 0000000..bd3fab6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_anchor_tree_from_anchor_tree_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_birch_from_birch_slab.json b/src/generated/resources/data/minecraft/recipes/chair_birch_from_birch_slab.json
new file mode 100644
index 0000000..7a35c87
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_birch_from_birch_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:birch_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_birch"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_cincinnasite_from_cincinnasite_slab.json b/src/generated/resources/data/minecraft/recipes/chair_cincinnasite_from_cincinnasite_slab.json
new file mode 100644
index 0000000..8f76448
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_cincinnasite_from_cincinnasite_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_cincinnasite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_crimson_from_crimson_slab.json b/src/generated/resources/data/minecraft/recipes/chair_crimson_from_crimson_slab.json
new file mode 100644
index 0000000..7089ade
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_crimson_from_crimson_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_crimson"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_dark_oak_from_dark_oak_slab.json b/src/generated/resources/data/minecraft/recipes/chair_dark_oak_from_dark_oak_slab.json
new file mode 100644
index 0000000..4dc5482
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_dark_oak_from_dark_oak_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:dark_oak_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_dark_oak"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_jungle_from_jungle_slab.json b/src/generated/resources/data/minecraft/recipes/chair_jungle_from_jungle_slab.json
new file mode 100644
index 0000000..d865d2e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_jungle_from_jungle_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:jungle_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_jungle"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_mushroom_fir_from_mushroom_fir_slab.json b/src/generated/resources/data/minecraft/recipes/chair_mushroom_fir_from_mushroom_fir_slab.json
new file mode 100644
index 0000000..dc24d48
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_mushroom_fir_from_mushroom_fir_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_mushroom_from_mushroom_slab.json b/src/generated/resources/data/minecraft/recipes/chair_mushroom_from_mushroom_slab.json
new file mode 100644
index 0000000..8faaac7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_mushroom_from_mushroom_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_nether_sakura_from_nether_sakura_slab.json b/src/generated/resources/data/minecraft/recipes/chair_nether_sakura_from_nether_sakura_slab.json
new file mode 100644
index 0000000..43ae25a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_nether_sakura_from_nether_sakura_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_oak_from_oak_slab.json b/src/generated/resources/data/minecraft/recipes/chair_oak_from_oak_slab.json
new file mode 100644
index 0000000..ce22478
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_oak_from_oak_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:oak_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_oak"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_reeds_from_reeds_slab.json b/src/generated/resources/data/minecraft/recipes/chair_reeds_from_reeds_slab.json
new file mode 100644
index 0000000..74370c5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_reeds_from_reeds_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_reeds"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_rubeus_from_rubeus_slab.json b/src/generated/resources/data/minecraft/recipes/chair_rubeus_from_rubeus_slab.json
new file mode 100644
index 0000000..f820e04
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_rubeus_from_rubeus_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_spruce_from_spruce_slab.json b/src/generated/resources/data/minecraft/recipes/chair_spruce_from_spruce_slab.json
new file mode 100644
index 0000000..22bac28
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_spruce_from_spruce_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:spruce_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_spruce"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_stalagnate_from_stalagnate_planks_slab.json b/src/generated/resources/data/minecraft/recipes/chair_stalagnate_from_stalagnate_planks_slab.json
new file mode 100644
index 0000000..50963fe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_stalagnate_from_stalagnate_planks_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_warped_from_warped_slab.json b/src/generated/resources/data/minecraft/recipes/chair_warped_from_warped_slab.json
new file mode 100644
index 0000000..752648b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_warped_from_warped_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_warped"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_wart_from_wart_slab.json b/src/generated/resources/data/minecraft/recipes/chair_wart_from_wart_slab.json
new file mode 100644
index 0000000..7026d70
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_wart_from_wart_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chair_willow_from_willow_slab.json b/src/generated/resources/data/minecraft/recipes/chair_willow_from_willow_slab.json
new file mode 100644
index 0000000..272dde8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chair_willow_from_willow_slab.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I ",
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:chair_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/chest_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..13e13bd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_crimson_from_crimson_planks.json b/src/generated/resources/data/minecraft/recipes/chest_crimson_from_crimson_planks.json
new file mode 100644
index 0000000..f9cb1aa
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_crimson_from_crimson_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_crimson"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/chest_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..15b9a4c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/chest_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..f0492db
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_mushroom_from_mushroom_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/chest_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..fd705ef
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/chest_reed_from_reeds_block.json
new file mode 100644
index 0000000..ac6a782
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_reed_from_reeds_block.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_reed"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/chest_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..81cd2c4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_rubeus_from_rubeus_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/chest_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..b7c93e2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_warped_from_warped_planks.json b/src/generated/resources/data/minecraft/recipes/chest_warped_from_warped_planks.json
new file mode 100644
index 0000000..2d94c8e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_warped_from_warped_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_warped"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/chest_wart_from_wart_planks.json
new file mode 100644
index 0000000..a18c8df
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_wart_from_wart_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/chest_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/chest_willow_from_willow_planks.json
new file mode 100644
index 0000000..a05646e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/chest_willow_from_willow_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:chest_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/cincinnasite_fire_bowl_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/cincinnasite_fire_bowl_from_cincinnasite_forged.json
new file mode 100644
index 0000000..d72cda3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/cincinnasite_fire_bowl_from_cincinnasite_forged.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ " # ",
+ "L L"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ },
+ "I": [],
+ "L": {
+ "item": "minecraft:netherrack"
+ }
+ },
+ "result": {
+ "item": "betternether:cincinnasite_fire_bowl"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json
new file mode 100644
index 0000000..fde6fee
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/cincinnasite_fire_bowl_soul_from_cincinnasite_forged.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ " # ",
+ "L L"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ },
+ "I": [],
+ "L": {
+ "item": "minecraft:soul_sand"
+ }
+ },
+ "result": {
+ "item": "betternether:cincinnasite_fire_bowl_soul"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/cincinnasite_plate_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/cincinnasite_plate_from_cincinnasite_forged.json
new file mode 100644
index 0000000..9a236fb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/cincinnasite_plate_from_cincinnasite_forged.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ }
+ },
+ "result": {
+ "item": "betternether:cincinnasite_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/cincinnasite_slab_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/cincinnasite_slab_from_cincinnasite_forged.json
new file mode 100644
index 0000000..2d2b697
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/cincinnasite_slab_from_cincinnasite_forged.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ }
+ },
+ "result": {
+ "item": "betternether:cincinnasite_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/cincinnasite_stairs_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/cincinnasite_stairs_from_cincinnasite_forged.json
new file mode 100644
index 0000000..1772dd1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/cincinnasite_stairs_from_cincinnasite_forged.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ }
+ },
+ "result": {
+ "item": "betternether:cincinnasite_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/cincinnasite_wall_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/cincinnasite_wall_from_cincinnasite_forged.json
new file mode 100644
index 0000000..4bb1b0a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/cincinnasite_wall_from_cincinnasite_forged.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ }
+ },
+ "result": {
+ "item": "betternether:cincinnasite_wall",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..c11a2a2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_crimson_from_crimson_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_crimson_from_crimson_planks.json
new file mode 100644
index 0000000..0fd7560
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_crimson_from_crimson_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_crimson"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..69eeb5f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..baaa027
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_mushroom_from_mushroom_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..71ccf42
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/crafting_table_reed_from_reeds_block.json
new file mode 100644
index 0000000..8554315
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_reed_from_reeds_block.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_reed"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..e2c4688
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_rubeus_from_rubeus_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..445b116
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_warped_from_warped_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_warped_from_warped_planks.json
new file mode 100644
index 0000000..877fa6e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_warped_from_warped_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_warped"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_wart_from_wart_planks.json
new file mode 100644
index 0000000..c08569d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_wart_from_wart_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crafting_table_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/crafting_table_willow_from_willow_planks.json
new file mode 100644
index 0000000..2707d79
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crafting_table_willow_from_willow_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:crafting_table_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/crimson_ladder_from_crimson_planks.json b/src/generated/resources/data/minecraft/recipes/crimson_ladder_from_crimson_planks.json
new file mode 100644
index 0000000..716afc0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/crimson_ladder_from_crimson_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:crimson_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/glowstone_stalactite_from_glowstone.json b/src/generated/resources/data/minecraft/recipes/glowstone_stalactite_from_glowstone.json
new file mode 100644
index 0000000..a803fee
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/glowstone_stalactite_from_glowstone.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:glowstone"
+ }
+ },
+ "result": {
+ "item": "betternether:glowstone_stalactite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_button_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_button_from_mushroom_planks.json
new file mode 100644
index 0000000..f3a3a30
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_button_from_mushroom_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:mushroom_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_door_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_door_from_mushroom_planks.json
new file mode 100644
index 0000000..7943b90
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_door_from_mushroom_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fence_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fence_from_mushroom_planks.json
new file mode 100644
index 0000000..c06020f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fence_from_mushroom_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_button_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_button_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..1119d59
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_button_from_mushroom_fir_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_fir_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_door_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_door_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..8c43417
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_door_from_mushroom_fir_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_fence_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_fence_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..86ed580
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_fence_from_mushroom_fir_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_gate_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_gate_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..58cd73f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_gate_from_mushroom_fir_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_ladder_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_ladder_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..4f96884
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_ladder_from_mushroom_fir_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_log_from_mushroom_fir_stem.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_log_from_mushroom_fir_stem.json
new file mode 100644
index 0000000..9768be0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_log_from_mushroom_fir_stem.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_stem"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_log"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_log.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_log.json
new file mode 100644
index 0000000..1841c2a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:mushroom_fir_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_fir_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_stem.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_stem.json
new file mode 100644
index 0000000..97ef411
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_stem.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:mushroom_fir_stem"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_wood.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_wood.json
new file mode 100644
index 0000000..a7ecffd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_mushroom_fir_wood.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:mushroom_fir_wood"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_fir_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_striped_log_mushroom_fir.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_striped_log_mushroom_fir.json
new file mode 100644
index 0000000..3f2dfcc
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_striped_log_mushroom_fir.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_mushroom_fir"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_fir_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_striped_wood_mushroom_fir.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_striped_wood_mushroom_fir.json
new file mode 100644
index 0000000..af0cbae
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_planks_from_striped_wood_mushroom_fir.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_wood_mushroom_fir"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_fir_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_plate_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_plate_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..4fba920
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_plate_from_mushroom_fir_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_slab_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_slab_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..165c54a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_slab_from_mushroom_fir_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_stairs_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_stairs_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..e01e185
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_stairs_from_mushroom_fir_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_trapdoor_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_trapdoor_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..3be29aa
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_trapdoor_from_mushroom_fir_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_fir_wood_from_mushroom_fir_log.json b/src/generated/resources/data/minecraft/recipes/mushroom_fir_wood_from_mushroom_fir_log.json
new file mode 100644
index 0000000..734f8fd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_fir_wood_from_mushroom_fir_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_log"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_fir_wood",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_gate_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_gate_from_mushroom_planks.json
new file mode 100644
index 0000000..32cd5e8
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_gate_from_mushroom_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_ladder_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_ladder_from_mushroom_planks.json
new file mode 100644
index 0000000..9d86d85
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_ladder_from_mushroom_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_planks_from_mushroom_stem.json b/src/generated/resources/data/minecraft/recipes/mushroom_planks_from_mushroom_stem.json
new file mode 100644
index 0000000..9615192
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_planks_from_mushroom_stem.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:mushroom_stem"
+ }
+ ],
+ "result": {
+ "item": "betternether:mushroom_planks",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_plate_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_plate_from_mushroom_planks.json
new file mode 100644
index 0000000..a8c0f4b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_plate_from_mushroom_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_slab_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_slab_from_mushroom_planks.json
new file mode 100644
index 0000000..52408ab
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_slab_from_mushroom_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_stairs_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_stairs_from_mushroom_planks.json
new file mode 100644
index 0000000..c749db4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_stairs_from_mushroom_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/mushroom_trapdoor_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/mushroom_trapdoor_from_mushroom_planks.json
new file mode 100644
index 0000000..1a06a12
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/mushroom_trapdoor_from_mushroom_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:mushroom_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_brick_tile_slab_from_nether_brick_tile_small.json b/src/generated/resources/data/minecraft/recipes/nether_brick_tile_slab_from_nether_brick_tile_small.json
new file mode 100644
index 0000000..ac7406c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_brick_tile_slab_from_nether_brick_tile_small.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_brick_tile_small"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_brick_tile_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_brick_tile_stairs_from_nether_brick_tile_small.json b/src/generated/resources/data/minecraft/recipes/nether_brick_tile_stairs_from_nether_brick_tile_small.json
new file mode 100644
index 0000000..c363f01
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_brick_tile_stairs_from_nether_brick_tile_small.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_brick_tile_small"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_brick_tile_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_brick_wall_from_nether_brick_tile_large.json b/src/generated/resources/data/minecraft/recipes/nether_brick_wall_from_nether_brick_tile_large.json
new file mode 100644
index 0000000..cfbc802
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_brick_wall_from_nether_brick_tile_large.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_brick_tile_large"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_brick_wall",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_ruby_slab_from_nether_ruby_block.json b/src/generated/resources/data/minecraft/recipes/nether_ruby_slab_from_nether_ruby_block.json
new file mode 100644
index 0000000..ad3e14d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_ruby_slab_from_nether_ruby_block.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_ruby_block"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_ruby_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_ruby_stairs_from_nether_ruby_block.json b/src/generated/resources/data/minecraft/recipes/nether_ruby_stairs_from_nether_ruby_block.json
new file mode 100644
index 0000000..de0bd91
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_ruby_stairs_from_nether_ruby_block.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_ruby_block"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_ruby_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_bark_from_nether_sakura_log.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_bark_from_nether_sakura_log.json
new file mode 100644
index 0000000..a5fc4c7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_bark_from_nether_sakura_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_log"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_bark",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_button_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_button_from_nether_sakura_planks.json
new file mode 100644
index 0000000..eb80036
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_button_from_nether_sakura_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:nether_sakura_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:nether_sakura_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_door_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_door_from_nether_sakura_planks.json
new file mode 100644
index 0000000..a43f7cd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_door_from_nether_sakura_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_fence_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_fence_from_nether_sakura_planks.json
new file mode 100644
index 0000000..fd91e1e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_fence_from_nether_sakura_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_gate_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_gate_from_nether_sakura_planks.json
new file mode 100644
index 0000000..3f4fa54
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_gate_from_nether_sakura_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_ladder_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_ladder_from_nether_sakura_planks.json
new file mode 100644
index 0000000..4a29dcc
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_ladder_from_nether_sakura_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_bark.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_bark.json
new file mode 100644
index 0000000..8096ba5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_bark.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:nether_sakura_bark"
+ }
+ ],
+ "result": {
+ "item": "betternether:nether_sakura_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_log.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_log.json
new file mode 100644
index 0000000..e522c6f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_nether_sakura_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:nether_sakura_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:nether_sakura_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_striped_bark_nether_sakura.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_striped_bark_nether_sakura.json
new file mode 100644
index 0000000..0131a4d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_striped_bark_nether_sakura.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_bark_nether_sakura"
+ }
+ ],
+ "result": {
+ "item": "betternether:nether_sakura_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_striped_log_nether_sakura.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_striped_log_nether_sakura.json
new file mode 100644
index 0000000..75ec5e0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_planks_from_striped_log_nether_sakura.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_nether_sakura"
+ }
+ ],
+ "result": {
+ "item": "betternether:nether_sakura_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_plate_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_plate_from_nether_sakura_planks.json
new file mode 100644
index 0000000..f77af03
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_plate_from_nether_sakura_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_slab_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_slab_from_nether_sakura_planks.json
new file mode 100644
index 0000000..4635c71
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_slab_from_nether_sakura_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_stairs_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_stairs_from_nether_sakura_planks.json
new file mode 100644
index 0000000..2d61bbe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_stairs_from_nether_sakura_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/nether_sakura_trapdoor_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/nether_sakura_trapdoor_from_nether_sakura_planks.json
new file mode 100644
index 0000000..54a2090
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/nether_sakura_trapdoor_from_nether_sakura_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:nether_sakura_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/netherite_fire_bowl_from_netherite_block.json b/src/generated/resources/data/minecraft/recipes/netherite_fire_bowl_from_netherite_block.json
new file mode 100644
index 0000000..652bf23
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/netherite_fire_bowl_from_netherite_block.json
@@ -0,0 +1,23 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ " # ",
+ "L L"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:netherite_block"
+ },
+ "I": {
+ "item": "minecraft:netherite_ingot"
+ },
+ "L": {
+ "item": "minecraft:netherrack"
+ }
+ },
+ "result": {
+ "item": "betternether:netherite_fire_bowl"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/netherite_fire_bowl_soul_from_netherite_block.json b/src/generated/resources/data/minecraft/recipes/netherite_fire_bowl_soul_from_netherite_block.json
new file mode 100644
index 0000000..dbd0285
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/netherite_fire_bowl_soul_from_netherite_block.json
@@ -0,0 +1,23 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ " # ",
+ "L L"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:netherite_block"
+ },
+ "I": {
+ "item": "minecraft:netherite_ingot"
+ },
+ "L": {
+ "item": "minecraft:soul_sand"
+ }
+ },
+ "result": {
+ "item": "betternether:netherite_fire_bowl_soul"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/netherrack_furnace_from_netherrack.json b/src/generated/resources/data/minecraft/recipes/netherrack_furnace_from_netherrack.json
new file mode 100644
index 0000000..6a24bb3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/netherrack_furnace_from_netherrack.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "# #",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:netherrack"
+ }
+ },
+ "result": {
+ "item": "betternether:netherrack_furnace"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/netherrack_stalactite_from_netherrack.json b/src/generated/resources/data/minecraft/recipes/netherrack_stalactite_from_netherrack.json
new file mode 100644
index 0000000..53c9ec6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/netherrack_stalactite_from_netherrack.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:netherrack"
+ }
+ },
+ "result": {
+ "item": "betternether:netherrack_stalactite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/obsidian_bricks_slab_from_obsidian_bricks.json b/src/generated/resources/data/minecraft/recipes/obsidian_bricks_slab_from_obsidian_bricks.json
new file mode 100644
index 0000000..069215c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/obsidian_bricks_slab_from_obsidian_bricks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:obsidian_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:obsidian_bricks_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/obsidian_bricks_stairs_from_obsidian_bricks.json b/src/generated/resources/data/minecraft/recipes/obsidian_bricks_stairs_from_obsidian_bricks.json
new file mode 100644
index 0000000..7a683f1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/obsidian_bricks_stairs_from_obsidian_bricks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:obsidian_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:obsidian_bricks_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/obsidian_tile_slab_from_obsidian_tile_small.json b/src/generated/resources/data/minecraft/recipes/obsidian_tile_slab_from_obsidian_tile_small.json
new file mode 100644
index 0000000..62d1cae
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/obsidian_tile_slab_from_obsidian_tile_small.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:obsidian_tile_small"
+ }
+ },
+ "result": {
+ "item": "betternether:obsidian_tile_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/obsidian_tile_stairs_from_obsidian_tile_small.json b/src/generated/resources/data/minecraft/recipes/obsidian_tile_stairs_from_obsidian_tile_small.json
new file mode 100644
index 0000000..9600802
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/obsidian_tile_stairs_from_obsidian_tile_small.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:obsidian_tile_small"
+ }
+ },
+ "result": {
+ "item": "betternether:obsidian_tile_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_button_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_button_from_reeds_block.json
new file mode 100644
index 0000000..509fbbf
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_button_from_reeds_block.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:reeds_block"
+ }
+ ],
+ "result": {
+ "item": "betternether:reeds_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_door_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_door_from_reeds_block.json
new file mode 100644
index 0000000..6537120
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_door_from_reeds_block.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_fence_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_fence_from_reeds_block.json
new file mode 100644
index 0000000..9245cef
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_fence_from_reeds_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_gate_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_gate_from_reeds_block.json
new file mode 100644
index 0000000..894cff0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_gate_from_reeds_block.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_ladder_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_ladder_from_reeds_block.json
new file mode 100644
index 0000000..2b7d340
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_ladder_from_reeds_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_plate_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_plate_from_reeds_block.json
new file mode 100644
index 0000000..82fdc62
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_plate_from_reeds_block.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_slab_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_slab_from_reeds_block.json
new file mode 100644
index 0000000..2094bef
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_slab_from_reeds_block.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_stairs_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_stairs_from_reeds_block.json
new file mode 100644
index 0000000..53f2d28
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_stairs_from_reeds_block.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/reeds_trapdoor_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/reeds_trapdoor_from_reeds_block.json
new file mode 100644
index 0000000..e54c8fe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/reeds_trapdoor_from_reeds_block.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:reeds_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_from_cincinnasite_forged.json b/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_from_cincinnasite_forged.json
new file mode 100644
index 0000000..8d76636
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_from_cincinnasite_forged.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# #",
+ "###",
+ " # "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_forged"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_cincinnasite",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json b/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json
new file mode 100644
index 0000000..c884eb9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_slab_from_roof_tile_cincinnasite.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_cincinnasite"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_cincinnasite_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json b/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json
new file mode 100644
index 0000000..8033334
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_cincinnasite_stairs_from_roof_tile_cincinnasite.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_cincinnasite"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_cincinnasite_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_from_nether_bricks.json b/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_from_nether_bricks.json
new file mode 100644
index 0000000..e216bb5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_from_nether_bricks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# #",
+ "###",
+ " # "
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:nether_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_nether_bricks",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json b/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json
new file mode 100644
index 0000000..918fad1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_slab_from_roof_tile_nether_bricks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_nether_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_nether_bricks_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json b/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json
new file mode 100644
index 0000000..acc08c0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_nether_bricks_stairs_from_roof_tile_nether_bricks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_nether_bricks"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_nether_bricks_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_from_reeds_block.json
new file mode 100644
index 0000000..51ebdaa
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_from_reeds_block.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# #",
+ "###",
+ " # "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_reeds",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_slab_from_roof_tile_reeds.json b/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_slab_from_roof_tile_reeds.json
new file mode 100644
index 0000000..d26f1cd
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_slab_from_roof_tile_reeds.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_reeds"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_reeds_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_stairs_from_roof_tile_reeds.json b/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_stairs_from_roof_tile_reeds.json
new file mode 100644
index 0000000..ac0a8aa
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_reeds_stairs_from_roof_tile_reeds.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_reeds"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_reeds_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..5ff2aba
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# #",
+ "###",
+ " # "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_stalagnate",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json b/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json
new file mode 100644
index 0000000..fea7153
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_slab_from_roof_tile_stalagnate.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_stalagnate"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_stalagnate_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json b/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json
new file mode 100644
index 0000000..bd772b5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_stalagnate_stairs_from_roof_tile_stalagnate.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_stalagnate"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_stalagnate_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/roof_tile_wart_from_wart_planks.json
new file mode 100644
index 0000000..78a197a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_wart_from_wart_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# #",
+ "###",
+ " # "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_wart",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_wart_slab_from_roof_tile_wart.json b/src/generated/resources/data/minecraft/recipes/roof_tile_wart_slab_from_roof_tile_wart.json
new file mode 100644
index 0000000..90ea8cb
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_wart_slab_from_roof_tile_wart.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_wart"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_wart_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_wart_stairs_from_roof_tile_wart.json b/src/generated/resources/data/minecraft/recipes/roof_tile_wart_stairs_from_roof_tile_wart.json
new file mode 100644
index 0000000..03c36ca
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_wart_stairs_from_roof_tile_wart.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_wart"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_wart_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/roof_tile_willow_from_willow_planks.json
new file mode 100644
index 0000000..75caee5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_willow_from_willow_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# #",
+ "###",
+ " # "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_willow",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_willow_slab_from_roof_tile_willow.json b/src/generated/resources/data/minecraft/recipes/roof_tile_willow_slab_from_roof_tile_willow.json
new file mode 100644
index 0000000..b7bf954
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_willow_slab_from_roof_tile_willow.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_willow"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_willow_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/roof_tile_willow_stairs_from_roof_tile_willow.json b/src/generated/resources/data/minecraft/recipes/roof_tile_willow_stairs_from_roof_tile_willow.json
new file mode 100644
index 0000000..8a59eef
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/roof_tile_willow_stairs_from_roof_tile_willow.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:roof_tile_willow"
+ }
+ },
+ "result": {
+ "item": "betternether:roof_tile_willow_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_bark_from_rubeus_log.json b/src/generated/resources/data/minecraft/recipes/rubeus_bark_from_rubeus_log.json
new file mode 100644
index 0000000..325d54a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_bark_from_rubeus_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_log"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_bark",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_button_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_button_from_rubeus_planks.json
new file mode 100644
index 0000000..437aaa7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_button_from_rubeus_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:rubeus_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:rubeus_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_door_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_door_from_rubeus_planks.json
new file mode 100644
index 0000000..51e5904
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_door_from_rubeus_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_fence_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_fence_from_rubeus_planks.json
new file mode 100644
index 0000000..04e4a4d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_fence_from_rubeus_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_gate_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_gate_from_rubeus_planks.json
new file mode 100644
index 0000000..20a5458
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_gate_from_rubeus_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_ladder_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_ladder_from_rubeus_planks.json
new file mode 100644
index 0000000..f194d38
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_ladder_from_rubeus_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_rubeus_bark.json b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_rubeus_bark.json
new file mode 100644
index 0000000..6725932
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_rubeus_bark.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:rubeus_bark"
+ }
+ ],
+ "result": {
+ "item": "betternether:rubeus_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_rubeus_log.json b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_rubeus_log.json
new file mode 100644
index 0000000..05cc09c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_rubeus_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:rubeus_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:rubeus_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_striped_bark_rubeus.json b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_striped_bark_rubeus.json
new file mode 100644
index 0000000..a4ee4d7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_striped_bark_rubeus.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_bark_rubeus"
+ }
+ ],
+ "result": {
+ "item": "betternether:rubeus_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_striped_log_rubeus.json b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_striped_log_rubeus.json
new file mode 100644
index 0000000..7e6c9ab
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_planks_from_striped_log_rubeus.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_rubeus"
+ }
+ ],
+ "result": {
+ "item": "betternether:rubeus_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_plate_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_plate_from_rubeus_planks.json
new file mode 100644
index 0000000..cac95ae
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_plate_from_rubeus_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_slab_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_slab_from_rubeus_planks.json
new file mode 100644
index 0000000..fdd78e2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_slab_from_rubeus_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_stairs_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_stairs_from_rubeus_planks.json
new file mode 100644
index 0000000..75b934a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_stairs_from_rubeus_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/rubeus_trapdoor_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/rubeus_trapdoor_from_rubeus_planks.json
new file mode 100644
index 0000000..dd4652f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/rubeus_trapdoor_from_rubeus_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:rubeus_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_anchor_tree_from_anchor_tree_planks.json b/src/generated/resources/data/minecraft/recipes/sign_anchor_tree_from_anchor_tree_planks.json
new file mode 100644
index 0000000..881576c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_anchor_tree_from_anchor_tree_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_mushroom_fir_from_mushroom_fir_planks.json b/src/generated/resources/data/minecraft/recipes/sign_mushroom_fir_from_mushroom_fir_planks.json
new file mode 100644
index 0000000..ae08be9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_mushroom_fir_from_mushroom_fir_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_mushroom_from_mushroom_planks.json b/src/generated/resources/data/minecraft/recipes/sign_mushroom_from_mushroom_planks.json
new file mode 100644
index 0000000..f979efa
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_mushroom_from_mushroom_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_nether_sakura_from_nether_sakura_planks.json b/src/generated/resources/data/minecraft/recipes/sign_nether_sakura_from_nether_sakura_planks.json
new file mode 100644
index 0000000..9cb8ed0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_nether_sakura_from_nether_sakura_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_reed_from_reeds_block.json b/src/generated/resources/data/minecraft/recipes/sign_reed_from_reeds_block.json
new file mode 100644
index 0000000..3f74a6b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_reed_from_reeds_block.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_block"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_reed"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_rubeus_from_rubeus_planks.json b/src/generated/resources/data/minecraft/recipes/sign_rubeus_from_rubeus_planks.json
new file mode 100644
index 0000000..3e72b83
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_rubeus_from_rubeus_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_stalagnate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/sign_stalagnate_from_stalagnate_planks.json
new file mode 100644
index 0000000..4b88953
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_stalagnate_from_stalagnate_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_wart_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/sign_wart_from_wart_planks.json
new file mode 100644
index 0000000..4e1c17d
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_wart_from_wart_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/sign_willow_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/sign_willow_from_willow_planks.json
new file mode 100644
index 0000000..fca46a5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/sign_willow_from_willow_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###",
+ " I "
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:sign_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_chiseled_from_soul_sandstone_smooth.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_chiseled_from_soul_sandstone_smooth.json
new file mode 100644
index 0000000..e64867f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_chiseled_from_soul_sandstone_smooth.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_smooth"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_chiseled",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_from_soul_sandstone.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_from_soul_sandstone.json
new file mode 100644
index 0000000..ade6734
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_from_soul_sandstone.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_cut",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_slab_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_slab_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..e8eeeb5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_slab_from_soul_sandstone_cut.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_cut_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..55b4dc9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_cut_stairs_from_soul_sandstone_cut.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_cut_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_slab_from_soul_sandstone.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_slab_from_soul_sandstone.json
new file mode 100644
index 0000000..98c96ae
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_slab_from_soul_sandstone.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..d1a0f21
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_from_soul_sandstone_cut.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_smooth",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json
new file mode 100644
index 0000000..5591a3b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_slab_from_soul_sandstone_smooth.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_smooth"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_smooth_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json
new file mode 100644
index 0000000..2198171
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_smooth_stairs_from_soul_sandstone_smooth.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_smooth"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_smooth_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_stairs_from_soul_sandstone.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_stairs_from_soul_sandstone.json
new file mode 100644
index 0000000..2ee5c07
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_stairs_from_soul_sandstone.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/soul_sandstone_wall_from_soul_sandstone_cut.json b/src/generated/resources/data/minecraft/recipes/soul_sandstone_wall_from_soul_sandstone_cut.json
new file mode 100644
index 0000000..a1c4398
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/soul_sandstone_wall_from_soul_sandstone_cut.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:soul_sandstone_cut"
+ }
+ },
+ "result": {
+ "item": "betternether:soul_sandstone_wall",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_bark_from_stalagnate_log.json b/src/generated/resources/data/minecraft/recipes/stalagnate_bark_from_stalagnate_log.json
new file mode 100644
index 0000000..7fb4291
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_bark_from_stalagnate_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_log"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_bark",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_ladder_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_ladder_from_stalagnate_planks.json
new file mode 100644
index 0000000..9e5fd10
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_ladder_from_stalagnate_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_log_from_stalagnate_stem.json b/src/generated/resources/data/minecraft/recipes/stalagnate_log_from_stalagnate_stem.json
new file mode 100644
index 0000000..33879ea
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_log_from_stalagnate_stem.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_stem"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_log"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_button_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_button_from_stalagnate_planks.json
new file mode 100644
index 0000000..b4d6c37
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_button_from_stalagnate_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:stalagnate_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:stalagnate_planks_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_door_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_door_from_stalagnate_planks.json
new file mode 100644
index 0000000..7caac0f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_door_from_stalagnate_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_fence_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_fence_from_stalagnate_planks.json
new file mode 100644
index 0000000..f0bba64
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_fence_from_stalagnate_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_bark.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_bark.json
new file mode 100644
index 0000000..5420f76
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_bark.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:stalagnate_bark"
+ }
+ ],
+ "result": {
+ "item": "betternether:stalagnate_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_log.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_log.json
new file mode 100644
index 0000000..81b7d4e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:stalagnate_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:stalagnate_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_stem.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_stem.json
new file mode 100644
index 0000000..bd28871
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_stalagnate_stem.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:stalagnate_stem"
+ }
+ ],
+ "result": {
+ "item": "betternether:stalagnate_planks"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_striped_bark_stalagnate.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_striped_bark_stalagnate.json
new file mode 100644
index 0000000..73c41a6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_striped_bark_stalagnate.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_bark_stalagnate"
+ }
+ ],
+ "result": {
+ "item": "betternether:stalagnate_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_striped_log_stalagnate.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_striped_log_stalagnate.json
new file mode 100644
index 0000000..9f44a64
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_from_striped_log_stalagnate.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_stalagnate"
+ }
+ ],
+ "result": {
+ "item": "betternether:stalagnate_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_gate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_gate_from_stalagnate_planks.json
new file mode 100644
index 0000000..56f4625
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_gate_from_stalagnate_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_plate_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_plate_from_stalagnate_planks.json
new file mode 100644
index 0000000..d43abab
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_plate_from_stalagnate_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_slab_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_slab_from_stalagnate_planks.json
new file mode 100644
index 0000000..f829606
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_slab_from_stalagnate_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_stairs_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_stairs_from_stalagnate_planks.json
new file mode 100644
index 0000000..9f1f9df
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_stairs_from_stalagnate_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/stalagnate_planks_trapdoor_from_stalagnate_planks.json b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_trapdoor_from_stalagnate_planks.json
new file mode 100644
index 0000000..d5fc1d0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/stalagnate_planks_trapdoor_from_stalagnate_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:stalagnate_planks_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_acacia_from_acacia_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_acacia_from_acacia_slab.json
new file mode 100644
index 0000000..28efc1f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_acacia_from_acacia_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:acacia_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_acacia"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_anchor_tree_from_anchor_tree_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_anchor_tree_from_anchor_tree_slab.json
new file mode 100644
index 0000000..c78f045
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_anchor_tree_from_anchor_tree_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:anchor_tree_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_anchor_tree"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_birch_from_birch_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_birch_from_birch_slab.json
new file mode 100644
index 0000000..a52d654
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_birch_from_birch_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:birch_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_birch"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_cincinnasite_from_cincinnasite_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_cincinnasite_from_cincinnasite_slab.json
new file mode 100644
index 0000000..c8aa4a3
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_cincinnasite_from_cincinnasite_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:cincinnasite_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_cincinnasite"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_crimson_from_crimson_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_crimson_from_crimson_slab.json
new file mode 100644
index 0000000..f99bda7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_crimson_from_crimson_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:crimson_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_crimson"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_dark_oak_from_dark_oak_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_dark_oak_from_dark_oak_slab.json
new file mode 100644
index 0000000..b0fc1be
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_dark_oak_from_dark_oak_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:dark_oak_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_dark_oak"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_jungle_from_jungle_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_jungle_from_jungle_slab.json
new file mode 100644
index 0000000..cf10bc1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_jungle_from_jungle_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:jungle_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_jungle"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_mushroom_fir_from_mushroom_fir_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_mushroom_fir_from_mushroom_fir_slab.json
new file mode 100644
index 0000000..7fb0e04
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_mushroom_fir_from_mushroom_fir_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_fir_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_mushroom_fir"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_mushroom_from_mushroom_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_mushroom_from_mushroom_slab.json
new file mode 100644
index 0000000..3c58d2a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_mushroom_from_mushroom_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:mushroom_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_mushroom"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_nether_sakura_from_nether_sakura_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_nether_sakura_from_nether_sakura_slab.json
new file mode 100644
index 0000000..fdb1425
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_nether_sakura_from_nether_sakura_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:nether_sakura_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_nether_sakura"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_oak_from_oak_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_oak_from_oak_slab.json
new file mode 100644
index 0000000..e2843af
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_oak_from_oak_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:oak_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_oak"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_reeds_from_reeds_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_reeds_from_reeds_slab.json
new file mode 100644
index 0000000..2487fe2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_reeds_from_reeds_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:reeds_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_reeds"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_rubeus_from_rubeus_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_rubeus_from_rubeus_slab.json
new file mode 100644
index 0000000..fd8dcef
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_rubeus_from_rubeus_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:rubeus_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_rubeus"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_spruce_from_spruce_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_spruce_from_spruce_slab.json
new file mode 100644
index 0000000..b75ba4c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_spruce_from_spruce_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:spruce_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_spruce"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_stalagnate_from_stalagnate_planks_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_stalagnate_from_stalagnate_planks_slab.json
new file mode 100644
index 0000000..a9ef859
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_stalagnate_from_stalagnate_planks_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:stalagnate_planks_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_stalagnate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_warped_from_warped_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_warped_from_warped_slab.json
new file mode 100644
index 0000000..6b1a5e6
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_warped_from_warped_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_warped"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_wart_from_wart_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_wart_from_wart_slab.json
new file mode 100644
index 0000000..c4732a9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_wart_from_wart_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_wart"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/taburet_willow_from_willow_slab.json b/src/generated/resources/data/minecraft/recipes/taburet_willow_from_willow_slab.json
new file mode 100644
index 0000000..5465229
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/taburet_willow_from_willow_slab.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "II"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_slab"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:taburet_willow"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/warped_ladder_from_warped_planks.json b/src/generated/resources/data/minecraft/recipes/warped_ladder_from_warped_planks.json
new file mode 100644
index 0000000..3cded2c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/warped_ladder_from_warped_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "minecraft:warped_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:warped_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_bark_from_wart_log.json b/src/generated/resources/data/minecraft/recipes/wart_bark_from_wart_log.json
new file mode 100644
index 0000000..2ac353e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_bark_from_wart_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_log"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_bark",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_button_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_button_from_wart_planks.json
new file mode 100644
index 0000000..897577b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_button_from_wart_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:wart_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:wart_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_door_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_door_from_wart_planks.json
new file mode 100644
index 0000000..b70ef67
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_door_from_wart_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_fence_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_fence_from_wart_planks.json
new file mode 100644
index 0000000..142b1ed
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_fence_from_wart_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_gate_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_gate_from_wart_planks.json
new file mode 100644
index 0000000..7192da1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_gate_from_wart_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_ladder_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_ladder_from_wart_planks.json
new file mode 100644
index 0000000..071b0c5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_ladder_from_wart_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_planks_from_striped_bark_wart.json b/src/generated/resources/data/minecraft/recipes/wart_planks_from_striped_bark_wart.json
new file mode 100644
index 0000000..a8de183
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_planks_from_striped_bark_wart.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_bark_wart"
+ }
+ ],
+ "result": {
+ "item": "betternether:wart_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_planks_from_striped_log_wart.json b/src/generated/resources/data/minecraft/recipes/wart_planks_from_striped_log_wart.json
new file mode 100644
index 0000000..fdc947c
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_planks_from_striped_log_wart.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_wart"
+ }
+ ],
+ "result": {
+ "item": "betternether:wart_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_planks_from_wart_bark.json b/src/generated/resources/data/minecraft/recipes/wart_planks_from_wart_bark.json
new file mode 100644
index 0000000..9fa74da
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_planks_from_wart_bark.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:wart_bark"
+ }
+ ],
+ "result": {
+ "item": "betternether:wart_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_planks_from_wart_log.json b/src/generated/resources/data/minecraft/recipes/wart_planks_from_wart_log.json
new file mode 100644
index 0000000..7f38bc5
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_planks_from_wart_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:wart_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:wart_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_plate_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_plate_from_wart_planks.json
new file mode 100644
index 0000000..46a058e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_plate_from_wart_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_slab_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_slab_from_wart_planks.json
new file mode 100644
index 0000000..b06a9c2
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_slab_from_wart_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_stairs_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_stairs_from_wart_planks.json
new file mode 100644
index 0000000..9cc6d6e
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_stairs_from_wart_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/wart_trapdoor_from_wart_planks.json b/src/generated/resources/data/minecraft/recipes/wart_trapdoor_from_wart_planks.json
new file mode 100644
index 0000000..9d6b648
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/wart_trapdoor_from_wart_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:wart_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:wart_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_bark_from_willow_log.json b/src/generated/resources/data/minecraft/recipes/willow_bark_from_willow_log.json
new file mode 100644
index 0000000..8e6a866
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_bark_from_willow_log.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_log"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_bark",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_button_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_button_from_willow_planks.json
new file mode 100644
index 0000000..40767b0
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_button_from_willow_planks.json
@@ -0,0 +1,12 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:willow_planks"
+ }
+ ],
+ "result": {
+ "item": "betternether:willow_button"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_door_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_door_from_willow_planks.json
new file mode 100644
index 0000000..a6f47d1
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_door_from_willow_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##",
+ "##",
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_door",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_fence_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_fence_from_willow_planks.json
new file mode 100644
index 0000000..1592127
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_fence_from_willow_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "#I#",
+ "#I#"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_fence",
+ "count": 3
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_gate_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_gate_from_willow_planks.json
new file mode 100644
index 0000000..e5cd2d7
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_gate_from_willow_planks.json
@@ -0,0 +1,19 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I#I",
+ "I#I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_gate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_ladder_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_ladder_from_willow_planks.json
new file mode 100644
index 0000000..757892b
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_ladder_from_willow_planks.json
@@ -0,0 +1,20 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "I I",
+ "I#I",
+ "I I"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ },
+ "I": {
+ "item": "minecraft:stick"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_ladder"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_planks_from_striped_bark_willow.json b/src/generated/resources/data/minecraft/recipes/willow_planks_from_striped_bark_willow.json
new file mode 100644
index 0000000..149d361
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_planks_from_striped_bark_willow.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_bark_willow"
+ }
+ ],
+ "result": {
+ "item": "betternether:willow_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_planks_from_striped_log_willow.json b/src/generated/resources/data/minecraft/recipes/willow_planks_from_striped_log_willow.json
new file mode 100644
index 0000000..9d13337
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_planks_from_striped_log_willow.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:striped_log_willow"
+ }
+ ],
+ "result": {
+ "item": "betternether:willow_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_planks_from_willow_bark.json b/src/generated/resources/data/minecraft/recipes/willow_planks_from_willow_bark.json
new file mode 100644
index 0000000..8b716ea
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_planks_from_willow_bark.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:willow_bark"
+ }
+ ],
+ "result": {
+ "item": "betternether:willow_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_planks_from_willow_log.json b/src/generated/resources/data/minecraft/recipes/willow_planks_from_willow_log.json
new file mode 100644
index 0000000..3a584d4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_planks_from_willow_log.json
@@ -0,0 +1,13 @@
+{
+ "type": "minecraft:crafting_shapeless",
+ "group": "betternether",
+ "ingredients": [
+ {
+ "item": "betternether:willow_log"
+ }
+ ],
+ "result": {
+ "item": "betternether:willow_planks",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_plate_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_plate_from_willow_planks.json
new file mode 100644
index 0000000..ec27df4
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_plate_from_willow_planks.json
@@ -0,0 +1,15 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "##"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_plate"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_slab_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_slab_from_willow_planks.json
new file mode 100644
index 0000000..bb1fafe
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_slab_from_willow_planks.json
@@ -0,0 +1,16 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_slab",
+ "count": 6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_stairs_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_stairs_from_willow_planks.json
new file mode 100644
index 0000000..4fbe60a
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_stairs_from_willow_planks.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "# ",
+ "## ",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_stairs",
+ "count": 4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/recipes/willow_trapdoor_from_willow_planks.json b/src/generated/resources/data/minecraft/recipes/willow_trapdoor_from_willow_planks.json
new file mode 100644
index 0000000..a1b9e0f
--- /dev/null
+++ b/src/generated/resources/data/minecraft/recipes/willow_trapdoor_from_willow_planks.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "betternether",
+ "pattern": [
+ "###",
+ "###"
+ ],
+ "key": {
+ "#": {
+ "item": "betternether:willow_planks"
+ }
+ },
+ "result": {
+ "item": "betternether:willow_trapdoor",
+ "count": 2
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/BetterNether.java b/src/main/java/redd90/betternether/BetterNether.java
new file mode 100644
index 0000000..5103785
--- /dev/null
+++ b/src/main/java/redd90/betternether/BetterNether.java
@@ -0,0 +1,142 @@
+package redd90.betternether;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.client.renderer.RenderTypeLookup;
+import net.minecraft.entity.EntityType;
+import net.minecraft.item.Item;
+import net.minecraft.tileentity.TileEntityType;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.world.biome.Biome;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.eventbus.api.IEventBus;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
+import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+import net.minecraftforge.registries.ForgeRegistries;
+import redd90.betternether.biomes.NetherBiome;
+import redd90.betternether.blocks.BNRenderLayer;
+import redd90.betternether.client.IRenderTypeable;
+import redd90.betternether.config.Config;
+import redd90.betternether.config.Configs;
+import redd90.betternether.datagen.DataGenerators;
+import redd90.betternether.recipes.ItemRecipes;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.BrewingRegistry;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.registry.EntityRenderRegistry;
+import redd90.betternether.registry.FuelRegistry;
+import redd90.betternether.registry.ItemsRegistry;
+import redd90.betternether.registry.NetherBiomesRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.registry.TileEntitiesRegistry;
+import redd90.betternether.registry.TileEntityRenderRegistry;
+import redd90.betternether.world.BNWorldGenerator;
+import redd90.betternether.world.NetherBiomeProvider;
+import redd90.betternether.world.structures.piece.StructureTypes;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+@Mod(BetterNether.MOD_ID)
+public class BetterNether
+{
+ // Directly reference a log4j logger.
+ public static final Logger LOGGER = LogManager.getLogger();
+ public static final String MOD_ID = "betternether";
+ private static boolean thinArmor = true;
+ private static boolean lavafallParticles = true;
+ private static float fogStart = 0.05F;
+ private static float fogEnd = 0.5F;
+
+ public BetterNether() {
+ IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
+ IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
+
+ initOptions();
+
+ modEventBus.addListener(this::commonSetup);
+ modEventBus.addListener(this::clientSetup);
+
+ modEventBus.addListener(DataGenerators::gatherData);
+ forgeEventBus.addListener(FuelRegistry::onFuelBurnTimeEvent);
+ modEventBus.addListener(NetherBiomesRegistry::createRegistry);
+ modEventBus.addGenericListener(SoundEvent.class, SoundsRegistry::registerAll);
+ modEventBus.addGenericListener(EntityType.class, EntityRegistry::registerAll);
+ modEventBus.addGenericListener(Block.class, BlocksRegistry::registerAll);
+ modEventBus.addGenericListener(Item.class, ItemsRegistry::registerAll);
+ modEventBus.addGenericListener(TileEntityType.class, TileEntitiesRegistry::registerAll);
+ modEventBus.addGenericListener(NetherBiome.class, NetherBiomesRegistry::registerNetherBiomes);
+ modEventBus.addGenericListener(Biome.class, NetherBiomesRegistry::registerBiomes);
+
+ //StructureRegistry.DEFERRED_FEATURES.register(modEventBus);
+ //StructureRegistry.DEFERRED_STRUCTURES.register(modEventBus);
+ NetherBiomesRegistry.init();
+ EntityRegistry.registerNetherEntities();
+ StructureTypes.init();
+ BNWorldGenerator.onModInit();
+ BrewingRegistry.register();
+ Config.save();
+
+ NetherTags.init();
+
+ NetherBiomeProvider.register();
+ }
+
+ private void clientSetup(FMLClientSetupEvent e) {
+ registerRenderLayers();
+ EntityRenderRegistry.register();
+ TileEntityRenderRegistry.register();
+ }
+
+ private void commonSetup(FMLCommonSetupEvent e) {
+ ItemRecipes.register();
+ }
+
+ private void initOptions() {
+ thinArmor = Configs.MAIN.getBoolean("improvement", "smaller_armor_offset", true);
+ lavafallParticles = Configs.MAIN.getBoolean("improvement", "lavafall_particles", true);
+ float density = Configs.MAIN.getFloat("improvement", "fog_density[vanilla: 1.0]", 0.75F);
+ changeFogDensity(density);
+ }
+
+ private void registerRenderLayers() {
+ RenderType cutout = RenderType.getCutout();
+ RenderType translucent = RenderType.getTranslucent();
+ ForgeRegistries.BLOCKS.forEach(block -> {
+ if (block instanceof IRenderTypeable) {
+ BNRenderLayer layer = ((IRenderTypeable) block).getRenderLayer();
+ if (layer == BNRenderLayer.CUTOUT)
+ RenderTypeLookup.setRenderLayer(block, cutout);
+ else if (layer == BNRenderLayer.TRANSLUCENT)
+ RenderTypeLookup.setRenderLayer(block, translucent);
+ }
+ });
+ }
+
+ public static boolean hasThinArmor() {
+ return thinArmor;
+ }
+
+ public static void setThinArmor(boolean value) {
+ thinArmor = value;
+ }
+
+ public static boolean hasLavafallParticles() {
+ return lavafallParticles;
+ }
+
+ public static void changeFogDensity(float density) {
+ fogStart = -0.45F * density + 0.5F;
+ fogEnd = -0.5F * density + 1;
+ }
+
+ public static float getFogStart() {
+ return fogStart;
+ }
+
+ public static float getFogEnd() {
+ return fogEnd;
+ }
+}
diff --git a/src/main/java/redd90/betternether/BlocksHelper.java b/src/main/java/redd90/betternether/BlocksHelper.java
new file mode 100644
index 0000000..502bf7c
--- /dev/null
+++ b/src/main/java/redd90/betternether/BlocksHelper.java
@@ -0,0 +1,150 @@
+package redd90.betternether;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.fluid.LavaFluid;
+import net.minecraft.state.Property;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.vector.Vector3i;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.blocks.BlockFarmland;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlocksHelper {
+ public static final int FLAG_UPDATE_BLOCK = 1;
+ public static final int FLAG_SEND_CLIENT_CHANGES = 2;
+ public static final int FLAG_NO_RERENDER = 4;
+ public static final int FORSE_RERENDER = 8;
+ public static final int FLAG_IGNORE_OBSERVERS = 16;
+
+ public static final int SET_SILENT = FLAG_UPDATE_BLOCK | FLAG_IGNORE_OBSERVERS | FLAG_SEND_CLIENT_CHANGES;
+ public static final int SET_UPDATE = FLAG_UPDATE_BLOCK | FLAG_SEND_CLIENT_CHANGES;
+ public static final Direction[] HORIZONTAL = new Direction[] { Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST };
+
+ private static final Vector3i[] OFFSETS = new Vector3i[] {
+ new Vector3i(-1, -1, -1), new Vector3i(-1, -1, 0), new Vector3i(-1, -1, 1),
+ new Vector3i(-1, 0, -1), new Vector3i(-1, 0, 0), new Vector3i(-1, 0, 1),
+ new Vector3i(-1, 1, -1), new Vector3i(-1, 1, 0), new Vector3i(-1, 1, 1),
+
+ new Vector3i(0, -1, -1), new Vector3i(0, -1, 0), new Vector3i(0, -1, 1),
+ new Vector3i(0, 0, -1), new Vector3i(0, 0, 0), new Vector3i(0, 0, 1),
+ new Vector3i(0, 1, -1), new Vector3i(0, 1, 0), new Vector3i(0, 1, 1),
+
+ new Vector3i(1, -1, -1), new Vector3i(1, -1, 0), new Vector3i(1, -1, 1),
+ new Vector3i(1, 0, -1), new Vector3i(1, 0, 0), new Vector3i(1, 0, 1),
+ new Vector3i(1, 1, -1), new Vector3i(1, 1, 0), new Vector3i(1, 1, 1)
+ };
+
+ public static boolean isLava(BlockState state) {
+ return state.getFluidState().getFluid() instanceof LavaFluid;
+ }
+
+ public static boolean isNetherrack(BlockState state) {
+ return state.isIn(NetherTags.Blocks.NETHERRACK);
+ }
+
+ public static boolean isSoulSand(BlockState state) {
+ return state.isIn(NetherTags.Blocks.SOUL_GROUND);
+ }
+
+ public static boolean isNetherGround(BlockState state) {
+ return isNetherrack(state) || isSoulSand(state) || isNetherMycelium(state) || isNylium(state);
+ // return state.isIn(NetherTags.NETHER_GROUND);
+ }
+
+ public static boolean isNetherGroundMagma(BlockState state) {
+ return isNetherGround(state) || state.getBlock() == Blocks.MAGMA_BLOCK;
+ }
+
+ public static boolean isBone(BlockState state) {
+ Block b = state.getBlock();
+ return b == Blocks.BONE_BLOCK || b == BlocksRegistry.BONE_BLOCK;
+ }
+
+ public static boolean isNetherMycelium(BlockState state) {
+ return state.isIn(NetherTags.Blocks.MYCELIUM);
+ }
+
+ public static void setWithUpdate(IWorld world, BlockPos pos, BlockState state) {
+ world.setBlockState(pos, state, SET_UPDATE);
+ }
+
+ public static void setWithoutUpdate(IWorld world, BlockPos pos, BlockState state) {
+ world.setBlockState(pos, state, SET_SILENT);
+ }
+
+ public static int upRay(IWorld world, BlockPos pos, int maxDist) {
+ int length = 0;
+ for (int j = 1; j < maxDist && (world.isAirBlock(pos.up(j))); j++)
+ length++;
+ return length;
+ }
+
+ public static int downRay(IWorld world, BlockPos pos, int maxDist) {
+ int length = 0;
+ for (int j = 1; j < maxDist && (world.isAirBlock(pos.down(j))); j++)
+ length++;
+ return length;
+ }
+
+ public static BlockState rotateHorizontal(BlockState state, Rotation rotation, Property facing) {
+ return (BlockState) state.with(facing, rotation.rotate((Direction) state.get(facing)));
+ }
+
+ public static BlockState mirrorHorizontal(BlockState state, Mirror mirror, Property facing) {
+ return state.rotate(mirror.toRotation((Direction) state.get(facing)));
+ }
+
+ public static int getLengthDown(ServerWorld world, BlockPos pos, Block block) {
+ int count = 1;
+ while (world.getBlockState(pos.down(count)).getBlock() == block)
+ count++;
+ return count;
+ }
+
+ public static boolean isFertile(BlockState state) {
+ return state.getBlock() instanceof BlockFarmland;
+ }
+
+ public static void cover(IWorld world, BlockPos center, Block ground, BlockState cover, int radius, Random random) {
+ HashSet points = new HashSet();
+ HashSet points2 = new HashSet();
+ if (world.getBlockState(center).getBlock() == ground) {
+ points.add(center);
+ points2.add(center);
+ for (int i = 0; i < radius; i++) {
+ Iterator iterator = points.iterator();
+ while (iterator.hasNext()) {
+ BlockPos pos = iterator.next();
+ for (Vector3i offset : OFFSETS) {
+ if (random.nextBoolean()) {
+ BlockPos pos2 = pos.add(offset);
+ if (random.nextBoolean() && world.getBlockState(pos2).getBlock() == ground && !points.contains(pos2))
+ points2.add(pos2);
+ }
+ }
+ }
+ points.addAll(points2);
+ points2.clear();
+ }
+ Iterator iterator = points.iterator();
+ while (iterator.hasNext()) {
+ BlockPos pos = iterator.next();
+ BlocksHelper.setWithoutUpdate(world, pos, cover);
+ }
+ }
+ }
+
+ public static boolean isNylium(BlockState state) {
+ return state.isIn(NetherTags.Blocks.NYLIUM);
+ }
+}
diff --git a/src/main/java/redd90/betternether/MHelper.java b/src/main/java/redd90/betternether/MHelper.java
new file mode 100644
index 0000000..e7a538f
--- /dev/null
+++ b/src/main/java/redd90/betternether/MHelper.java
@@ -0,0 +1,51 @@
+package redd90.betternether;
+
+import java.util.Random;
+
+public class MHelper {
+ public static final float PI2 = (float) (Math.PI * 2);
+ private static final int ALPHA = 255 << 24;
+ public static final Random RANDOM = new Random();
+
+ public static int color(int r, int g, int b) {
+ return ALPHA | (r << 16) | (g << 8) | b;
+ }
+
+ public static int randRange(int min, int max, Random random) {
+ return min + random.nextInt(max - min + 1);
+ }
+
+ public static float randRange(float min, float max, Random random) {
+ return min + random.nextFloat() * (max - min);
+ }
+
+ public static byte setBit(byte source, int pos, boolean value) {
+ return value ? setBitTrue(source, pos) : setBitFalse(source, pos);
+ }
+
+ public static byte setBitTrue(byte source, int pos) {
+ source |= 1 << pos;
+ return source;
+ }
+
+ public static byte setBitFalse(byte source, int pos) {
+ source &= ~(1 << pos);
+ return source;
+ }
+
+ public static boolean getBit(byte source, int pos) {
+ return ((source >> pos) & 1) == 1;
+ }
+
+ public static int floor(float x) {
+ return x < 0 ? (int) (x - 1) : (int) x;
+ }
+
+ public static float wrap(float x, float side) {
+ return x - floor(x / side) * side;
+ }
+
+ public static int floor(double x) {
+ return x < 0 ? (int) (x - 1) : (int) x;
+ }
+}
diff --git a/src/main/java/redd90/betternether/NetherTags.java b/src/main/java/redd90/betternether/NetherTags.java
new file mode 100644
index 0000000..5655e85
--- /dev/null
+++ b/src/main/java/redd90/betternether/NetherTags.java
@@ -0,0 +1,41 @@
+package redd90.betternether;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.tags.BlockTags;
+import net.minecraft.tags.ItemTags;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.common.Tags.IOptionalNamedTag;
+
+public class NetherTags {
+ public static void init ()
+ {
+ Blocks.init();
+ Items.init();
+ }
+
+ public static class Blocks {
+ private static void init(){}
+
+ public static final IOptionalNamedTag SOUL_GROUND = tag("soul_ground");
+ public static final IOptionalNamedTag NETHERRACK = tag("netherrack");
+ public static final IOptionalNamedTag MYCELIUM = tag("nether_mycelium");
+ public static final IOptionalNamedTag NYLIUM = tag("nylium");
+
+ private static IOptionalNamedTag tag(String name)
+ {
+ return BlockTags.createOptional(new ResourceLocation(BetterNether.MOD_ID, name));
+ }
+ }
+
+ public static class Items {
+ private static void init(){}
+
+ public static final IOptionalNamedTag- SOUL_GROUND = tag("soul_ground");
+
+ private static IOptionalNamedTag
- tag(String name)
+ {
+ return ItemTags.createOptional(new ResourceLocation(BetterNether.MOD_ID, name));
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/BiomeDefinition.java b/src/main/java/redd90/betternether/biomes/BiomeDefinition.java
new file mode 100644
index 0000000..8589dc1
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/BiomeDefinition.java
@@ -0,0 +1,381 @@
+package redd90.betternether.biomes;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.client.audio.BackgroundMusicTracks;
+import net.minecraft.entity.EntityClassification;
+import net.minecraft.entity.EntityType;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.world.biome.Biome;
+import net.minecraft.world.biome.Biome.Category;
+import net.minecraft.world.biome.Biome.RainType;
+import net.minecraft.world.biome.BiomeAmbience;
+import net.minecraft.world.biome.BiomeGenerationSettings;
+import net.minecraft.world.biome.DefaultBiomeFeatures;
+import net.minecraft.world.biome.MobSpawnInfo;
+import net.minecraft.world.biome.MoodSoundAmbience;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import net.minecraft.world.biome.SoundAdditionsAmbience;
+import net.minecraft.world.gen.GenerationStage;
+import net.minecraft.world.gen.carver.ConfiguredCarvers;
+import net.minecraft.world.gen.feature.ConfiguredFeature;
+import net.minecraft.world.gen.feature.Features;
+import net.minecraft.world.gen.feature.StructureFeature;
+import net.minecraft.world.gen.feature.structure.StructureFeatures;
+import net.minecraft.world.gen.surfacebuilders.ConfiguredSurfaceBuilders;
+import net.minecraftforge.registries.ForgeRegistries;
+import redd90.betternether.BetterNether;
+import redd90.betternether.MHelper;
+import redd90.betternether.config.Configs;
+
+
+public class BiomeDefinition {
+ private final List> structures = Lists.newArrayList();
+ private final List features = Lists.newArrayList();
+ private final List mobs = Lists.newArrayList();
+
+ private ParticleEffectAmbience particleConfig;
+ private SoundAdditionsAmbience additions;
+ private MoodSoundAmbience mood;
+ private SoundEvent music;
+ private SoundEvent loop;
+
+ private int waterFogColor = 329011;
+ private int waterColor = 4159204;
+ private int fogColor = 3344392;
+
+ private boolean defaultOres = true;
+ private boolean defaultMobs = true;
+ private boolean defaultFeatures = true;
+ private boolean defaultStructureFeatures = true;
+ private boolean stalactites = true;
+ private boolean bnStructures = true;
+
+ private final ResourceLocation id;
+
+ public BiomeDefinition(String name) {
+ this.id = new ResourceLocation(BetterNether.MOD_ID, name.replace(' ', '_').toLowerCase());
+ }
+
+ public BiomeDefinition(ResourceLocation id) {
+ this.id = id;
+ }
+
+ public BiomeDefinition setStalactites(boolean value) {
+ stalactites = value;
+ return this;
+ }
+
+ public BiomeDefinition setBNStructures(boolean value) {
+ bnStructures = value;
+ return this;
+ }
+
+ /**
+ * Set default ores generation
+ *
+ * @param value
+ * - if true (default) then default ores will be generated
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setDefaultOres(boolean value) {
+ defaultOres = value;
+ return this;
+ }
+
+ /**
+ * Set default nether structure features to be added
+ *
+ * @param value
+ * - if true (default) then default structure features (nether
+ * fortresses, caves, etc.) will be added into biome
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setDefaultStructureFeatures(boolean value) {
+ defaultStructureFeatures = value;
+ return this;
+ }
+
+ /**
+ * Set default nether features to be added
+ *
+ * @param value
+ * - if true (default) then default features (small structures)
+ * will be added into biome
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setDefaultFeatures(boolean value) {
+ defaultFeatures = value;
+ return this;
+ }
+
+ /**
+ * Set default Nether Wastes mobs to be added
+ *
+ * @param value
+ * - if true (default) then default mobs will be added into biome
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setDefaultMobs(boolean value) {
+ defaultMobs = value;
+ return this;
+ }
+
+ public BiomeDefinition setParticleConfig(ParticleEffectAmbience config) {
+ this.particleConfig = config;
+ return this;
+ }
+
+ /**
+ * Adds mob into biome
+ *
+ * @param type
+ * - {@link EntityType}
+ * @param group
+ * - {@link SpawnGroup}
+ * @param weight
+ * - cumulative spawning weight
+ * @param minGroupSize
+ * - minimum count of mobs in the group
+ * @param maxGroupSize
+ * - maximum count of mobs in the group
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition addMobSpawn(EntityType> type, int weight, int minGroupSize, int maxGroupSize) {
+ ResourceLocation eID = ForgeRegistries.ENTITIES.getKey(type);
+ if (eID != ForgeRegistries.ENTITIES.getDefaultKey()) {
+ String path = "generator.biome." + id.getNamespace() + "." + id.getPath() + ".mobs." + eID.getNamespace() + "." + eID.getPath();
+ SpawnInfo info = new SpawnInfo();
+ info.type = type;
+ info.weight = Configs.BIOMES.getInt(path, "weight", weight);
+ info.minGroupSize = Configs.BIOMES.getInt(path, "min_group_size", minGroupSize);
+ info.maxGroupSize = Configs.BIOMES.getInt(path, "max_group_size", maxGroupSize);
+ mobs.add(info);
+ }
+ return this;
+ }
+
+ /**
+ * Adds feature (small structure) into biome - plants, ores, small
+ * buildings, etc.
+ *
+ * @param feature
+ * - {@link StructureFeature} to add
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition addStructureFeature(StructureFeature, ?> feature) {
+ structures.add(feature);
+ return this;
+ }
+
+ public BiomeDefinition addFeature(GenerationStage.Decoration featureStep, ConfiguredFeature, ?> feature) {
+ FeatureInfo info = new FeatureInfo();
+ info.featureStep = featureStep;
+ info.feature = feature;
+ features.add(info);
+ return this;
+ }
+
+ /**
+ * Sets biome fog color
+ *
+ * @param r
+ * - Red [0 - 255]
+ * @param g
+ * - Green [0 - 255]
+ * @param b
+ * - Blue [0 - 255]
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setFogColor(int r, int g, int b) {
+ String path = "generator.biome." + id.getNamespace() + "." + id.getPath() + ".fog_color";
+ r = MathHelper.clamp(Configs.BIOMES.getInt(path, "red", r), 0, 255);
+ g = MathHelper.clamp(Configs.BIOMES.getInt(path, "green", g), 0, 255);
+ b = MathHelper.clamp(Configs.BIOMES.getInt(path, "blue", b), 0, 255);
+ this.fogColor = MHelper.color(r, g, b);
+ return this;
+ }
+
+ /**
+ * Sets biome water color
+ *
+ * @param r
+ * - Red [0 - 255]
+ * @param g
+ * - Green [0 - 255]
+ * @param b
+ * - Blue [0 - 255]
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setWaterColor(int r, int g, int b) {
+ String path = "generator.biome." + id.getNamespace() + "." + id.getPath() + ".water_color";
+ r = MathHelper.clamp(Configs.BIOMES.getInt(path, "red", r), 0, 255);
+ g = MathHelper.clamp(Configs.BIOMES.getInt(path, "green", g), 0, 255);
+ b = MathHelper.clamp(Configs.BIOMES.getInt(path, "blue", b), 0, 255);
+ this.waterColor = MHelper.color(r, g, b);
+ return this;
+ }
+
+ /**
+ * Sets biome underwater fog color
+ *
+ * @param r
+ * - Red [0 - 255]
+ * @param g
+ * - Green [0 - 255]
+ * @param b
+ * - Blue [0 - 255]
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setWaterFogColor(int r, int g, int b) {
+ String path = "generator.biome." + id.getNamespace() + "." + id.getPath() + ".water_fog_color";
+ r = MathHelper.clamp(Configs.BIOMES.getInt(path, "red", r), 0, 255);
+ g = MathHelper.clamp(Configs.BIOMES.getInt(path, "green", g), 0, 255);
+ b = MathHelper.clamp(Configs.BIOMES.getInt(path, "blue", b), 0, 255);
+ this.waterFogColor = MHelper.color(r, g, b);
+ return this;
+ }
+
+ /**
+ * Plays in never-ending loop for as long as player is in the biome
+ *
+ * @param loop
+ * - SoundEvent
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setLoop(SoundEvent loop) {
+ this.loop = loop;
+ return this;
+ }
+
+ /**
+ * Plays commonly while the player is in the biome
+ *
+ * @param mood
+ * - SoundEvent
+ * @return this {@link BiomeDefinition}
+ */
+ public BiomeDefinition setMood(SoundEvent mood) {
+ this.mood = new MoodSoundAmbience(mood, 6000, 8, 2.0D);
+ return this;
+ }
+
+ /**
+ * Set additional sounds. They plays once every 6000-17999 ticks while the
+ * player is in the biome
+ *
+ * @param additions
+ * - SoundEvent
+ * @return this BiomeDefenition
+ */
+ public BiomeDefinition setAdditions(SoundEvent additions) {
+ this.additions = new SoundAdditionsAmbience(additions, 0.0111);
+ return this;
+ }
+
+ /**
+ * Set background music for biome
+ *
+ * @param music
+ * @return
+ */
+ public BiomeDefinition setMusic(SoundEvent music) {
+ this.music = music;
+ return this;
+ }
+
+ public Biome build() {
+ MobSpawnInfo.Builder spawnSettings = new MobSpawnInfo.Builder();
+ BiomeGenerationSettings.Builder generationSettings = new BiomeGenerationSettings.Builder();
+ BiomeAmbience.Builder effects = new BiomeAmbience.Builder();
+
+ if (defaultMobs) addDefaultMobs(spawnSettings);
+ mobs.forEach((spawn) -> {
+ spawnSettings.withSpawner(spawn.type.getClassification(), new MobSpawnInfo.Spawners(spawn.type, spawn.weight, spawn.minGroupSize, spawn.maxGroupSize));
+ });
+
+ generationSettings.withSurfaceBuilder(ConfiguredSurfaceBuilders.field_244183_o);
+ structures.forEach((structure) -> generationSettings.withStructure(structure));
+ features.forEach((info) -> generationSettings.withFeature(info.featureStep, info.feature));
+ if (defaultOres) DefaultBiomeFeatures.withCommonNetherBlocks(generationSettings);
+ if (defaultStructureFeatures) addDefaultStructures(generationSettings);
+ if (defaultFeatures) addDefaultFeatures(generationSettings);
+
+ effects.withSkyColor(fogColor).setWaterColor(waterColor).setWaterFogColor(waterFogColor).setFogColor(fogColor);
+ if (loop != null) effects.setAmbientSound(loop);
+ if (mood != null) effects.setMoodSound(mood);
+ if (additions != null) effects.setAdditionsSound(additions);
+ if (particleConfig != null) effects.setParticle(particleConfig);
+ effects.setMusic(BackgroundMusicTracks.getDefaultBackgroundMusicSelector(music != null ? music : SoundEvents.MUSIC_NETHER_NETHER_WASTES));
+
+ return new Biome.Builder()
+ .precipitation(RainType.NONE)
+ .category(Category.NETHER)
+ .depth(0.1F)
+ .scale(0.2F)
+ .temperature(2.0F)
+ .downfall(0.0F)
+ .setEffects(effects.build())
+ .withMobSpawnSettings(spawnSettings.copy())
+ .withGenerationSettings(generationSettings.build())
+ .build();
+ }
+
+ private void addDefaultStructures(BiomeGenerationSettings.Builder generationSettings) {
+ generationSettings.withStructure(StructureFeatures.RUINED_PORTAL_NETHER);
+ generationSettings.withStructure(StructureFeatures.FORTRESS);
+ generationSettings.withStructure(StructureFeatures.BASTION_REMNANT);
+ generationSettings.withCarver(GenerationStage.Carving.AIR, ConfiguredCarvers.field_243772_f);
+ generationSettings.withFeature(GenerationStage.Decoration.VEGETAL_DECORATION, Features.SPRING_LAVA);
+ }
+
+ private void addDefaultFeatures(BiomeGenerationSettings.Builder generationSettings) {
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.SPRING_OPEN);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.PATCH_FIRE);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.PATCH_SOUL_FIRE);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.GLOWSTONE_EXTRA);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.GLOWSTONE);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.BROWN_MUSHROOM_NETHER);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.RED_MUSHROOM_NETHER);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.ORE_MAGMA);
+ generationSettings.withFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, Features.SPRING_CLOSED);
+ }
+
+ private void addDefaultMobs(MobSpawnInfo.Builder spawnSettings) {
+ spawnSettings.withSpawner(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.GHAST, 50, 4, 4));
+ spawnSettings.withSpawner(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.ZOMBIFIED_PIGLIN, 100, 4, 4));
+ spawnSettings.withSpawner(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.MAGMA_CUBE, 2, 4, 4));
+ spawnSettings.withSpawner(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.ENDERMAN, 1, 4, 4));
+ spawnSettings.withSpawner(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.PIGLIN, 15, 4, 4));
+ spawnSettings.withSpawner(EntityClassification.CREATURE, new MobSpawnInfo.Spawners(EntityType.STRIDER, 60, 1, 2));
+ }
+
+ private static final class SpawnInfo {
+ EntityType> type;
+ int weight;
+ int minGroupSize;
+ int maxGroupSize;
+ }
+
+ private static final class FeatureInfo {
+ GenerationStage.Decoration featureStep;
+ ConfiguredFeature, ?> feature;
+ }
+
+ public ResourceLocation getID() {
+ return id;
+ }
+
+ public boolean hasStalactites() {
+ return stalactites;
+ }
+
+ public boolean hasBNStructures() {
+ return bnStructures;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/CrimsonGlowingWoods.java b/src/main/java/redd90/betternether/biomes/CrimsonGlowingWoods.java
new file mode 100644
index 0000000..4777895
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/CrimsonGlowingWoods.java
@@ -0,0 +1,53 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.noise.OpenSimplexNoise;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureCrimsonFungus;
+import redd90.betternether.structures.plants.StructureCrimsonGlowingTree;
+import redd90.betternether.structures.plants.StructureCrimsonRoots;
+import redd90.betternether.structures.plants.StructureGoldenVine;
+import redd90.betternether.structures.plants.StructureWallMoss;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+import redd90.betternether.structures.plants.StructureWartBush;
+import redd90.betternether.structures.plants.StructureWartSeed;
+
+public class CrimsonGlowingWoods extends NetherBiome {
+ private static final OpenSimplexNoise TERRAIN = new OpenSimplexNoise(614);
+
+ public CrimsonGlowingWoods(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(51, 3, 3)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.CRIMSON_SPORE, 0.025F))
+ .addMobSpawn(EntityRegistry.FLYING_PIG, 20, 2, 4));
+ addStructure("crimson_glowing_tree", new StructureCrimsonGlowingTree(), StructureType.FLOOR, 0.2F, false);
+ addStructure("wart_bush", new StructureWartBush(), StructureType.FLOOR, 0.05F, false);
+ addStructure("wart_seed", new StructureWartSeed(), StructureType.FLOOR, 0.02F, true);
+ addStructure("crimson_fungus", new StructureCrimsonFungus(), StructureType.FLOOR, 0.05F, true);
+ addStructure("crimson_roots", new StructureCrimsonRoots(), StructureType.FLOOR, 0.2F, true);
+ addStructure("golden_vine", new StructureGoldenVine(), StructureType.CEIL, 0.3F, true);
+ addStructure("wall_moss", new StructureWallMoss(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.4F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ if (TERRAIN.eval(pos.getX() * 0.1, pos.getZ() * 0.1) > MHelper.randRange(0.5F, 0.7F, random))
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.NETHER_WART_BLOCK.getDefaultState());
+ else
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.CRIMSON_NYLIUM.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/CrimsonPinewood.java b/src/main/java/redd90/betternether/biomes/CrimsonPinewood.java
new file mode 100644
index 0000000..dab2ef0
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/CrimsonPinewood.java
@@ -0,0 +1,53 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.noise.OpenSimplexNoise;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureCrimsonFungus;
+import redd90.betternether.structures.plants.StructureCrimsonPinewood;
+import redd90.betternether.structures.plants.StructureCrimsonRoots;
+import redd90.betternether.structures.plants.StructureGoldenVine;
+import redd90.betternether.structures.plants.StructureWallMoss;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+import redd90.betternether.structures.plants.StructureWartBush;
+import redd90.betternether.structures.plants.StructureWartSeed;
+
+public class CrimsonPinewood extends NetherBiome {
+ private static final OpenSimplexNoise TERRAIN = new OpenSimplexNoise(614);
+
+ public CrimsonPinewood(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(51, 3, 3)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.CRIMSON_SPORE, 0.025F))
+ .addMobSpawn(EntityRegistry.FLYING_PIG, 20, 2, 4));
+ addStructure("crimson_pinewood", new StructureCrimsonPinewood(), StructureType.FLOOR, 0.2F, false);
+ addStructure("wart_bush", new StructureWartBush(), StructureType.FLOOR, 0.1F, false);
+ addStructure("wart_seed", new StructureWartSeed(), StructureType.FLOOR, 0.05F, true);
+ addStructure("crimson_fungus", new StructureCrimsonFungus(), StructureType.FLOOR, 0.05F, true);
+ addStructure("crimson_roots", new StructureCrimsonRoots(), StructureType.FLOOR, 0.2F, true);
+ addStructure("golden_vine", new StructureGoldenVine(), StructureType.CEIL, 0.3F, true);
+ addStructure("wall_moss", new StructureWallMoss(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.4F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ if (TERRAIN.eval(pos.getX() * 0.1, pos.getZ() * 0.1) > MHelper.randRange(0.5F, 0.7F, random))
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.NETHER_WART_BLOCK.getDefaultState());
+ else
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.CRIMSON_NYLIUM.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/FloodedDeltas.java b/src/main/java/redd90/betternether/biomes/FloodedDeltas.java
new file mode 100644
index 0000000..6e4c090
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/FloodedDeltas.java
@@ -0,0 +1,67 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.structures.StructureType;
+
+public class FloodedDeltas extends NetherBiome {
+ private static final Mutable POS = new Mutable();
+
+ public FloodedDeltas(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(104, 95, 112)
+ .setLoop(SoundEvents.AMBIENT_BASALT_DELTAS_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_BASALT_DELTAS_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_BASALT_DELTAS_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_BASALT_DELTAS)
+ .setStalactites(false)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.WHITE_ASH, 0.12F)));
+
+ addStructure("blackstone_stalactite", STALACTITE_BLACKSTONE, StructureType.FLOOR, 0.2F, true);
+ addStructure("stalactite_stalactite", STALACTITE_BASALT, StructureType.FLOOR, 0.2F, true);
+
+ addStructure("blackstone_stalagmite", STALAGMITE_BLACKSTONE, StructureType.CEIL, 0.1F, true);
+ addStructure("basalt_stalagmite", STALAGMITE_BASALT, StructureType.CEIL, 0.1F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ POS.setPos(pos);
+ int d = MHelper.randRange(2, 4, random);
+ BlockState state = isLavaValid(world, pos) ? Blocks.LAVA.getDefaultState() : (random.nextInt(16) > 0 ? Blocks.BASALT.getDefaultState() : Blocks.AIR.getDefaultState());
+ BlocksHelper.setWithoutUpdate(world, POS, state);
+ if (state.getBlock() == Blocks.LAVA)
+ world.getChunk(pos.getX() >> 4, pos.getZ() >> 4).markBlockForPostprocessing(POS.setPos(pos.getX() & 15, pos.getY(), pos.getZ() & 15));
+ POS.setPos(pos);
+ for (int h = 1; h < d; h++) {
+ POS.setY(pos.getY() - h);
+ if (BlocksHelper.isNetherGround(world.getBlockState(POS)))
+ BlocksHelper.setWithoutUpdate(world, POS, Blocks.BASALT.getDefaultState());
+ else
+ break;
+ }
+ }
+
+ protected boolean isLavaValid(IWorld world, BlockPos pos) {
+ return validWall(world, pos.down()) &&
+ validWall(world, pos.north()) &&
+ validWall(world, pos.south()) &&
+ validWall(world, pos.east()) &&
+ validWall(world, pos.west());
+ }
+
+ protected boolean validWall(IWorld world, BlockPos pos) {
+ BlockState state = world.getBlockState(pos);
+ return BlocksHelper.isLava(state) || state.hasOpaqueCollisionShape(world, pos);
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherBiome.java b/src/main/java/redd90/betternether/biomes/NetherBiome.java
new file mode 100644
index 0000000..53132c7
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherBiome.java
@@ -0,0 +1,421 @@
+package redd90.betternether.biomes;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IServerWorld;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.Biome;
+import net.minecraftforge.registries.ForgeRegistryEntry;
+import redd90.betternether.config.Configs;
+import redd90.betternether.noise.OpenSimplexNoise;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.structures.IStructure;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.StructureWorld;
+import redd90.betternether.structures.decorations.StructureStalactite;
+import redd90.betternether.structures.decorations.StructureStalagmite;
+import redd90.betternether.structures.plants.StructureWartCap;
+
+public class NetherBiome extends ForgeRegistryEntry {
+ private static final OpenSimplexNoise SCATTER = new OpenSimplexNoise(1337);
+ private static int structureID = 0;
+
+ private ArrayList generatorsFloor = new ArrayList();
+ private ArrayList generatorsWall = new ArrayList();
+ private ArrayList generatorsCeil = new ArrayList();
+ private ArrayList generatorsLava = new ArrayList();
+
+ private ArrayList buildGeneratorsFloor = new ArrayList();
+ private ArrayList buildGeneratorsCeil = new ArrayList();
+ private ArrayList buildGeneratorsLava = new ArrayList();
+ private ArrayList buildGeneratorsUnder = new ArrayList();
+
+ protected final ResourceLocation mcID;
+ protected final Biome biome;
+
+ protected float maxSubBiomeChance = 1;
+ protected float plantDensity = 1.0001F;
+ protected float noiseDensity = 0.3F;
+ protected float genChance = 1;
+ protected float edgeSize;
+
+ protected List subbiomes;
+ protected NetherBiome biomeParent;
+ protected NetherBiome edge;
+
+ private static final String[] DEF_STRUCTURES = new String[] {
+ structureFormat("altar_01", -2, StructureType.FLOOR, 1),
+ structureFormat("altar_02", -4, StructureType.FLOOR, 1),
+ structureFormat("altar_03", -3, StructureType.FLOOR, 1),
+ structureFormat("altar_04", -3, StructureType.FLOOR, 1),
+ structureFormat("altar_05", -2, StructureType.FLOOR, 1),
+ structureFormat("altar_06", -2, StructureType.FLOOR, 1),
+ structureFormat("altar_07", -2, StructureType.FLOOR, 1),
+ structureFormat("altar_08", -2, StructureType.FLOOR, 1),
+ structureFormat("portal_01", -4, StructureType.FLOOR, 1),
+ structureFormat("portal_02", -3, StructureType.FLOOR, 1),
+ structureFormat("garden_01", -3, StructureType.FLOOR, 1),
+ structureFormat("garden_02", -2, StructureType.FLOOR, 1),
+ structureFormat("pillar_01", -1, StructureType.FLOOR, 1),
+ structureFormat("pillar_02", -1, StructureType.FLOOR, 1),
+ structureFormat("pillar_03", -1, StructureType.FLOOR, 1),
+ structureFormat("pillar_04", -1, StructureType.FLOOR, 1),
+ structureFormat("pillar_05", -1, StructureType.FLOOR, 1),
+ structureFormat("pillar_06", -1, StructureType.FLOOR, 1),
+ structureFormat("respawn_point_01", -3, StructureType.FLOOR, 1),
+ structureFormat("respawn_point_02", -2, StructureType.FLOOR, 1),
+ structureFormat("respawn_point_03", -3, StructureType.FLOOR, 1),
+ structureFormat("respawn_point_04", -2, StructureType.FLOOR, 1),
+ structureFormat("spawn_altar_ladder", -5, StructureType.FLOOR, 1),
+
+ structureFormat("ghast_hive", -20, StructureType.CEIL, 1F),
+
+ structureFormat("lava/pyramid_1", -1, StructureType.LAVA, 1F),
+ structureFormat("lava/pyramid_2", -1, StructureType.LAVA, 1F),
+ structureFormat("lava/pyramid_3", -1, StructureType.LAVA, 1F),
+ structureFormat("lava/pyramid_4", -1, StructureType.LAVA, 1F)
+ };
+
+ private ArrayList structures;
+ private Biome actualBiome;
+
+ protected static final StructureStalagmite STALACTITE_NETHERRACK = new StructureStalagmite(BlocksRegistry.NETHERRACK_STALACTITE, null);
+ protected static final StructureStalagmite STALACTITE_GLOWSTONE = new StructureStalagmite(BlocksRegistry.GLOWSTONE_STALACTITE, Blocks.GLOWSTONE);
+ protected static final StructureStalagmite STALACTITE_BLACKSTONE = new StructureStalagmite(BlocksRegistry.BLACKSTONE_STALACTITE, Blocks.BLACKSTONE, Blocks.BLACKSTONE, Blocks.NETHERRACK);
+ protected static final StructureStalagmite STALACTITE_BASALT = new StructureStalagmite(BlocksRegistry.BASALT_STALACTITE, Blocks.BASALT, Blocks.BASALT, Blocks.NETHERRACK);
+
+ protected static final StructureStalactite STALAGMITE_NETHERRACK = new StructureStalactite(BlocksRegistry.NETHERRACK_STALACTITE, null);
+ protected static final StructureStalactite STALAGMITE_GLOWSTONE = new StructureStalactite(BlocksRegistry.GLOWSTONE_STALACTITE, Blocks.GLOWSTONE);
+ protected static final StructureStalactite STALAGMITE_BLACKSTONE = new StructureStalactite(BlocksRegistry.BLACKSTONE_STALACTITE, Blocks.BLACKSTONE, Blocks.BLACKSTONE, Blocks.NETHERRACK);
+ protected static final StructureStalactite STALAGMITE_BASALT = new StructureStalactite(BlocksRegistry.BASALT_STALACTITE, Blocks.BASALT, Blocks.BASALT, Blocks.NETHERRACK);
+
+ public NetherBiome(BiomeDefinition definition) {
+ //definition.addMobSpawn(EntityRegistry.FIREFLY, 5, 2, 6);
+ definition.addMobSpawn(EntityRegistry.SKULL, 2, 2, 4);
+ definition.addMobSpawn(EntityRegistry.NAGA, 20, 2, 4);
+ definition.addMobSpawn(EntityRegistry.HYDROGEN_JELLYFISH, 5, 2, 5);
+
+ biome = definition.build();
+ mcID = definition.getID();
+
+ subbiomes = new ArrayList();
+ addStructure("cap_gen", new StructureWartCap(), StructureType.WALL, 0.8F, true);
+ subbiomes.add(new Subbiome(this, 1));
+
+ structures = new ArrayList(DEF_STRUCTURES.length);
+ if (definition.hasBNStructures()) {
+ for (String s : DEF_STRUCTURES)
+ structures.add(s);
+ }
+
+ if (definition.hasStalactites()) {
+ addStructure("netherrack_stalactite", STALACTITE_NETHERRACK, StructureType.FLOOR, 0.05F, true);
+ addStructure("glowstone_stalactite", STALACTITE_GLOWSTONE, StructureType.FLOOR, 0.01F, true);
+
+ addStructure("netherrack_stalagmite", STALAGMITE_NETHERRACK, StructureType.CEIL, 0.01F, true);
+ addStructure("glowstone_stalagmite", STALAGMITE_GLOWSTONE, StructureType.CEIL, 0.005F, true);
+ }
+ }
+
+ public void setPlantDensity(float density) {
+ this.plantDensity = density * 1.0001F;
+ }
+
+ public float getPlantDensity() {
+ return plantDensity;
+ }
+
+ public void setNoiseDensity(float density) {
+ this.noiseDensity = 1 - density * 2;
+ }
+
+ public float getNoiseDensity() {
+ return (1F - this.noiseDensity) / 2F;
+ }
+
+ private String getGroup() {
+ return "generator.biome." + mcID.getNamespace() + "." + getRegistryName();
+ }
+
+ public void build() {
+ String group = getGroup();
+ String[] structAll = Configs.BIOMES.getStringArray(group, "schematics", structures.toArray(new String[] {}));
+ for (String struct : structAll) {
+ structureFromString(struct);
+ }
+ setNoiseDensity(Configs.BIOMES.getFloat(group, "noise_density", getNoiseDensity()));
+ }
+
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {}
+
+ public void genFloorObjects(IServerWorld world, BlockPos pos, Random random) {
+ for (StructureInfo info : generatorsFloor)
+ if (info.canGenerate(random, pos))
+ info.structure.generate(world, pos, random);
+ }
+
+ public void genWallObjects(IServerWorld world, BlockPos pos, Random random) {
+ for (StructureInfo info : generatorsWall)
+ if (info.canGenerate(random, pos))
+ info.structure.generate(world, pos, random);
+ }
+
+ public void genCeilObjects(IServerWorld world, BlockPos pos, Random random) {
+ for (StructureInfo info : generatorsCeil)
+ if (info.canGenerate(random, pos))
+ info.structure.generate(world, pos, random);
+ }
+
+ public void genLavaObjects(IServerWorld world, BlockPos pos, Random random) {
+ for (StructureInfo info : generatorsLava)
+ if (info.canGenerate(random, pos))
+ info.structure.generate(world, pos, random);
+ }
+
+ protected static double getFeatureNoise(BlockPos pos, int id) {
+ return SCATTER.eval(pos.getX() * 0.1, pos.getY() * 0.1 + id * 10, pos.getZ() * 0.1);
+ }
+
+ public String getRawBiomeRegistryName() {
+ return mcID.getPath();
+ }
+
+ public NetherBiome getEdge() {
+ return edge;
+ }
+
+ public void setEdge(NetherBiome edge) {
+ this.edge = edge;
+ edge.biomeParent = this;
+ }
+
+ public float getEdgeSize() {
+ return edgeSize;
+ }
+
+ public void setEdgeSize(float size) {
+ edgeSize = size;
+ }
+
+ public void addSubBiome(NetherBiome biome, float chance) {
+ maxSubBiomeChance += chance;
+ biome.biomeParent = this;
+ subbiomes.add(new Subbiome(biome, maxSubBiomeChance));
+ }
+
+ public NetherBiome getSubBiome(Random random) {
+ float chance = random.nextFloat() * maxSubBiomeChance;
+ for (Subbiome biome : subbiomes)
+ if (biome.canGenerate(chance))
+ return biome.biome;
+ return this;
+ }
+
+ public NetherBiome getParentBiome() {
+ return this.biomeParent;
+ }
+
+ public boolean hasEdge() {
+ return edge != null;
+ }
+
+ public boolean hasParentBiome() {
+ return biomeParent != null;
+ }
+
+ public boolean isSame(NetherBiome biome) {
+ return biome == this || (biome.hasParentBiome() && biome.getParentBiome() == this);
+ }
+
+ protected void addStructure(String name, IStructure structure, StructureType type, float density, boolean useNoise) {
+ String group = getGroup() + ".procedural." + type.getName() + "." + name;
+ float dens = Configs.BIOMES.getFloat(group, "density", density);
+ boolean limit = Configs.BIOMES.getBoolean(group, "limit", useNoise);
+ this.addStructure(structure, type, dens, limit);
+ }
+
+ private void addStructure(IStructure structure, StructureType type, float density, boolean useNoise) {
+ switch (type) {
+ case CEIL:
+ generatorsCeil.add(new StructureInfo(structure, density, useNoise));
+ break;
+ case FLOOR:
+ generatorsFloor.add(new StructureInfo(structure, density, useNoise));
+ break;
+ case WALL:
+ generatorsWall.add(new StructureInfo(structure, density, useNoise));
+ break;
+ default:
+ break;
+ }
+ }
+
+ protected void addWorldStructures(String... structures) {
+ for (String s : structures)
+ this.structures.add(s);
+ }
+
+ protected class StructureInfo {
+ final IStructure structure;
+ final float density;
+ final boolean useNoise;
+ final int id;
+
+ StructureInfo(IStructure structure, float density, boolean useNoise) {
+ this.structure = structure;
+ this.density = density;
+ this.useNoise = useNoise;
+ id = structureID++;
+ }
+
+ boolean canGenerate(Random random, BlockPos pos) {
+ return (!useNoise || getFeatureNoise(pos, id) > noiseDensity) && random.nextFloat() < density;
+ }
+ }
+
+ protected class Subbiome {
+ NetherBiome biome;
+ float chance;
+
+ Subbiome(NetherBiome biome, float chance) {
+ this.biome = biome;
+ this.chance = chance;
+ }
+
+ public boolean canGenerate(float chance) {
+ return chance < this.chance;
+ }
+ }
+
+ public boolean canGenerate(float chance) {
+ return chance <= this.genChance;
+ }
+
+ public void setGenChance(float chance) {
+ this.genChance = chance;
+ }
+
+ protected static String structureFormat(String name, int offset, StructureType type, float chance) {
+ return String.format(Locale.ROOT, "name: %s; offset: %d; type: %s; chance: %f", name, offset, type.getName(), chance);
+ }
+
+ public void genFloorBuildings(IServerWorld world, BlockPos pos, Random random) {
+ chancedStructure(world, pos, random, buildGeneratorsFloor);
+ }
+
+ public void genCeilBuildings(IServerWorld world, BlockPos pos, Random random) {
+ chancedStructure(world, pos, random, buildGeneratorsCeil);
+ }
+
+ public void genLavaBuildings(IServerWorld world, BlockPos pos, Random random) {
+ chancedStructure(world, pos, random, buildGeneratorsLava);
+ }
+
+ public void genUnderBuildings(IServerWorld world, BlockPos pos, Random random) {
+ chancedStructure(world, pos, random, buildGeneratorsUnder);
+ }
+
+ private void chancedStructure(IServerWorld world, BlockPos pos, Random random, List infoList) {
+ float chance = getLastChance(infoList);
+ if (chance > 0) {
+ float rnd = random.nextFloat() * chance;
+ for (StructureInfo info : infoList)
+ if (rnd <= info.density) {
+ info.structure.generate(world, pos, random);
+ return;
+ }
+ }
+ }
+
+ private void structureFromString(String structureString) {
+ String[] args = structureString.split(";");
+
+ String name = "";
+ int offset = 0;
+ StructureType type = StructureType.FLOOR;
+ float chance = 0;
+
+ for (String a : args) {
+ if (a.contains("name:")) {
+ name = a.replace("name:", "").trim();
+ }
+ else if (a.contains("offset:")) {
+ offset = Integer.parseInt(a.replace("offset:", "").trim());
+ }
+ else if (a.contains("type:")) {
+ type = StructureType.fromString(a);
+ }
+ else if (a.contains("chance:")) {
+ chance = Float.parseFloat(a.replace("chance:", "").trim());
+ }
+ }
+
+ if (!name.isEmpty()) {
+ StructureWorld structure = new StructureWorld(name, offset, type);
+ if (structure.loaded()) {
+ List infoList = null;
+ switch (structure.getType()) {
+ case CEIL:
+ infoList = buildGeneratorsCeil;
+ break;
+ case FLOOR:
+ infoList = buildGeneratorsFloor;
+ break;
+ case LAVA:
+ infoList = buildGeneratorsLava;
+ break;
+ case UNDER:
+ infoList = buildGeneratorsUnder;
+ break;
+ default:
+ break;
+ }
+
+ chance += getLastChance(infoList);
+ StructureInfo info = new StructureInfo(structure, chance, false);
+ infoList.add(info);
+ }
+ }
+ }
+
+ private float getLastChance(List info) {
+ int size = info.size();
+ return size > 0 ? info.get(size - 1).density : 0;
+ }
+
+ public Biome getBiome() {
+ return biome;
+ }
+
+ public boolean hasCeilStructures() {
+ return !buildGeneratorsCeil.isEmpty();
+ }
+
+ public String getNamespace() {
+ return mcID.getNamespace();
+ }
+
+ @Override
+ public String toString() {
+ return mcID.toString();
+ }
+
+ public ResourceLocation getID() {
+ return mcID;
+ }
+
+ public Biome getActualBiome() {
+ return actualBiome;
+ }
+
+ public void setActualBiome(Biome actualBiome) {
+ this.actualBiome = actualBiome;
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherBiomeWrapper.java b/src/main/java/redd90/betternether/biomes/NetherBiomeWrapper.java
new file mode 100644
index 0000000..a7015a8
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherBiomeWrapper.java
@@ -0,0 +1,37 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.Biome;
+import net.minecraftforge.registries.ForgeRegistries;
+import redd90.betternether.structures.StructureType;
+
+public class NetherBiomeWrapper extends NetherBiome {
+ final Biome biome;
+
+ public NetherBiomeWrapper(ResourceLocation id) {
+ super(new BiomeDefinition(id));
+ this.biome = ForgeRegistries.BIOMES.getValue(id);
+
+ if (id.getPath().equals("basalt_deltas")) {
+ addStructure("blackstone_stalactite", STALACTITE_BLACKSTONE, StructureType.FLOOR, 0.2F, true);
+ addStructure("stalactite_stalactite", STALACTITE_BASALT, StructureType.FLOOR, 0.2F, true);
+
+ addStructure("blackstone_stalagmite", STALAGMITE_BLACKSTONE, StructureType.CEIL, 0.1F, true);
+ addStructure("basalt_stalagmite", STALAGMITE_BASALT, StructureType.CEIL, 0.1F, true);
+ }
+ }
+
+ public NetherBiomeWrapper(ResourceLocation id, Biome biome) {
+ super(new BiomeDefinition(id));
+ this.biome = biome;
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ //BlocksHelper.setWithoutUpdate(world, pos, biome.getGenerationSettings().getSurfaceConfig().getTopMaterial());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/NetherBoneReef.java b/src/main/java/redd90/betternether/biomes/NetherBoneReef.java
new file mode 100644
index 0000000..1e63459
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherBoneReef.java
@@ -0,0 +1,49 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.decorations.StructureStalactite;
+import redd90.betternether.structures.decorations.StructureStalagmite;
+import redd90.betternether.structures.plants.StructureBoneGrass;
+import redd90.betternether.structures.plants.StructureBoneReef;
+import redd90.betternether.structures.plants.StructureFeatherFern;
+import redd90.betternether.structures.plants.StructureJellyfishMushroom;
+import redd90.betternether.structures.plants.StructureLumabusVine;
+import redd90.betternether.structures.plants.StructureReeds;
+
+public class NetherBoneReef extends NetherBiome {
+ public NetherBoneReef(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(47, 221, 202)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setStalactites(false)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.WARPED_SPORE, 0.01F)));
+
+ addStructure("bone_stalactite", new StructureStalagmite(BlocksRegistry.BONE_STALACTITE, BlocksRegistry.BONE_BLOCK), StructureType.FLOOR, 0.05F, true);
+
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.5F, false);
+ addStructure("bone_reef", new StructureBoneReef(), StructureType.FLOOR, 0.2F, true);
+ addStructure("jellyfish_mushroom", new StructureJellyfishMushroom(), StructureType.FLOOR, 0.02F, true);
+ addStructure("feather_fern", new StructureFeatherFern(), StructureType.FLOOR, 0.05F, true);
+ addStructure("bone_grass", new StructureBoneGrass(), StructureType.FLOOR, 0.1F, false);
+
+ addStructure("bone_stalagmite", new StructureStalactite(BlocksRegistry.BONE_STALACTITE, BlocksRegistry.BONE_BLOCK), StructureType.CEIL, 0.05F, true);
+
+ addStructure("lumabus_vine", new StructureLumabusVine(), StructureType.CEIL, 0.3F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.MUSHROOM_GRASS.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherGrasslands.java b/src/main/java/redd90/betternether/biomes/NetherGrasslands.java
new file mode 100644
index 0000000..8f585a7
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherGrasslands.java
@@ -0,0 +1,67 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackApple;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureInkBush;
+import redd90.betternether.structures.plants.StructureMagmaFlower;
+import redd90.betternether.structures.plants.StructureNetherGrass;
+import redd90.betternether.structures.plants.StructureNetherWart;
+import redd90.betternether.structures.plants.StructureReeds;
+import redd90.betternether.structures.plants.StructureSmoker;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallMoss;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+import redd90.betternether.structures.plants.StructureWartSeed;
+
+public class NetherGrasslands extends NetherBiome {
+ public NetherGrasslands(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(113, 73, 133)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD));
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.5F, false);
+ addStructure("nether_wart", new StructureNetherWart(), StructureType.FLOOR, 0.05F, true);
+ addStructure("magma_flower", new StructureMagmaFlower(), StructureType.FLOOR, 0.5F, true);
+ addStructure("smoker", new StructureSmoker(), StructureType.FLOOR, 0.05F, true);
+ addStructure("ink_bush", new StructureInkBush(), StructureType.FLOOR, 0.05F, true);
+ addStructure("black_apple", new StructureBlackApple(), StructureType.FLOOR, 0.01F, true);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.02F, true);
+ addStructure("wart_seed", new StructureWartSeed(), StructureType.FLOOR, 0.02F, true);
+ addStructure("nether_grass", new StructureNetherGrass(), StructureType.FLOOR, 0.4F, true);
+ addStructure("wall_moss", new StructureWallMoss(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.8F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ switch (random.nextInt(3)) {
+ case 0:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SOIL.getDefaultState());
+ break;
+ case 1:
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHERRACK_MOSS.getDefaultState());
+ break;
+ default:
+ super.genSurfColumn(world, pos, random);
+ break;
+ }
+ for (int i = 1; i < random.nextInt(3); i++) {
+ BlockPos down = pos.down(i);
+ if (random.nextInt(3) == 0 && BlocksHelper.isNetherGround(world.getBlockState(down))) {
+ BlocksHelper.setWithoutUpdate(world, down, Blocks.SOUL_SAND.getDefaultState());
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/biomes/NetherGravelDesert.java b/src/main/java/redd90/betternether/biomes/NetherGravelDesert.java
new file mode 100644
index 0000000..caf3412
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherGravelDesert.java
@@ -0,0 +1,45 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureAgave;
+import redd90.betternether.structures.plants.StructureBarrelCactus;
+import redd90.betternether.structures.plants.StructureNetherCactus;
+
+public class NetherGravelDesert extends NetherBiome {
+ public NetherGravelDesert(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(170, 48, 0)
+ .setLoop(SoundsRegistry.AMBIENT_GRAVEL_DESERT)
+ .setMood(SoundEvents.AMBIENT_NETHER_WASTES_MOOD)
+ .setAdditions(SoundEvents.AMBIENT_NETHER_WASTES_ADDITIONS)
+ .setMusic(SoundEvents.MUSIC_NETHER_NETHER_WASTES)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.ASH, 0.02F)));
+ addStructure("nether_cactus", new StructureNetherCactus(), StructureType.FLOOR, 0.02F, true);
+ addStructure("agave", new StructureAgave(), StructureType.FLOOR, 0.02F, true);
+ addStructure("barrel_cactus", new StructureBarrelCactus(), StructureType.FLOOR, 0.02F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ for (int i = 0; i < 1 + random.nextInt(3); i++) {
+ BlockPos p2 = pos.down(i);
+ if (BlocksHelper.isNetherGround(world.getBlockState(p2)))
+ if (world.isAirBlock(p2.down())) {
+ BlocksHelper.setWithoutUpdate(world, p2, Blocks.NETHERRACK.getDefaultState());
+ return;
+ }
+ else
+ BlocksHelper.setWithoutUpdate(world, p2, Blocks.GRAVEL.getDefaultState());
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherJungle.java b/src/main/java/redd90/betternether/biomes/NetherJungle.java
new file mode 100644
index 0000000..db6bde1
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherJungle.java
@@ -0,0 +1,75 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackVine;
+import redd90.betternether.structures.plants.StructureBloomingVine;
+import redd90.betternether.structures.plants.StructureEggPlant;
+import redd90.betternether.structures.plants.StructureEye;
+import redd90.betternether.structures.plants.StructureFeatherFern;
+import redd90.betternether.structures.plants.StructureGoldenVine;
+import redd90.betternether.structures.plants.StructureJellyfishMushroom;
+import redd90.betternether.structures.plants.StructureJungleMoss;
+import redd90.betternether.structures.plants.StructureJunglePlant;
+import redd90.betternether.structures.plants.StructureLucis;
+import redd90.betternether.structures.plants.StructureMagmaFlower;
+import redd90.betternether.structures.plants.StructureReeds;
+import redd90.betternether.structures.plants.StructureRubeus;
+import redd90.betternether.structures.plants.StructureRubeusBush;
+import redd90.betternether.structures.plants.StructureStalagnate;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallMoss;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+
+public class NetherJungle extends NetherBiome {
+ public NetherJungle(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(62, 169, 61)
+ .setLoop(SoundsRegistry.AMBIENT_NETHER_JUNGLE)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setDefaultMobs(false)
+ .addMobSpawn(EntityRegistry.JUNGLE_SKELETON, 40, 2, 4));
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.5F, false);
+ addStructure("stalagnate", new StructureStalagnate(), StructureType.FLOOR, 0.2F, false);
+ addStructure("rubeus_tree", new StructureRubeus(), StructureType.FLOOR, 0.1F, false);
+ addStructure("bush_rubeus", new StructureRubeusBush(), StructureType.FLOOR, 0.1F, false);
+ addStructure("magma_flower", new StructureMagmaFlower(), StructureType.FLOOR, 0.5F, false);
+ addStructure("egg_plant", new StructureEggPlant(), StructureType.FLOOR, 0.05F, true);
+ addStructure("jellyfish_mushroom", new StructureJellyfishMushroom(), StructureType.FLOOR, 0.03F, true);
+ addStructure("feather_fern", new StructureFeatherFern(), StructureType.FLOOR, 0.05F, true);
+ addStructure("jungle_plant", new StructureJunglePlant(), StructureType.FLOOR, 0.1F, false);
+ addStructure("lucis", new StructureLucis(), StructureType.WALL, 0.1F, false);
+ addStructure("eye", new StructureEye(), StructureType.CEIL, 0.1F, true);
+ addStructure("black_vine", new StructureBlackVine(), StructureType.CEIL, 0.1F, true);
+ addStructure("golden_vine", new StructureGoldenVine(), StructureType.CEIL, 0.1F, true);
+ addStructure("flowered_vine", new StructureBloomingVine(), StructureType.CEIL, 0.1F, true);
+ addStructure("jungle_moss", new StructureJungleMoss(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_moss", new StructureWallMoss(), StructureType.WALL, 0.2F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.8F, true);
+
+ addWorldStructures(structureFormat("ruined_temple", -4, StructureType.FLOOR, 10F));
+ addWorldStructures(structureFormat("jungle_temple_altar", -2, StructureType.FLOOR, 10F));
+ addWorldStructures(structureFormat("jungle_temple_2", -2, StructureType.FLOOR, 10F));
+
+ addWorldStructures(structureFormat("jungle_bones_1", 0, StructureType.FLOOR, 20F));
+ addWorldStructures(structureFormat("jungle_bones_2", 0, StructureType.FLOOR, 20F));
+ addWorldStructures(structureFormat("jungle_bones_3", 0, StructureType.FLOOR, 20F));
+
+ this.setNoiseDensity(0.5F);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.JUNGLE_GRASS.getDefaultState());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/NetherMagmaLand.java b/src/main/java/redd90/betternether/biomes/NetherMagmaLand.java
new file mode 100644
index 0000000..2de82ee
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherMagmaLand.java
@@ -0,0 +1,87 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.decorations.StructureCrystal;
+import redd90.betternether.structures.decorations.StructureGeyser;
+import redd90.betternether.structures.plants.StructureGoldenVine;
+import redd90.betternether.structures.plants.StructureMagmaFlower;
+
+public class NetherMagmaLand extends NetherBiome {
+ private static final Mutable POS = new Mutable();
+ private static final boolean[] MASK;
+
+ public NetherMagmaLand(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(248, 158, 68)
+ .setLoop(SoundEvents.AMBIENT_NETHER_WASTES_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_NETHER_WASTES_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_NETHER_WASTES_MOOD));
+ addStructure("geyser", new StructureGeyser(), StructureType.FLOOR, 0.1F, false);
+ addStructure("obsidian_crystals", new StructureCrystal(), StructureType.FLOOR, 0.04F, true);
+ addStructure("magma_flower", new StructureMagmaFlower(), StructureType.FLOOR, 0.4F, false);
+ addStructure("golden_vine", new StructureGoldenVine(), StructureType.CEIL, 0.2F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ if (isMask(pos.getX(), pos.getZ())) {
+ POS.setPos(pos);
+ boolean magma = true;
+ if (random.nextInt(4) == 0) {
+ if (validWall(world, POS.down()) && validWall(world, POS.north()) && validWall(world, POS.south()) && validWall(world, POS.east()) && validWall(world, POS.west())) {
+ BlocksHelper.setWithoutUpdate(world, POS, Blocks.LAVA.getDefaultState());
+ magma = false;
+ }
+ }
+ if (magma)
+ for (int y = 0; y < random.nextInt(3) + 1; y++) {
+ POS.setY(pos.getY() - y);
+ if (BlocksHelper.isNetherGround(world.getBlockState(POS)))
+ BlocksHelper.setWithoutUpdate(world, POS, Blocks.MAGMA_BLOCK.getDefaultState());
+ }
+ }
+ else
+ super.genSurfColumn(world, pos, random);
+ }
+
+ protected boolean validWall(IWorld world, BlockPos pos) {
+ BlockState state = world.getBlockState(pos);
+ return BlocksHelper.isLava(state) || BlocksHelper.isNetherGroundMagma(state);
+ }
+
+ protected boolean isMask(int x, int z) {
+ x &= 15;
+ z &= 15;
+ return MASK[(x << 4) | z];
+ }
+
+ static {
+ MASK = new boolean[] {
+ false, true, false, false, false, false, false, true, false, false, false, false, true, true, false, false,
+ false, false, false, false, false, false, false, true, false, false, false, false, true, true, false, false,
+ true, true, true, false, false, false, true, true, false, false, false, true, false, false, true, true,
+ true, false, false, true, true, true, true, false, true, true, true, true, false, false, false, true,
+ true, false, false, true, true, true, false, false, false, false, false, true, false, false, false, false,
+ true, false, false, false, true, false, false, false, false, false, false, false, true, false, false, false,
+ false, false, false, false, true, false, false, false, false, false, false, false, true, true, true, true,
+ true, false, false, false, true, true, true, true, false, false, false, true, true, false, true, true,
+ true, true, true, true, true, false, false, true, true, false, true, true, false, false, false, true,
+ false, false, true, false, false, false, false, false, true, true, true, false, false, false, false, true,
+ false, false, true, false, false, false, false, false, false, true, false, false, false, false, true, false,
+ false, false, true, true, false, false, false, false, false, true, false, false, false, false, true, false,
+ true, false, false, false, true, false, false, false, false, true, false, false, false, false, true, false,
+ true, true, false, false, true, false, false, false, true, true, true, true, true, true, false, true,
+ false, true, true, true, true, true, true, true, false, false, false, false, true, false, false, false,
+ false, true, true, false, false, false, true, false, false, false, false, false, true, true, false, false
+ };
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherMushroomForest.java b/src/main/java/redd90/betternether/biomes/NetherMushroomForest.java
new file mode 100644
index 0000000..5e8058b
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherMushroomForest.java
@@ -0,0 +1,53 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureGiantMold;
+import redd90.betternether.structures.plants.StructureGrayMold;
+import redd90.betternether.structures.plants.StructureLucis;
+import redd90.betternether.structures.plants.StructureMedBrownMushroom;
+import redd90.betternether.structures.plants.StructureMedRedMushroom;
+import redd90.betternether.structures.plants.StructureMushroomFir;
+import redd90.betternether.structures.plants.StructureOrangeMushroom;
+import redd90.betternether.structures.plants.StructureRedMold;
+import redd90.betternether.structures.plants.StructureVanillaMushroom;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+
+public class NetherMushroomForest extends NetherBiome {
+ public NetherMushroomForest(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(166, 38, 95)
+ .setLoop(SoundsRegistry.AMBIENT_MUSHROOM_FOREST)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.MYCELIUM, 0.1F)));
+ this.setNoiseDensity(0.5F);
+ addStructure("large_red_mushroom", new StructureMedRedMushroom(), StructureType.FLOOR, 0.12F, true);
+ addStructure("large_brown_mushroom", new StructureMedBrownMushroom(), StructureType.FLOOR, 0.12F, true);
+ addStructure("giant_mold", new StructureGiantMold(), StructureType.FLOOR, 0.12F, true);
+ addStructure("mushroom_fir", new StructureMushroomFir(), StructureType.FLOOR, 0.2F, true);
+ addStructure("vanilla_mushrooms", new StructureVanillaMushroom(), StructureType.FLOOR, 0.1F, false);
+ addStructure("orange_mushroom", new StructureOrangeMushroom(), StructureType.FLOOR, 0.05F, true);
+ addStructure("red_mold", new StructureRedMold(), StructureType.FLOOR, 0.5F, true);
+ addStructure("gray_mold", new StructureGrayMold(), StructureType.FLOOR, 0.5F, true);
+ addStructure("lucis", new StructureLucis(), StructureType.WALL, 0.05F, false);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.8F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHER_MYCELIUM.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherMushroomForestEdge.java b/src/main/java/redd90/betternether/biomes/NetherMushroomForestEdge.java
new file mode 100644
index 0000000..642e06d
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherMushroomForestEdge.java
@@ -0,0 +1,37 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureGrayMold;
+import redd90.betternether.structures.plants.StructureOrangeMushroom;
+import redd90.betternether.structures.plants.StructureRedMold;
+import redd90.betternether.structures.plants.StructureVanillaMushroom;
+
+public class NetherMushroomForestEdge extends NetherBiome {
+ public NetherMushroomForestEdge(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(200, 121, 157)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST));
+ addStructure("orange_mushroom", new StructureOrangeMushroom(), StructureType.FLOOR, 0.05F, true);
+ addStructure("vanilla_mushrooms", new StructureVanillaMushroom(), StructureType.FLOOR, 0.1F, false);
+ addStructure("red_mold", new StructureRedMold(), StructureType.FLOOR, 0.5F, false);
+ addStructure("gray_mold", new StructureGrayMold(), StructureType.FLOOR, 0.5F, false);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ if (random.nextInt(4) > 0)
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHER_MYCELIUM.getDefaultState());
+ else if (random.nextBoolean())
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHERRACK_MOSS.getDefaultState());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/NetherPoorGrasslands.java b/src/main/java/redd90/betternether/biomes/NetherPoorGrasslands.java
new file mode 100644
index 0000000..23e4df4
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherPoorGrasslands.java
@@ -0,0 +1,60 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackApple;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureInkBush;
+import redd90.betternether.structures.plants.StructureMagmaFlower;
+import redd90.betternether.structures.plants.StructureNetherGrass;
+import redd90.betternether.structures.plants.StructureNetherWart;
+import redd90.betternether.structures.plants.StructureReeds;
+import redd90.betternether.structures.plants.StructureSmoker;
+import redd90.betternether.structures.plants.StructureWartSeed;
+
+public class NetherPoorGrasslands extends NetherBiome {
+ public NetherPoorGrasslands(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(113, 73, 133)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD));
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.05F, false);
+ addStructure("nether_wart", new StructureNetherWart(), StructureType.FLOOR, 0.005F, true);
+ addStructure("magma_flower", new StructureMagmaFlower(), StructureType.FLOOR, 0.05F, true);
+ addStructure("smoker", new StructureSmoker(), StructureType.FLOOR, 0.005F, true);
+ addStructure("ink_bush", new StructureInkBush(), StructureType.FLOOR, 0.005F, true);
+ addStructure("black_apple", new StructureBlackApple(), StructureType.FLOOR, 0.001F, true);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.002F, true);
+ addStructure("wart_seed", new StructureWartSeed(), StructureType.FLOOR, 0.002F, true);
+ addStructure("nether_grass", new StructureNetherGrass(), StructureType.FLOOR, 0.04F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ switch (random.nextInt(3)) {
+ case 0:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SOIL.getDefaultState());
+ break;
+ case 1:
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHERRACK_MOSS.getDefaultState());
+ break;
+ default:
+ super.genSurfColumn(world, pos, random);
+ break;
+ }
+ for (int i = 1; i < random.nextInt(3); i++) {
+ BlockPos down = pos.down(i);
+ if (random.nextInt(3) == 0 && BlocksHelper.isNetherGround(world.getBlockState(down))) {
+ BlocksHelper.setWithoutUpdate(world, down, Blocks.SOUL_SAND.getDefaultState());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/NetherSoulPlain.java b/src/main/java/redd90/betternether/biomes/NetherSoulPlain.java
new file mode 100644
index 0000000..d9d4a98
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherSoulPlain.java
@@ -0,0 +1,63 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.BlockSoulSandstone;
+import redd90.betternether.noise.OpenSimplexNoise;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureSoulGrass;
+import redd90.betternether.structures.plants.StructureSoulVein;
+
+public class NetherSoulPlain extends NetherBiome {
+ private static final OpenSimplexNoise TERRAIN = new OpenSimplexNoise(245);
+ private static final Mutable POS = new Mutable();
+
+ public NetherSoulPlain(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(196, 113, 239)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.PORTAL, 0.02F)));
+ addStructure("soul_vein", new StructureSoulVein(), StructureType.FLOOR, 0.5F, true);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.02F, false);
+ addStructure("soul_grass", new StructureSoulGrass(), StructureType.FLOOR, 0.3F, false);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ POS.setPos(pos);
+ int d1 = MHelper.randRange(2, 4, random);
+
+ for (int i = 0; i < d1; i++) {
+ POS.setY(pos.getY() - i);
+ if (BlocksHelper.isNetherGround(world.getBlockState(POS)))
+ if (TERRAIN.eval(pos.getX() * 0.1, pos.getY() * 0.1, pos.getZ() * 0.1) > 0)
+ BlocksHelper.setWithoutUpdate(world, POS, Blocks.SOUL_SOIL.getDefaultState());
+ else
+ BlocksHelper.setWithoutUpdate(world, POS, Blocks.SOUL_SAND.getDefaultState());
+ else
+ return;
+ }
+
+ int d2 = MHelper.randRange(5, 7, random);
+ for (int i = d1; i < d2; i++) {
+ POS.setY(pos.getY() - i);
+ if (BlocksHelper.isNetherGround(world.getBlockState(POS)))
+ BlocksHelper.setWithoutUpdate(world, POS, BlocksRegistry.SOUL_SANDSTONE.getDefaultState().with(BlockSoulSandstone.UP, i == d1));
+ else
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/NetherSulfuricBoneReef.java b/src/main/java/redd90/betternether/biomes/NetherSulfuricBoneReef.java
new file mode 100644
index 0000000..44fcded
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherSulfuricBoneReef.java
@@ -0,0 +1,47 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.decorations.StructureStalactite;
+import redd90.betternether.structures.decorations.StructureStalagmite;
+import redd90.betternether.structures.plants.StructureBoneReef;
+import redd90.betternether.structures.plants.StructureGoldenLumabusVine;
+import redd90.betternether.structures.plants.StructureJellyfishMushroom;
+import redd90.betternether.structures.plants.StructureReeds;
+import redd90.betternether.structures.plants.StructureSepiaBoneGrass;
+
+public class NetherSulfuricBoneReef extends NetherBiome {
+ public NetherSulfuricBoneReef(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(154, 144, 49)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setStalactites(false)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.ASH, 0.01F)));
+
+ addStructure("bone_stalactite", new StructureStalagmite(BlocksRegistry.BONE_STALACTITE, BlocksRegistry.BONE_BLOCK), StructureType.FLOOR, 0.05F, true);
+
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.5F, false);
+ addStructure("bone_reef", new StructureBoneReef(), StructureType.FLOOR, 0.2F, true);
+ addStructure("jellyfish_mushroom", new StructureJellyfishMushroom(), StructureType.FLOOR, 0.02F, true);
+ addStructure("sulfuric_bone_grass", new StructureSepiaBoneGrass(), StructureType.FLOOR, 0.1F, false);
+
+ addStructure("bone_stalagmite", new StructureStalactite(BlocksRegistry.BONE_STALACTITE, BlocksRegistry.BONE_BLOCK), StructureType.CEIL, 0.05F, true);
+
+ addStructure("golden_lumabus_vine", new StructureGoldenLumabusVine(), StructureType.CEIL, 0.3F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.SEPIA_MUSHROOM_GRASS.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherSwampland.java b/src/main/java/redd90/betternether/biomes/NetherSwampland.java
new file mode 100644
index 0000000..c8c1681
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherSwampland.java
@@ -0,0 +1,83 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.entity.EntityType;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.noise.OpenSimplexNoise;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureBlackVine;
+import redd90.betternether.structures.plants.StructureFeatherFern;
+import redd90.betternether.structures.plants.StructureJellyfishMushroom;
+import redd90.betternether.structures.plants.StructureReeds;
+import redd90.betternether.structures.plants.StructureSmoker;
+import redd90.betternether.structures.plants.StructureSoulVein;
+import redd90.betternether.structures.plants.StructureSwampGrass;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallMoss;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+import redd90.betternether.structures.plants.StructureWillow;
+import redd90.betternether.structures.plants.StructureWillowBush;
+
+public class NetherSwampland extends NetherBiome {
+ protected static final OpenSimplexNoise TERRAIN = new OpenSimplexNoise(523);
+
+ public NetherSwampland(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(137, 19, 78)
+ .setLoop(SoundsRegistry.AMBIENT_SWAMPLAND)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .setDefaultMobs(false)
+ .addMobSpawn(EntityType.STRIDER, 40, 2, 4)
+ .addMobSpawn(EntityType.MAGMA_CUBE, 40, 2, 4));
+ addStructure("willow", new StructureWillow(), StructureType.FLOOR, 0.05F, false);
+ addStructure("willow_bush", new StructureWillowBush(), StructureType.FLOOR, 0.2F, true);
+ addStructure("feather_fern", new StructureFeatherFern(), StructureType.FLOOR, 0.05F, true);
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.8F, false);
+ addStructure("soul_vein", new StructureSoulVein(), StructureType.FLOOR, 0.5F, false);
+ addStructure("smoker", new StructureSmoker(), StructureType.FLOOR, 0.05F, false);
+ addStructure("jellyfish_mushroom", new StructureJellyfishMushroom(), StructureType.FLOOR, 0.03F, true);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.01F, false);
+ addStructure("swamp_grass", new StructureSwampGrass(), StructureType.FLOOR, 0.4F, false);
+ addStructure("black_vine", new StructureBlackVine(), StructureType.CEIL, 0.4F, true);
+ addStructure("wall_moss", new StructureWallMoss(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.8F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ double value = TERRAIN.eval(pos.getX() * 0.2, pos.getY() * 0.2, pos.getZ() * 0.2);
+ if (value > 0.3 && validWalls(world, pos))
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.LAVA.getDefaultState());
+ else if (value > -0.3)
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.SWAMPLAND_GRASS.getDefaultState());
+ else {
+ value = TERRAIN.eval(pos.getX() * 0.5, pos.getZ() * 0.5);
+ BlocksHelper.setWithoutUpdate(world, pos, value > 0 ? Blocks.SOUL_SAND.getDefaultState() : Blocks.SOUL_SOIL.getDefaultState());
+ }
+ }
+
+ protected boolean validWalls(IWorld world, BlockPos pos) {
+ return validWall(world, pos.down())
+ && validWall(world, pos.north())
+ && validWall(world, pos.south())
+ && validWall(world, pos.east())
+ && validWall(world, pos.west());
+ }
+
+ protected boolean validWall(IWorld world, BlockPos pos) {
+ BlockState state = world.getBlockState(pos);
+ return BlocksHelper.isLava(state) || BlocksHelper.isNetherGround(state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherSwamplandTerraces.java b/src/main/java/redd90/betternether/biomes/NetherSwamplandTerraces.java
new file mode 100644
index 0000000..330a99d
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherSwamplandTerraces.java
@@ -0,0 +1,31 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class NetherSwamplandTerraces extends NetherSwampland {
+ public NetherSwamplandTerraces(String name) {
+ super(name);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ if (validWall(world, pos.down()) && validWall(world, pos.north()) && validWall(world, pos.south()) && validWall(world, pos.east()) && validWall(world, pos.west())) {
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.LAVA.getDefaultState());
+ }
+ else {
+ double value = TERRAIN.eval(pos.getX() * 0.2, pos.getY() * 0.2, pos.getZ() * 0.2);
+ if (value > -0.3)
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.SWAMPLAND_GRASS.getDefaultState());
+ else {
+ value = TERRAIN.eval(pos.getX() * 0.5, pos.getZ() * 0.5);
+ BlocksHelper.setWithoutUpdate(world, pos, value > 0 ? Blocks.SOUL_SAND.getDefaultState() : Blocks.SOUL_SOIL.getDefaultState());
+ }
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherWartForest.java b/src/main/java/redd90/betternether/biomes/NetherWartForest.java
new file mode 100644
index 0000000..21b6d9b
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherWartForest.java
@@ -0,0 +1,95 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.BlockSoulSandstone;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureNetherWart;
+import redd90.betternether.structures.plants.StructureSoulLily;
+import redd90.betternether.structures.plants.StructureWartDeadwood;
+import redd90.betternether.structures.plants.StructureWartSeed;
+import redd90.betternether.structures.plants.StructureWartTree;
+
+public class NetherWartForest extends NetherBiome {
+ private static final Mutable POS = new Mutable();
+
+ public NetherWartForest(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(151, 6, 6)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.CRIMSON_SPORE, 0.05F))
+ .addMobSpawn(EntityRegistry.FLYING_PIG, 20, 2, 4));
+ this.setNoiseDensity(0.45F);
+ addStructure("wart_deadwood", new StructureWartDeadwood(), StructureType.FLOOR, 0.02F, false);
+ addStructure("wart_tree", new StructureWartTree(), StructureType.FLOOR, 0.1F, false);
+ addStructure("nether_wart", new StructureNetherWart(), StructureType.FLOOR, 0.2F, false);
+ addStructure("wart_seed", new StructureWartSeed(), StructureType.FLOOR, 0.05F, false);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.05F, false);
+ addStructure("soul_lily", new StructureSoulLily(), StructureType.FLOOR, 0.2F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ switch (random.nextInt(4)) {
+ case 0:
+ super.genSurfColumn(world, pos, random);
+ break;
+ case 1:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SAND.getDefaultState());
+ break;
+ case 2:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SOIL.getDefaultState());
+ break;
+ case 3:
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHERRACK_MOSS.getDefaultState());
+ break;
+ }
+
+ int d1 = MHelper.randRange(2, 4, random);
+ POS.setX(pos.getX());
+ POS.setZ(pos.getZ());
+
+ for (int i = 1; i < d1; i++) {
+ POS.setY(pos.getY() - i);
+ if (BlocksHelper.isNetherGround(world.getBlockState(POS))) {
+ switch (random.nextInt(3)) {
+ case 0:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SAND.getDefaultState());
+ break;
+ case 1:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SOIL.getDefaultState());
+ break;
+ case 2:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.NETHERRACK.getDefaultState());
+ break;
+ }
+ }
+ else
+ return;
+ }
+
+ int d2 = MHelper.randRange(5, 7, random);
+ for (int i = d1; i < d2; i++) {
+ POS.setY(pos.getY() - i);
+ if (BlocksHelper.isNetherGround(world.getBlockState(POS)))
+ BlocksHelper.setWithoutUpdate(world, POS, BlocksRegistry.SOUL_SANDSTONE.getDefaultState().with(BlockSoulSandstone.UP, i == d1));
+ else
+ return;
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/NetherWartForestEdge.java b/src/main/java/redd90/betternether/biomes/NetherWartForestEdge.java
new file mode 100644
index 0000000..c27ccb5
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/NetherWartForestEdge.java
@@ -0,0 +1,53 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureNetherWart;
+import redd90.betternether.structures.plants.StructureWartSeed;
+
+public class NetherWartForestEdge extends NetherBiome {
+ public NetherWartForestEdge(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(191, 28, 28)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .addMobSpawn(EntityRegistry.FLYING_PIG, 20, 2, 4));
+ addStructure("nether_wart", new StructureNetherWart(), StructureType.FLOOR, 0.02F, false);
+ addStructure("wart_seed", new StructureWartSeed(), StructureType.FLOOR, 0.01F, false);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.01F, false);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ switch (random.nextInt(3)) {
+ case 0:
+ super.genSurfColumn(world, pos, random);
+ break;
+ case 1:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SAND.getDefaultState());
+ break;
+ case 2:
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.SOUL_SOIL.getDefaultState());
+ break;
+ case 3:
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHERRACK_MOSS.getDefaultState());
+ break;
+ }
+ for (int i = 1; i < random.nextInt(3); i++) {
+ BlockPos down = pos.down(i);
+ if (random.nextInt(3) == 0 && BlocksHelper.isNetherGround(world.getBlockState(down)))
+ BlocksHelper.setWithoutUpdate(world, down, Blocks.SOUL_SAND.getDefaultState());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/OldFungiwoods.java b/src/main/java/redd90/betternether/biomes/OldFungiwoods.java
new file mode 100644
index 0000000..963deee
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/OldFungiwoods.java
@@ -0,0 +1,49 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureGrayMold;
+import redd90.betternether.structures.plants.StructureMedBrownMushroom;
+import redd90.betternether.structures.plants.StructureMedRedMushroom;
+import redd90.betternether.structures.plants.StructureOldBrownMushrooms;
+import redd90.betternether.structures.plants.StructureOldRedMushrooms;
+import redd90.betternether.structures.plants.StructureRedMold;
+import redd90.betternether.structures.plants.StructureVanillaMushroom;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+
+public class OldFungiwoods extends NetherBiome {
+ public OldFungiwoods(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(166, 38, 95)
+ .setLoop(SoundsRegistry.AMBIENT_MUSHROOM_FOREST)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.MYCELIUM, 0.1F)));
+ this.setNoiseDensity(0.5F);
+ addStructure("old_red_mushrooms", new StructureOldRedMushrooms(), StructureType.FLOOR, 0.1F, false);
+ addStructure("old_brown_mushrooms", new StructureOldBrownMushrooms(), StructureType.FLOOR, 0.1F, false);
+ addStructure("large_red_mushroom", new StructureMedRedMushroom(), StructureType.FLOOR, 0.12F, true);
+ addStructure("large_brown_mushroom", new StructureMedBrownMushroom(), StructureType.FLOOR, 0.12F, true);
+ addStructure("vanilla_mushrooms", new StructureVanillaMushroom(), StructureType.FLOOR, 0.5F, false);
+ addStructure("red_mold", new StructureRedMold(), StructureType.FLOOR, 0.9F, true);
+ addStructure("gray_mold", new StructureGrayMold(), StructureType.FLOOR, 0.9F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.9F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.9F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.NETHER_MYCELIUM.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/OldSwampland.java b/src/main/java/redd90/betternether/biomes/OldSwampland.java
new file mode 100644
index 0000000..1613eb0
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/OldSwampland.java
@@ -0,0 +1,85 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.entity.EntityType;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.noise.OpenSimplexNoise;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBlackBush;
+import redd90.betternether.structures.plants.StructureBlackVine;
+import redd90.betternether.structures.plants.StructureFeatherFern;
+import redd90.betternether.structures.plants.StructureJellyfishMushroom;
+import redd90.betternether.structures.plants.StructureOldWillow;
+import redd90.betternether.structures.plants.StructureReeds;
+import redd90.betternether.structures.plants.StructureSmoker;
+import redd90.betternether.structures.plants.StructureSoulVein;
+import redd90.betternether.structures.plants.StructureSwampGrass;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallMoss;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+import redd90.betternether.structures.plants.StructureWillow;
+import redd90.betternether.structures.plants.StructureWillowBush;
+
+public class OldSwampland extends NetherBiome {
+ protected static final OpenSimplexNoise TERRAIN = new OpenSimplexNoise(523);
+
+ public OldSwampland(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(137, 19, 78)
+ .setLoop(SoundsRegistry.AMBIENT_SWAMPLAND)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .setDefaultMobs(false)
+ .addMobSpawn(EntityType.STRIDER, 40, 2, 4)
+ .addMobSpawn(EntityType.MAGMA_CUBE, 40, 2, 4));
+ addStructure("old_willow", new StructureOldWillow(), StructureType.FLOOR, 0.02F, false);
+ addStructure("willow", new StructureWillow(), StructureType.FLOOR, 0.02F, false);
+ addStructure("willow_bush", new StructureWillowBush(), StructureType.FLOOR, 0.1F, true);
+ addStructure("feather_fern", new StructureFeatherFern(), StructureType.FLOOR, 0.05F, true);
+ addStructure("nether_reed", new StructureReeds(), StructureType.FLOOR, 0.8F, false);
+ addStructure("soul_vein", new StructureSoulVein(), StructureType.FLOOR, 0.5F, false);
+ addStructure("smoker", new StructureSmoker(), StructureType.FLOOR, 0.05F, false);
+ addStructure("jellyfish_mushroom", new StructureJellyfishMushroom(), StructureType.FLOOR, 0.03F, true);
+ addStructure("black_bush", new StructureBlackBush(), StructureType.FLOOR, 0.01F, false);
+ addStructure("swamp_grass", new StructureSwampGrass(), StructureType.FLOOR, 0.4F, false);
+ addStructure("black_vine", new StructureBlackVine(), StructureType.CEIL, 0.4F, true);
+ addStructure("wall_moss", new StructureWallMoss(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.8F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.8F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ double value = TERRAIN.eval(pos.getX() * 0.2, pos.getY() * 0.2, pos.getZ() * 0.2);
+ if (value > 0.3 && validWalls(world, pos))
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.LAVA.getDefaultState());
+ else if (value > -0.3)
+ BlocksHelper.setWithoutUpdate(world, pos, BlocksRegistry.SWAMPLAND_GRASS.getDefaultState());
+ else {
+ value = TERRAIN.eval(pos.getX() * 0.5, pos.getZ() * 0.5);
+ BlocksHelper.setWithoutUpdate(world, pos, value > 0 ? Blocks.SOUL_SAND.getDefaultState() : Blocks.SOUL_SOIL.getDefaultState());
+ }
+ }
+
+ protected boolean validWalls(IWorld world, BlockPos pos) {
+ return validWall(world, pos.down())
+ && validWall(world, pos.north())
+ && validWall(world, pos.south())
+ && validWall(world, pos.east())
+ && validWall(world, pos.west());
+ }
+
+ protected boolean validWall(IWorld world, BlockPos pos) {
+ BlockState state = world.getBlockState(pos);
+ return BlocksHelper.isLava(state) || BlocksHelper.isNetherGround(state);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/biomes/OldWarpedWoods.java b/src/main/java/redd90/betternether/biomes/OldWarpedWoods.java
new file mode 100644
index 0000000..fe0c1a3
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/OldWarpedWoods.java
@@ -0,0 +1,42 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.entity.EntityType;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.biome.ParticleEffectAmbience;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.plants.StructureBigWarpedTree;
+import redd90.betternether.structures.plants.StructureBlackVine;
+import redd90.betternether.structures.plants.StructureTwistedVines;
+import redd90.betternether.structures.plants.StructureWarpedFungus;
+import redd90.betternether.structures.plants.StructureWarpedRoots;
+
+public class OldWarpedWoods extends NetherBiome {
+ public OldWarpedWoods(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(26, 5, 26)
+ .setLoop(SoundEvents.AMBIENT_WARPED_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_WARPED_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_WARPED_FOREST_MOOD)
+ .setParticleConfig(new ParticleEffectAmbience(ParticleTypes.WARPED_SPORE, 0.025F))
+ .setDefaultMobs(false)
+ .addMobSpawn(EntityType.ENDERMAN, 1, 4, 4)
+ .addMobSpawn(EntityType.STRIDER, 60, 1, 2));
+ addStructure("big_warped_tree", new StructureBigWarpedTree(), StructureType.FLOOR, 0.1F, false);
+ addStructure("warped_fungus", new StructureWarpedFungus(), StructureType.FLOOR, 0.05F, true);
+ addStructure("warped_roots", new StructureWarpedRoots(), StructureType.FLOOR, 0.2F, true);
+ addStructure("twisted_vine", new StructureTwistedVines(), StructureType.FLOOR, 0.1F, true);
+ addStructure("black_vine", new StructureBlackVine(), StructureType.CEIL, 0.3F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, Blocks.WARPED_NYLIUM.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/biomes/UpsideDownForest.java b/src/main/java/redd90/betternether/biomes/UpsideDownForest.java
new file mode 100644
index 0000000..a153047
--- /dev/null
+++ b/src/main/java/redd90/betternether/biomes/UpsideDownForest.java
@@ -0,0 +1,58 @@
+package redd90.betternether.biomes;
+
+import java.util.Random;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.StructureType;
+import redd90.betternether.structures.decorations.StructureForestLitter;
+import redd90.betternether.structures.plants.StructureAnchorTree;
+import redd90.betternether.structures.plants.StructureAnchorTreeBranch;
+import redd90.betternether.structures.plants.StructureAnchorTreeRoot;
+import redd90.betternether.structures.plants.StructureCeilingMushrooms;
+import redd90.betternether.structures.plants.StructureHookMushroom;
+import redd90.betternether.structures.plants.StructureJungleMoss;
+import redd90.betternether.structures.plants.StructureMossCover;
+import redd90.betternether.structures.plants.StructureNeonEquisetum;
+import redd90.betternether.structures.plants.StructureNetherSakura;
+import redd90.betternether.structures.plants.StructureNetherSakuraBush;
+import redd90.betternether.structures.plants.StructureWallBrownMushroom;
+import redd90.betternether.structures.plants.StructureWallRedMushroom;
+import redd90.betternether.structures.plants.StructureWhisperingGourd;
+
+public class UpsideDownForest extends NetherBiome {
+ public UpsideDownForest(String name) {
+ super(new BiomeDefinition(name)
+ .setFogColor(111, 188, 111)
+ .setLoop(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP)
+ .setAdditions(SoundEvents.AMBIENT_CRIMSON_FOREST_ADDITIONS)
+ .setMood(SoundEvents.AMBIENT_CRIMSON_FOREST_MOOD)
+ .setMusic(SoundEvents.MUSIC_NETHER_CRIMSON_FOREST)
+ .setBNStructures(false)
+ .setStalactites(false));
+ this.setNoiseDensity(0.5F);
+ addStructure("anchor_tree", new StructureAnchorTree(), StructureType.CEIL, 0.2F, false);
+ addStructure("anchor_tree_root", new StructureAnchorTreeRoot(), StructureType.CEIL, 0.03F, false);
+ addStructure("anchor_tree_branch", new StructureAnchorTreeBranch(), StructureType.CEIL, 0.02F, true);
+ addStructure("nether_sakura", new StructureNetherSakura(), StructureType.CEIL, 0.01F, true);
+ addStructure("nether_sakura_bush", new StructureNetherSakuraBush(), StructureType.FLOOR, 0.01F, true);
+ addStructure("moss_cover", new StructureMossCover(), StructureType.FLOOR, 0.6F, false);
+ addStructure("jungle_moss", new StructureJungleMoss(), StructureType.WALL, 0.4F, true);
+ addStructure("wall_red_mushroom", new StructureWallRedMushroom(), StructureType.WALL, 0.4F, true);
+ addStructure("wall_brown_mushroom", new StructureWallBrownMushroom(), StructureType.WALL, 0.4F, true);
+ addStructure("forest_litter", new StructureForestLitter(), StructureType.FLOOR, 0.1F, false);
+ addStructure("ceiling_mushrooms", new StructureCeilingMushrooms(), StructureType.CEIL, 1F, false);
+ addStructure("neon_equisetum", new StructureNeonEquisetum(), StructureType.CEIL, 0.1F, true);
+ addStructure("hook_mushroom", new StructureHookMushroom(), StructureType.CEIL, 0.03F, true);
+ addStructure("whispering_gourd", new StructureWhisperingGourd(), StructureType.CEIL, 0.02F, true);
+ }
+
+ @Override
+ public void genSurfColumn(IWorld world, BlockPos pos, Random random) {
+ BlocksHelper.setWithoutUpdate(world, pos, random.nextInt(3) == 0 ? BlocksRegistry.NETHERRACK_MOSS.getDefaultState() : Blocks.NETHERRACK.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNBarStool.java b/src/main/java/redd90/betternether/blocks/BNBarStool.java
new file mode 100644
index 0000000..de00e72
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNBarStool.java
@@ -0,0 +1,21 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+
+public class BNBarStool extends BNChair {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+
+ public BNBarStool(Block block) {
+ super(block, 15);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BNBarrel.java b/src/main/java/redd90/betternether/blocks/BNBarrel.java
new file mode 100644
index 0000000..dceacef
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNBarrel.java
@@ -0,0 +1,86 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BarrelBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockRenderType;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.monster.piglin.PiglinTasks;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.stats.Stats;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Hand;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.registry.TileEntitiesRegistry;
+import redd90.betternether.tileentities.BNBarrelTileEntity;
+
+public class BNBarrel extends BarrelBlock {
+ public BNBarrel(Block source) {
+ super(AbstractBlock.Properties.from(source).notSolid());
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(IBlockReader world) {
+ return TileEntitiesRegistry.BARREL.create();
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ List drop = super.getDrops(state, builder);
+ drop.add(new ItemStack(this.asItem()));
+ return drop;
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (world.isRemote) {
+ return ActionResultType.SUCCESS;
+ }
+ else {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNBarrelTileEntity) {
+ player.openContainer((BNBarrelTileEntity) blockEntity);
+ player.addStat(Stats.OPEN_BARREL);
+ PiglinTasks.func_234478_a_(player, true);
+ }
+
+ return ActionResultType.CONSUME;
+ }
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNBarrelTileEntity) {
+ ((BNBarrelTileEntity) blockEntity).tick();
+ }
+ }
+
+ @Override
+ public BlockRenderType getRenderType(BlockState state) {
+ return BlockRenderType.MODEL;
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
+ if (itemStack.hasDisplayName()) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNBarrelTileEntity) {
+ ((BNBarrelTileEntity) blockEntity).setCustomName(itemStack.getDisplayName());
+ }
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNBoneBlock.java b/src/main/java/redd90/betternether/blocks/BNBoneBlock.java
new file mode 100644
index 0000000..ddcc29c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNBoneBlock.java
@@ -0,0 +1,21 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNBoneBlock extends BlockBase {
+ public BNBoneBlock() {
+ super(AbstractBlock.Properties.from(Blocks.BONE_BLOCK));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNBrewingStand.java b/src/main/java/redd90/betternether/blocks/BNBrewingStand.java
new file mode 100644
index 0000000..33d8a35
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNBrewingStand.java
@@ -0,0 +1,78 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.BrewingStandBlock;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.inventory.InventoryHelper;
+import net.minecraft.item.ItemStack;
+import net.minecraft.stats.Stats;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Hand;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import redd90.betternether.client.IRenderTypeable;
+import redd90.betternether.tileentities.BNBrewingStandTileEntity;
+
+public class BNBrewingStand extends BrewingStandBlock implements IRenderTypeable {
+ public BNBrewingStand() {
+ super(AbstractBlock.Properties.from(Blocks.NETHER_BRICKS)
+ .hardnessAndResistance(0.5F, 0.5F)
+ .setLightLevel((state) -> {return 1;})
+ .notSolid());
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(IBlockReader view) {
+ return new BNBrewingStandTileEntity();
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (world.isRemote) {
+ return ActionResultType.SUCCESS;
+ }
+ else {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNBrewingStandTileEntity) {
+ player.openContainer((BNBrewingStandTileEntity) blockEntity);
+ player.addStat(Stats.INTERACT_WITH_BREWINGSTAND);
+ }
+
+ return ActionResultType.SUCCESS;
+ }
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
+ if (itemStack.hasDisplayName()) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNBrewingStandTileEntity) {
+ ((BNBrewingStandTileEntity) blockEntity).setCustomName(itemStack.getDisplayName());
+ }
+ }
+ }
+
+ @Override
+ public void onReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean notify) {
+ if (!state.isIn(newState.getBlock())) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNBrewingStandTileEntity) {
+ InventoryHelper.dropInventoryItems(world, (BlockPos) pos, (IInventory) ((BNBrewingStandTileEntity) blockEntity));
+ }
+
+ super.onReplaced(state, world, pos, newState, notify);
+ }
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return BNRenderLayer.CUTOUT;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNButton.java b/src/main/java/redd90/betternether/blocks/BNButton.java
new file mode 100644
index 0000000..3535ea4
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNButton.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.WoodButtonBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNButton extends WoodButtonBlock {
+ public BNButton(Block block) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNChain.java b/src/main/java/redd90/betternether/blocks/BNChain.java
new file mode 100644
index 0000000..b0c4609
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNChain.java
@@ -0,0 +1,28 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.ChainBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import redd90.betternether.client.IRenderTypeable;
+
+public class BNChain extends ChainBlock implements IRenderTypeable {
+ public BNChain() {
+ super(AbstractBlock.Properties.from(Blocks.CHAIN));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return BNRenderLayer.CUTOUT;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BNChair.java b/src/main/java/redd90/betternether/blocks/BNChair.java
new file mode 100644
index 0000000..dc0094a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNChair.java
@@ -0,0 +1,95 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.function.Predicate;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Hand;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.world.World;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.entity.EntityChair;
+import redd90.betternether.registry.EntityRegistry;
+
+
+public class BNChair extends BlockBaseNotFull {
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+ private float height;
+
+ public BNChair(Block block, int height) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ this.height = (float) (height - 3F) / 16F;
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder StateContainer) {
+ StateContainer.add(FACING);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return this.getDefaultState().with(FACING, ctx.getPlacementHorizontalFacing().getOpposite());
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (world.isRemote) {
+ return ActionResultType.FAIL;
+ }
+ else {
+ if (player.isPassenger() || player.isSpectator())
+ return ActionResultType.FAIL;
+
+ double px = pos.getX() + 0.5;
+ double py = pos.getY() + height;
+ double pz = pos.getZ() + 0.5;
+
+ List active = world.getEntitiesWithinAABB(EntityChair.class, new AxisAlignedBB(pos), new Predicate() {
+ @Override
+ public boolean test(EntityChair entity) {
+ return entity.isOnePlayerRiding();
+ }
+ });
+ if (!active.isEmpty())
+ return ActionResultType.FAIL;
+
+ float yaw = state.get(FACING).getOpposite().getHorizontalAngle();
+ EntityChair entity = EntityRegistry.CHAIR.create(world);
+ entity.setLocationAndAngles(px, py, pz, yaw, 0);
+ entity.setNoGravity(true);
+ entity.setSilent(true);
+ entity.setInvisible(true);
+ entity.setRotationYawHead(yaw);
+ entity.setRenderYawOffset(yaw);
+ if (world.addEntity(entity)) {
+ player.startRiding(entity, true);
+ player.setRenderYawOffset(yaw);
+ player.setRotationYawHead(yaw);
+ return ActionResultType.SUCCESS;
+ }
+ return ActionResultType.FAIL;
+ }
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNChest.java b/src/main/java/redd90/betternether/blocks/BNChest.java
new file mode 100644
index 0000000..99645e4
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNChest.java
@@ -0,0 +1,34 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.ChestBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockReader;
+import redd90.betternether.registry.TileEntitiesRegistry;
+
+
+public class BNChest extends ChestBlock {
+ public BNChest(Block source) {
+ super(AbstractBlock.Properties.from(source).notSolid(), () -> {
+ return TileEntitiesRegistry.CHEST;
+ });
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(IBlockReader world) {
+ return TileEntitiesRegistry.CHEST.create();
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ List drop = super.getDrops(state, builder);
+ drop.add(new ItemStack(this.asItem()));
+ return drop;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNCraftingTable.java b/src/main/java/redd90/betternether/blocks/BNCraftingTable.java
new file mode 100644
index 0000000..7d6277d
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNCraftingTable.java
@@ -0,0 +1,29 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.CraftingTableBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import redd90.betternether.client.IRenderTypeable;
+
+
+public class BNCraftingTable extends CraftingTableBlock implements IRenderTypeable {
+ public BNCraftingTable(Block block) {
+ super(AbstractBlock.Properties.from(block));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return BNRenderLayer.CUTOUT;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNDoor.java b/src/main/java/redd90/betternether/blocks/BNDoor.java
new file mode 100644
index 0000000..1ee4fce
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNDoor.java
@@ -0,0 +1,33 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.DoorBlock;
+import net.minecraft.block.material.Material;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.properties.DoubleBlockHalf;
+import redd90.betternether.client.IRenderTypeable;
+
+public class BNDoor extends DoorBlock implements IRenderTypeable {
+ public BNDoor(Block block) {
+ super(AbstractBlock.Properties.create(Material.NETHER_WOOD).sound(block.getSoundType(block.getDefaultState())).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (state.get(HALF) == DoubleBlockHalf.LOWER)
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return Collections.emptyList();
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return BNRenderLayer.CUTOUT;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNFence.java b/src/main/java/redd90/betternether/blocks/BNFence.java
new file mode 100644
index 0000000..ba7eedf
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNFence.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.FenceBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNFence extends FenceBlock {
+ public BNFence(Block block) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNGate.java b/src/main/java/redd90/betternether/blocks/BNGate.java
new file mode 100644
index 0000000..3f96e5a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNGate.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.FenceGateBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNGate extends FenceGateBlock {
+ public BNGate(Block block) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNGlass.java b/src/main/java/redd90/betternether/blocks/BNGlass.java
new file mode 100644
index 0000000..761229a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNGlass.java
@@ -0,0 +1,44 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.ToolType;
+
+public class BNGlass extends BlockBaseNotFull {
+ public BNGlass(Block block) {
+ super(AbstractBlock.Properties.from(block)
+ .harvestTool(ToolType.PICKAXE)
+ .hardnessAndResistance(0.3F)
+ .notSolid()
+ .setSuffocates((arg1, arg2, arg3) -> {
+ return false;
+ })
+ .setBlocksVision((arg1, arg2, arg3) -> {
+ return false;
+ }));
+ this.setRenderLayer(BNRenderLayer.TRANSLUCENT);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public boolean isSideInvisible(BlockState state, BlockState neighbor, Direction facing) {
+ return neighbor.getBlock() == this ? true : super.isSideInvisible(state, neighbor, facing);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BNLadder.java b/src/main/java/redd90/betternether/blocks/BNLadder.java
new file mode 100644
index 0000000..00a979b
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNLadder.java
@@ -0,0 +1,128 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.fluid.FluidState;
+import net.minecraft.fluid.Fluids;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.BlocksHelper;
+
+public class BNLadder extends BlockBaseNotFull {
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+ public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
+ protected static final VoxelShape EAST_SHAPE = Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D);
+ protected static final VoxelShape WEST_SHAPE = Block.makeCuboidShape(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D);
+ protected static final VoxelShape SOUTH_SHAPE = Block.makeCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D);
+ protected static final VoxelShape NORTH_SHAPE = Block.makeCuboidShape(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D);
+
+ public BNLadder(Block block) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING);
+ stateManager.add(WATERLOGGED);
+ }
+
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ switch (state.get(FACING)) {
+ case NORTH:
+ return NORTH_SHAPE;
+ case SOUTH:
+ return SOUTH_SHAPE;
+ case WEST:
+ return WEST_SHAPE;
+ case EAST:
+ default:
+ return EAST_SHAPE;
+ }
+ }
+
+ private boolean canPlaceOn(IBlockReader world, BlockPos pos, Direction side) {
+ BlockState blockState = world.getBlockState(pos);
+ return !blockState.canProvidePower() && blockState.isSolidSide(world, pos, side);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING);
+ return this.canPlaceOn(world, pos.offset(direction.getOpposite()), direction);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (facing.getOpposite() == state.get(FACING) && !state.isValidPosition(world, pos)) {
+ return Blocks.AIR.getDefaultState();
+ }
+ else {
+ if ((Boolean) state.get(WATERLOGGED)) {
+ world .getPendingFluidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
+ }
+
+ return super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos);
+ }
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState2;
+ if (!ctx.replacingClickedOnBlock()) {
+ blockState2 = ctx.getWorld().getBlockState(ctx.getPos().offset(ctx.getFace().getOpposite()));
+ if (blockState2.getBlock() == this && blockState2.get(FACING) == ctx.getFace()) {
+ return null;
+ }
+ }
+
+ blockState2 = this.getDefaultState();
+ IWorldReader worldView = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ FluidState fluidState = ctx.getWorld().getFluidState(ctx.getPos());
+ Direction[] var6 = ctx.getNearestLookingDirections();
+ int var7 = var6.length;
+
+ for (int var8 = 0; var8 < var7; ++var8) {
+ Direction direction = var6[var8];
+ if (direction.getAxis().isHorizontal()) {
+ blockState2 = (BlockState) blockState2.with(FACING, direction.getOpposite());
+ if (blockState2.isValidPosition(worldView, blockPos)) {
+ return (BlockState) blockState2.with(WATERLOGGED, fluidState.getFluid() == Fluids.WATER);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public FluidState getFluidState(BlockState state) {
+ return (Boolean) state.get(WATERLOGGED) ? Fluids.WATER.getStillFluidState(false) : super.getFluidState(state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNLogStripable.java b/src/main/java/redd90/betternether/blocks/BNLogStripable.java
new file mode 100644
index 0000000..05f3db7
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNLogStripable.java
@@ -0,0 +1,46 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.RotatedPillarBlock;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Hand;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.world.World;
+import net.minecraftforge.common.ToolType;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BNLogStripable extends BNPillar {
+ Block result;
+
+ public BNLogStripable(Block source, Block result) {
+ super(source);
+ this.result = result;
+ }
+
+ public BNLogStripable(MaterialColor color, Block result) {
+ super(MaterialBuilder.makeWood(MaterialColor.LIME_TERRACOTTA));
+ this.result = result;
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (player.getHeldItemMainhand().getToolTypes().contains(ToolType.AXE)) {
+ world.playSound(player, pos, SoundEvents.ITEM_AXE_STRIP, SoundCategory.BLOCKS, 1.0F, 1.0F);
+ if (!world.isRemote) {
+ world.setBlockState(pos, result.getDefaultState().with(RotatedPillarBlock.AXIS, state.get(RotatedPillarBlock.AXIS)), 11);
+ if (player != null && !player.isCreative()) {
+ player.getHeldItemMainhand().attemptDamageItem(1, world.rand, (ServerPlayerEntity) player);
+ }
+ }
+ return ActionResultType.SUCCESS;
+ }
+ return ActionResultType.FAIL;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNNetherBrick.java b/src/main/java/redd90/betternether/blocks/BNNetherBrick.java
new file mode 100644
index 0000000..9b78d94
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNNetherBrick.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Blocks;
+
+public class BNNetherBrick extends BlockBase {
+ public BNNetherBrick() {
+ super(AbstractBlock.Properties.from(Blocks.NETHER_BRICKS));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BNNormalChair.java b/src/main/java/redd90/betternether/blocks/BNNormalChair.java
new file mode 100644
index 0000000..f4ec9b9
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNNormalChair.java
@@ -0,0 +1,104 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+
+public class BNNormalChair extends BNChair {
+ private static final VoxelShape SHAPE_BOTTOM = Block.makeCuboidShape(3, 0, 3, 13, 16, 13);
+ private static final VoxelShape SHAPE_TOP = Block.makeCuboidShape(3, 0, 3, 13, 6, 13);
+ private static final VoxelShape COLLIDER = Block.makeCuboidShape(3, 0, 3, 13, 10, 13);
+ public static final BooleanProperty TOP = BooleanProperty.create("top");
+
+ public BNNormalChair(Block block) {
+ super(block, 10);
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.NORTH).with(TOP, false));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING, TOP);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(TOP) ? SHAPE_TOP : SHAPE_BOTTOM;
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(TOP) ? VoxelShapes.empty() : COLLIDER;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ if (state.get(TOP))
+ return true;
+ BlockState up = world.getBlockState(pos.up());
+ return up.isAir() || (up.getBlock() == this && up.get(TOP));
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
+ if (!world.isRemote())
+ BlocksHelper.setWithUpdate((ServerWorld) world, pos.up(), state.with(TOP, true));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (state.get(TOP)) {
+ return world.getBlockState(pos.down()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ else {
+ return world.getBlockState(pos.up()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (!state.get(TOP))
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return Collections.emptyList();
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (state.get(TOP)) {
+ pos = pos.down();
+ state = world.getBlockState(pos);
+ }
+ return super.onBlockActivated(state, world, pos, player, hand, hit);
+ }
+
+ @Override
+ public void onBlockHarvested(World world, BlockPos pos, BlockState state, PlayerEntity player) {
+ if (player.isCreative() && state.get(TOP) && world.getBlockState(pos.down()).getBlock() == this) {
+ world.setBlockState(pos.down(), Blocks.AIR.getDefaultState());
+ }
+ super.onBlockHarvested(world, pos, state, player);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNObsidian.java b/src/main/java/redd90/betternether/blocks/BNObsidian.java
new file mode 100644
index 0000000..9aae807
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNObsidian.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Blocks;
+
+public class BNObsidian extends BlockBase {
+ public BNObsidian() {
+ super(AbstractBlock.Properties.from(Blocks.OBSIDIAN));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNPane.java b/src/main/java/redd90/betternether/blocks/BNPane.java
new file mode 100644
index 0000000..552345a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNPane.java
@@ -0,0 +1,52 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.PaneBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.util.Direction;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.client.IRenderTypeable;
+
+public class BNPane extends PaneBlock implements IRenderTypeable {
+ private boolean dropSelf;
+
+ public BNPane(Block block, boolean dropSelf) {
+ super(AbstractBlock.Properties.from(block).hardnessAndResistance(0.3F, 0.3F).notSolid());
+ this.dropSelf = dropSelf;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (dropSelf)
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return super.getDrops(state, builder);
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return BNRenderLayer.TRANSLUCENT;
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public boolean isSideInvisible(BlockState state, BlockState neighbor, Direction facing) {
+ if (neighbor.getBlock() == this) {
+ if (!facing.getAxis().isHorizontal()) {
+ return false;
+ }
+
+ if (state.get(FACING_TO_PROPERTY_MAP.get(facing)) && neighbor.get(FACING_TO_PROPERTY_MAP.get(facing.getOpposite()))) {
+ return true;
+ }
+ }
+
+ return super.isSideInvisible(state, neighbor, facing);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNPillar.java b/src/main/java/redd90/betternether/blocks/BNPillar.java
new file mode 100644
index 0000000..0f0e62b
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNPillar.java
@@ -0,0 +1,32 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.RotatedPillarBlock;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BNPillar extends RotatedPillarBlock {
+ public BNPillar(AbstractBlock.Properties settings) {
+ super(settings);
+ }
+
+ public BNPillar(Block block) {
+ super(AbstractBlock.Properties.from(block));
+ }
+
+ public BNPillar(MaterialColor color) {
+ super(MaterialBuilder.makeWood(color));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNPlanks.java b/src/main/java/redd90/betternether/blocks/BNPlanks.java
new file mode 100644
index 0000000..f97e3aa
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNPlanks.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BNPlanks extends BlockBase {
+ public BNPlanks(MaterialColor color) {
+ super(MaterialBuilder.makeWood(color));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNPlate.java b/src/main/java/redd90/betternether/blocks/BNPlate.java
new file mode 100644
index 0000000..90dc37b
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNPlate.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.PressurePlateBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNPlate extends PressurePlateBlock {
+ public BNPlate(Sensitivity type, Block block) {
+ super(type, AbstractBlock.Properties.from(block).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNRenderLayer.java b/src/main/java/redd90/betternether/blocks/BNRenderLayer.java
new file mode 100644
index 0000000..7c94bfd
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNRenderLayer.java
@@ -0,0 +1,5 @@
+package redd90.betternether.blocks;
+
+public enum BNRenderLayer {
+ SOLID, CUTOUT, TRANSLUCENT;
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNSign.java b/src/main/java/redd90/betternether/blocks/BNSign.java
new file mode 100644
index 0000000..0c72d7d
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNSign.java
@@ -0,0 +1,157 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.AbstractSignBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.WoodType;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.fluid.FluidState;
+import net.minecraft.fluid.Fluids;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.item.DyeItem;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.network.play.server.SOpenSignMenuPacket;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.IntegerProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import redd90.betternether.tileentities.BNSignTileEntity;
+
+public class BNSign extends AbstractSignBlock {
+ public static final IntegerProperty ROTATION = BlockStateProperties.ROTATION_0_15;
+ public static final BooleanProperty FLOOR = BooleanProperty.create("floor");
+ private static final VoxelShape[] WALL_SHAPES = new VoxelShape[] {
+ Block.makeCuboidShape(0.0D, 4.5D, 14.0D, 16.0D, 12.5D, 16.0D),
+ Block.makeCuboidShape(0.0D, 4.5D, 0.0D, 2.0D, 12.5D, 16.0D),
+ Block.makeCuboidShape(0.0D, 4.5D, 0.0D, 16.0D, 12.5D, 2.0D),
+ Block.makeCuboidShape(14.0D, 4.5D, 0.0D, 16.0D, 12.5D, 16.0D)
+ };
+
+ public BNSign(Block source) {
+ super(AbstractBlock.Properties.from(source).doesNotBlockMovement().notSolid(), WoodType.OAK);
+ this.setDefaultState(this.stateContainer.getBaseState().with(ROTATION, 0).with(FLOOR, true).with(WATERLOGGED, false));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder builder) {
+ builder.add(ROTATION, FLOOR, WATERLOGGED);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(FLOOR) ? SHAPE : WALL_SHAPES[state.get(ROTATION) >> 2];
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(IBlockReader world) {
+ return new BNSignTileEntity();
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ ItemStack itemStack = player.getHeldItem(hand);
+ boolean bl = itemStack.getItem() instanceof DyeItem && player.abilities.allowEdit;
+ if (world.isRemote) {
+ return bl ? ActionResultType.SUCCESS : ActionResultType.CONSUME;
+ }
+ else {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof BNSignTileEntity) {
+ BNSignTileEntity signBlockEntity = (BNSignTileEntity) blockEntity;
+ if (bl) {
+ boolean bl2 = signBlockEntity.setTextColor(((DyeItem) itemStack.getItem()).getDyeColor());
+ if (bl2 && !player.isCreative()) {
+ itemStack.shrink(1);
+ }
+ }
+ return signBlockEntity.onActivate(player) ? ActionResultType.SUCCESS : ActionResultType.PASS;
+ }
+ else {
+ return ActionResultType.PASS;
+ }
+ }
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
+ if (placer != null && placer instanceof PlayerEntity) {
+ BNSignTileEntity sign = (BNSignTileEntity) world.getTileEntity(pos);
+ if (!world.isRemote) {
+ sign.setEditor((PlayerEntity) placer);
+ ((ServerPlayerEntity) placer).connection.sendPacket(new SOpenSignMenuPacket(pos));
+ }
+ else
+ sign.setEditable(true);
+ }
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if ((Boolean) state.get(WATERLOGGED)) {
+ world.getPendingFluidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
+ }
+
+ return super.updatePostPlacement(state, facing, neighborState, world, pos, neighborPos);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ if (ctx.getFace() == Direction.UP) {
+ FluidState fluidState = ctx.getWorld().getFluidState(ctx.getPos());
+ return this.getDefaultState()
+ .with(FLOOR, true)
+ .with(ROTATION, MathHelper.floor((180.0 + ctx.getPlacementYaw() * 16.0 / 360.0) + 0.5 - 12) & 15)
+ .with(WATERLOGGED, fluidState.getFluid() == Fluids.WATER);
+ }
+ else if (ctx.getFace() != Direction.DOWN) {
+ BlockState blockState = this.getDefaultState();
+ FluidState fluidState = ctx.getWorld().getFluidState(ctx.getPos());
+ IWorldReader worldView = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ Direction[] var7 = directions;
+ int var8 = directions.length;
+
+ for (int var9 = 0; var9 < var8; ++var9) {
+ Direction direction = var7[var9];
+ if (direction.getAxis().isHorizontal()) {
+ Direction direction2 = direction.getOpposite();
+ int rot = MathHelper.floor((180.0 + direction2.getHorizontalAngle() * 16.0 / 360.0) + 0.5 + 4) & 15;
+ blockState = blockState.with(ROTATION, rot);
+ if (blockState.isValidPosition(worldView, blockPos)) {
+ return blockState.with(FLOOR, false).with(WATERLOGGED, fluidState.getFluid() == Fluids.WATER);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BNSlab.java b/src/main/java/redd90/betternether/blocks/BNSlab.java
new file mode 100644
index 0000000..dc9afd3
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNSlab.java
@@ -0,0 +1,23 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.SlabBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.properties.SlabType;
+
+public class BNSlab extends SlabBlock {
+ public BNSlab(Block block) {
+ super(AbstractBlock.Properties.from(block));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem(), state.get(TYPE) == SlabType.DOUBLE ? 2 : 1));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BNStairs.java b/src/main/java/redd90/betternether/blocks/BNStairs.java
new file mode 100644
index 0000000..8717ea9
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNStairs.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.StairsBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNStairs extends StairsBlock {
+ public BNStairs(Block block) {
+ super(() -> block.getDefaultState(), AbstractBlock.Properties.from(block));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNTaburet.java b/src/main/java/redd90/betternether/blocks/BNTaburet.java
new file mode 100644
index 0000000..e7f9857
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNTaburet.java
@@ -0,0 +1,21 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+
+public class BNTaburet extends BNChair {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 10, 14);
+
+ public BNTaburet(Block block) {
+ super(block, 9);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNTrapdoor.java b/src/main/java/redd90/betternether/blocks/BNTrapdoor.java
new file mode 100644
index 0000000..348ac75
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNTrapdoor.java
@@ -0,0 +1,28 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.TrapDoorBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import redd90.betternether.client.IRenderTypeable;
+
+public class BNTrapdoor extends TrapDoorBlock implements IRenderTypeable {
+ public BNTrapdoor(Block block) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return BNRenderLayer.CUTOUT;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BNWall.java b/src/main/java/redd90/betternether/blocks/BNWall.java
new file mode 100644
index 0000000..436afef
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BNWall.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.WallBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+
+public class BNWall extends WallBlock {
+ public BNWall(Block block) {
+ super(AbstractBlock.Properties.from(block).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockAgave.java b/src/main/java/redd90/betternether/blocks/BlockAgave.java
new file mode 100644
index 0000000..8780c4c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockAgave.java
@@ -0,0 +1,81 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.Entity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.ItemsRegistry;
+
+public class BlockAgave extends BlockCommonPlant {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 14, 14);
+
+ public BlockAgave() {
+ super(AbstractBlock.Properties.create(Material.CACTUS, MaterialColor.ORANGE_TERRACOTTA)
+ .sound(SoundType.CLOTH)
+ .notSolid()
+ .doesNotBlockMovement()
+ .hardnessAndResistance(0.4F)
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ public Block.OffsetType getOffsetType() {
+ return Block.OffsetType.XZ;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Block down = world.getBlockState(pos.down()).getBlock();
+ return down == Blocks.GRAVEL;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
+ if (state.get(BlockCommonPlant.AGE) > 1) entity.attackEntityFrom(DamageSource.CACTUS, 1.0F);
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (state.get(BlockCommonPlant.AGE) == 3) {
+ return Lists.newArrayList(new ItemStack(this, MHelper.randRange(1, 2, MHelper.RANDOM)), new ItemStack(ItemsRegistry.AGAVE_LEAF, MHelper.randRange(2, 5, MHelper.RANDOM)));
+ }
+ return Lists.newArrayList(new ItemStack(this));
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockAnchorTreeLeaves.java b/src/main/java/redd90/betternether/blocks/BlockAnchorTreeLeaves.java
new file mode 100644
index 0000000..3af4e11
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockAnchorTreeLeaves.java
@@ -0,0 +1,65 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockAnchorTreeLeaves extends BlockBaseNotFull {
+ private Random random = new Random();
+
+ public BlockAnchorTreeLeaves() {
+ super(MaterialBuilder.makeLeaves(MaterialColor.GREEN));
+ this.setDropItself(false);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ public AbstractBlock.OffsetType getOffsetType() {
+ return AbstractBlock.OffsetType.XZ;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos) {
+ return VoxelShapes.empty();
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.getItem().isIn(Tags.Items.SHEARS) || EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ }
+ else {
+ return random.nextInt(5) == 0 ? Lists.newArrayList(new ItemStack(BlocksRegistry.ANCHOR_TREE_SAPLING)) : super.getDrops(state, builder);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockAnchorTreeSapling.java b/src/main/java/redd90/betternether/blocks/BlockAnchorTreeSapling.java
new file mode 100644
index 0000000..08762fb
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockAnchorTreeSapling.java
@@ -0,0 +1,80 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureAnchorTreeBranch;
+
+public class BlockAnchorTreeSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 2, 4, 12, 16, 12);
+ private static final StructureAnchorTreeBranch STRUCTURE = new StructureAnchorTreeBranch();
+
+ public BlockAnchorTreeSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.LIME)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly()
+ .setLightLevel((state) -> {return 10;}));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherrack(world.getBlockState(pos.up()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return random.nextInt(16) == 0;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.grow(world, pos, random, false);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockAnchorTreeVine.java b/src/main/java/redd90/betternether/blocks/BlockAnchorTreeVine.java
new file mode 100644
index 0000000..b1da2d1
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockAnchorTreeVine.java
@@ -0,0 +1,90 @@
+package redd90.betternether.blocks;
+
+import java.util.function.ToIntFunction;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.BlocksRegistry;
+
+
+public class BlockAnchorTreeVine extends BlockBaseNotFull {
+ protected static final VoxelShape SHAPE_SELECTION = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockAnchorTreeVine() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.GREEN)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .notSolid()
+ .setLightLevel(getLuminance()));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ setDropItself(false);
+ }
+
+ protected static ToIntFunction getLuminance() {
+ return (state) -> {
+ return state.get(SHAPE) == TripleShape.BOTTOM ? 15 : 0;
+ };
+ }
+
+ public AbstractBlock.OffsetType getOffsetType() {
+ return AbstractBlock.OffsetType.XZ;
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE_SELECTION.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ Block up = world.getBlockState(pos.up()).getBlock();
+ if (up != this && up != BlocksRegistry.ANCHOR_TREE_LEAVES && up != Blocks.NETHERRACK)
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.ANCHOR_TREE_LEAVES);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockBNPot.java b/src/main/java/redd90/betternether/blocks/BlockBNPot.java
new file mode 100644
index 0000000..d1a1a46
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBNPot.java
@@ -0,0 +1,63 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+
+public class BlockBNPot extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(3, 0, 3, 13, 8, 13);
+
+ public BlockBNPot(Block material) {
+ super(AbstractBlock.Properties.from(material).notSolid());
+ }
+
+ @Override
+ public boolean isTransparent(BlockState state) {
+ return true;
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ BlockPos plantPos = pos.up();
+ if (hit.getFace() == Direction.UP && world.isAirBlock(plantPos)) {
+ BlockState plant = BlockPottedPlant.getPlant(player.getHeldItemMainhand().getItem());
+ if (plant != null) {
+ if (!world.isRemote())
+ BlocksHelper.setWithUpdate((ServerWorld) world, plantPos, plant);
+ world.playSound(
+ pos.getX() + 0.5,
+ pos.getY() + 1.5,
+ pos.getZ() + 0.5,
+ SoundEvents.ITEM_CROP_PLANT,
+ SoundCategory.BLOCKS,
+ 0.8F,
+ 1.0F,
+ true);
+ if (!player.isCreative())
+ player.getHeldItemMainhand().shrink(1);
+ return ActionResultType.SUCCESS;
+ }
+ }
+ return ActionResultType.FAIL;
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockBarrelCactus.java b/src/main/java/redd90/betternether/blocks/BlockBarrelCactus.java
new file mode 100644
index 0000000..6134912
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBarrelCactus.java
@@ -0,0 +1,91 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.Entity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import redd90.betternether.MHelper;
+
+public class BlockBarrelCactus extends BlockCommonPlant implements IGrowable {
+ private static final VoxelShape EMPTY = Block.makeCuboidShape(0, 0, 0, 0, 0, 0);
+ private static final VoxelShape[] SHAPES = new VoxelShape[] {
+ Block.makeCuboidShape(5, 0, 5, 11, 5, 11),
+ Block.makeCuboidShape(3, 0, 3, 13, 9, 13),
+ Block.makeCuboidShape(2, 0, 2, 14, 12, 14),
+ Block.makeCuboidShape(1, 0, 1, 15, 14, 15)
+ };
+
+ public BlockBarrelCactus() {
+ super(AbstractBlock.Properties.create(Material.CACTUS, MaterialColor.BLUE_TERRACOTTA)
+ .sound(SoundType.CLOTH)
+ .notSolid()
+ .hardnessAndResistance(0.4F)
+ .tickRandomly());
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Block down = world.getBlockState(pos.down()).getBlock();
+ return down == Blocks.GRAVEL;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
+ if (state.get(BlockCommonPlant.AGE) > 1) entity.attackEntityFrom(DamageSource.CACTUS, 1.0F);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPES[state.get(BlockCommonPlant.AGE)].withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ if (state.get(BlockCommonPlant.AGE) < 2) return EMPTY;
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPES[state.get(BlockCommonPlant.AGE)].withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ public Block.OffsetType getOffsetType() {
+ return Block.OffsetType.XYZ;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (state.get(BlockCommonPlant.AGE) == 3) {
+ return Lists.newArrayList(new ItemStack(this, MHelper.randRange(1, 3, MHelper.RANDOM)));
+ }
+ return Lists.newArrayList(new ItemStack(this));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockBase.java b/src/main/java/redd90/betternether/blocks/BlockBase.java
new file mode 100644
index 0000000..a9f40df
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBase.java
@@ -0,0 +1,45 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import redd90.betternether.client.IRenderTypeable;
+
+public class BlockBase extends Block implements IRenderTypeable {
+ private boolean dropItself = true;
+ private BNRenderLayer layer = BNRenderLayer.SOLID;
+
+ public BlockBase(AbstractBlock.Properties settings) {
+ super(settings);
+ }
+
+ public void setRenderLayer(BNRenderLayer layer) {
+ this.layer = layer;
+ }
+
+ @Override
+ public BNRenderLayer getRenderLayer() {
+ return layer;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (dropItself)
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return super.getDrops(state, builder);
+ }
+
+ public void setDropItself(boolean drop) {
+ this.dropItself = drop;
+ }
+
+ /*
+ * public int getLuminance(BlockState state) { return 0; }
+ */
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockBaseNotFull.java b/src/main/java/redd90/betternether/blocks/BlockBaseNotFull.java
new file mode 100644
index 0000000..e620252
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBaseNotFull.java
@@ -0,0 +1,26 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.EntityType;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+
+public class BlockBaseNotFull extends BlockBase {
+
+ public BlockBaseNotFull(AbstractBlock.Properties settings) {
+ super(settings);
+ }
+
+ public boolean canSuffocate(BlockState state, IBlockReader view, BlockPos pos) {
+ return false;
+ }
+
+ public boolean isSimpleFullBlock(BlockState state, IBlockReader view, BlockPos pos) {
+ return false;
+ }
+
+ public boolean allowsSpawning(BlockState state, IBlockReader view, BlockPos pos, EntityType> type) {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockBlackApple.java b/src/main/java/redd90/betternether/blocks/BlockBlackApple.java
new file mode 100644
index 0000000..93ce41e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBlackApple.java
@@ -0,0 +1,32 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockBlackApple extends BlockCommonPlant {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+
+ public BlockBlackApple() {
+ super(MaterialColor.ORANGE_TERRACOTTA);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.BLACK_APPLE_SEED);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockBlackAppleSeed.java b/src/main/java/redd90/betternether/blocks/BlockBlackAppleSeed.java
new file mode 100644
index 0000000..1f1a4e1
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBlackAppleSeed.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockBlackAppleSeed extends BlockCommonSapling {
+ public BlockBlackAppleSeed() {
+ super(BlocksRegistry.BLACK_APPLE, MaterialColor.ADOBE);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockBlackBush.java b/src/main/java/redd90/betternether/blocks/BlockBlackBush.java
new file mode 100644
index 0000000..5164f2b
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBlackBush.java
@@ -0,0 +1,70 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+
+
+public class BlockBlackBush extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = VoxelShapes.create(0.1875, 0.0, 0.1875, 0.8125, 0.625, 0.8125);
+
+ public BlockBlackBush() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.BLACK)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherGround(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return true;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ spawnAsEntity(world, pos, new ItemStack(this.asItem()));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockBlackVine.java b/src/main/java/redd90/betternether/blocks/BlockBlackVine.java
new file mode 100644
index 0000000..f9a709d
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBlackVine.java
@@ -0,0 +1,127 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.BlocksHelper;
+
+public class BlockBlackVine extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 16, 14);
+ public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
+
+ public BlockBlackVine() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .notSolid());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(BOTTOM, true));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(BOTTOM);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState upState = world.getBlockState(pos.up());
+ return upState.getBlock() == this || upState.isSolidSide(world, pos, Direction.DOWN);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return world.getBlockState(pos.down()).getBlock() == this ? state.with(BOTTOM, false) : state.with(BOTTOM, true);
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ Mutable blockPos = new Mutable().setPos(pos);
+ for (int y = pos.getY() - 1; y > 1; y--) {
+ blockPos.setY(y);
+ if (world.getBlockState(blockPos).getBlock() != this)
+ return world.getBlockState(blockPos).getBlock() == Blocks.AIR;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return true;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ Mutable blockPos = new Mutable().setPos(pos);
+ for (int y = pos.getY(); y > 1; y--) {
+ blockPos.setY(y);
+ if (world.getBlockState(blockPos).getBlock() != this)
+ break;
+ }
+ BlocksHelper.setWithoutUpdate(world, blockPos.up(), getDefaultState().with(BOTTOM, false));
+ BlocksHelper.setWithoutUpdate(world, blockPos, getDefaultState().with(BOTTOM, true));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.getItem().isIn(Tags.Items.SHEARS) || EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ }
+ else {
+ return Lists.newArrayList();
+ }
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockBoneMushroom.java b/src/main/java/redd90/betternether/blocks/BlockBoneMushroom.java
new file mode 100644
index 0000000..0db0136
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBoneMushroom.java
@@ -0,0 +1,137 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.IntegerProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+
+
+public class BlockBoneMushroom extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE_NORTH = Block.makeCuboidShape(1, 1, 8, 15, 15, 16);
+ private static final VoxelShape SHAPE_SOUTH = Block.makeCuboidShape(1, 1, 0, 15, 15, 8);
+ private static final VoxelShape SHAPE_WEST = Block.makeCuboidShape(8, 1, 1, 16, 15, 15);
+ private static final VoxelShape SHAPE_EAST = Block.makeCuboidShape(0, 1, 1, 8, 15, 15);
+ private static final VoxelShape SHAPE_UP = Block.makeCuboidShape(1, 0, 1, 15, 12, 15);
+ public static final DirectionProperty FACING = BlockStateProperties.FACING;
+ public static final IntegerProperty AGE = IntegerProperty.create("age", 0, 2);
+
+ public BlockBoneMushroom() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.LIME)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(AGE, 0).with(FACING, Direction.UP));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING, AGE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ switch (state.get(FACING)) {
+ case NORTH:
+ return SHAPE_NORTH;
+ case SOUTH:
+ return SHAPE_SOUTH;
+ case EAST:
+ return SHAPE_EAST;
+ case WEST:
+ return SHAPE_WEST;
+ case UP:
+ default:
+ return SHAPE_UP;
+ }
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING);
+ if (direction == Direction.DOWN)
+ return false;
+ BlockPos blockPos = pos.offset(direction.getOpposite());
+ BlockState blockState = world.getBlockState(blockPos);
+ return BlocksHelper.isBone(blockState);
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ int age = state.get(AGE);
+ if (age < 2 && random.nextInt(32) == 0) {
+ BlocksHelper.setWithoutUpdate(world, pos, state.with(AGE, age + 1));
+ }
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ IWorldReader IWorldReader = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ for (int i = 0; i < directions.length; ++i) {
+ Direction direction = directions[i];
+ if (direction != Direction.UP) {
+ Direction direction2 = direction.getOpposite();
+ blockState = blockState.with(FACING, direction2);
+ if (blockState.isValidPosition(IWorldReader, blockPos)) {
+ return blockState;
+ }
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockBrownLargeMushroom.java b/src/main/java/redd90/betternether/blocks/BlockBrownLargeMushroom.java
new file mode 100644
index 0000000..a084e0a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockBrownLargeMushroom.java
@@ -0,0 +1,196 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockBrownLargeMushroom extends BlockBaseNotFull {
+ private static final VoxelShape TOP_CENTER_SHAPE = Block.makeCuboidShape(0, 0.1, 0, 16, 16, 16);
+ private static final VoxelShape TOP_EDGE_SHAPE = Block.makeCuboidShape(0, 8, 0, 16, 16, 16);
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", BrownMushroomShape.class);
+
+ private static final BrownMushroomShape[] ROT_SIDE = new BrownMushroomShape[] {
+ BrownMushroomShape.SIDE_N,
+ BrownMushroomShape.SIDE_E,
+ BrownMushroomShape.SIDE_S,
+ BrownMushroomShape.SIDE_W
+ };
+
+ private static final BrownMushroomShape[] ROT_CORNER = new BrownMushroomShape[] {
+ BrownMushroomShape.CORNER_N,
+ BrownMushroomShape.CORNER_E,
+ BrownMushroomShape.CORNER_S,
+ BrownMushroomShape.CORNER_W
+ };
+
+ public BlockBrownLargeMushroom() {
+ super(MaterialBuilder.makeWood(MaterialColor.BROWN).notSolid());
+ this.setDropItself(false);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ BrownMushroomShape shape = state.get(SHAPE);
+ return shape == BrownMushroomShape.BOTTOM || shape == BrownMushroomShape.MIDDLE ? new ItemStack(BlocksRegistry.MUSHROOM_STEM) : new ItemStack(Items.BROWN_MUSHROOM);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ BrownMushroomShape shape = state.get(SHAPE);
+ if (shape == BrownMushroomShape.TOP)
+ return TOP_CENTER_SHAPE;
+ else if (shape == BrownMushroomShape.MIDDLE || shape == BrownMushroomShape.BOTTOM)
+ return MIDDLE_SHAPE;
+ else
+ return TOP_EDGE_SHAPE;
+ }
+
+ public static enum BrownMushroomShape implements IStringSerializable {
+ TOP("top"), SIDE_N("side_n"), SIDE_S("side_s"), SIDE_E("side_e"), SIDE_W("side_w"), CORNER_N("corner_n"), CORNER_S("corner_s"), CORNER_E("corner_e"), CORNER_W("corner_w"), MIDDLE("middle"), BOTTOM("bottom");
+
+ final String name;
+
+ BrownMushroomShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ BrownMushroomShape shape = state.get(SHAPE);
+
+ int index = getRotationIndex(shape, ROT_SIDE);
+ if (index < 0) {
+ index = getRotationIndex(shape, ROT_CORNER);
+
+ if (index < 0) {
+ return state;
+ }
+
+ int offset = rotOffset(rotation);
+ return state.with(SHAPE, ROT_CORNER[(index + offset) & 3]);
+ }
+
+ int offset = rotOffset(rotation);
+ return state.with(SHAPE, ROT_SIDE[(index + offset) & 3]);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ BrownMushroomShape shape = state.get(SHAPE);
+ int index = getRotationIndex(shape, ROT_SIDE);
+ if (index < 0) {
+ index = getRotationIndex(shape, ROT_CORNER);
+ if (index < 0)
+ return state;
+ if (mirror == Mirror.FRONT_BACK) {
+ if (shape == BrownMushroomShape.CORNER_E)
+ shape = BrownMushroomShape.CORNER_W;
+ else if (shape == BrownMushroomShape.CORNER_W)
+ shape = BrownMushroomShape.CORNER_E;
+ }
+ else if (mirror == Mirror.LEFT_RIGHT) {
+ if (shape == BrownMushroomShape.CORNER_N)
+ shape = BrownMushroomShape.CORNER_S;
+ else if (shape == BrownMushroomShape.CORNER_S)
+ shape = BrownMushroomShape.CORNER_N;
+ }
+ return state.with(SHAPE, shape);
+ }
+ if (mirror == Mirror.FRONT_BACK) {
+ if (shape == BrownMushroomShape.SIDE_E)
+ shape = BrownMushroomShape.SIDE_W;
+ else if (shape == BrownMushroomShape.SIDE_W)
+ shape = BrownMushroomShape.SIDE_E;
+ }
+ else if (mirror == Mirror.LEFT_RIGHT) {
+ if (shape == BrownMushroomShape.SIDE_N)
+ shape = BrownMushroomShape.SIDE_S;
+ else if (shape == BrownMushroomShape.SIDE_S)
+ shape = BrownMushroomShape.SIDE_N;
+ }
+ return state.with(SHAPE, shape);
+ }
+
+ private int getRotationIndex(BrownMushroomShape shape, BrownMushroomShape[] rotations) {
+ for (int i = 0; i < 4; i++) {
+ if (shape == rotations[i])
+ return i;
+ }
+ return -1;
+ }
+
+ private int rotOffset(Rotation rotation) {
+ if (rotation == Rotation.NONE)
+ return 0;
+ else if (rotation == Rotation.CLOCKWISE_90)
+ return 1;
+ else if (rotation == Rotation.CLOCKWISE_180)
+ return 2;
+ else
+ return 3;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ switch (state.get(SHAPE)) {
+ case BOTTOM:
+ return state;
+ case MIDDLE:
+ case TOP:
+ default:
+ return getStateIfSame(state, world, pos.down());
+ case SIDE_E:
+ case CORNER_E:
+ return getStateIfSame(state, world, pos.west());
+ case SIDE_N:
+ case CORNER_N:
+ return getStateIfSame(state, world, pos.south());
+ case SIDE_S:
+ case CORNER_S:
+ return getStateIfSame(state, world, pos.north());
+ case SIDE_W:
+ case CORNER_W:
+ return getStateIfSame(state, world, pos.east());
+ }
+ }
+
+ private BlockState getStateIfSame(BlockState state, IWorld world, BlockPos pos) {
+ return world.getBlockState(pos).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockChestOfDrawers.java b/src/main/java/redd90/betternether/blocks/BlockChestOfDrawers.java
new file mode 100644
index 0000000..f450510
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockChestOfDrawers.java
@@ -0,0 +1,123 @@
+package redd90.betternether.blocks;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockRenderType;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.ContainerBlock;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.tileentities.TileEntityChestOfDrawers;
+
+
+public class BlockChestOfDrawers extends ContainerBlock {
+ private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(ImmutableMap.of(
+ Direction.NORTH, Block.makeCuboidShape(0, 0, 8, 16, 16, 16),
+ Direction.SOUTH, Block.makeCuboidShape(0, 0, 0, 16, 16, 8),
+ Direction.WEST, Block.makeCuboidShape(8, 0, 0, 16, 16, 16),
+ Direction.EAST, Block.makeCuboidShape(0, 0, 0, 8, 16, 16)));
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+ public static final BooleanProperty OPEN = BooleanProperty.create("open");
+
+ public BlockChestOfDrawers() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).notSolid());
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.NORTH).with(OPEN, false));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING, OPEN);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return BOUNDING_SHAPES.get(state.get(FACING));
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(IBlockReader view) {
+ return new TileEntityChestOfDrawers();
+ }
+
+ @Override
+ public BlockRenderType getRenderType(BlockState state) {
+ return BlockRenderType.MODEL;
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
+ if (itemStack.hasDisplayName()) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof TileEntityChestOfDrawers) {
+ ((TileEntityChestOfDrawers) blockEntity).setCustomName(itemStack.getDisplayName());
+ }
+ }
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (world.isRemote) {
+ return ActionResultType.SUCCESS;
+ }
+ else {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof TileEntityChestOfDrawers) {
+ player.openContainer((TileEntityChestOfDrawers) blockEntity);
+ }
+ return ActionResultType.SUCCESS;
+ }
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return this.getDefaultState().with(FACING, ctx.getPlacementHorizontalFacing().getOpposite());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ List drop = new ArrayList();
+ TileEntityChestOfDrawers entity = (TileEntityChestOfDrawers) builder.get(LootParameters.BLOCK_ENTITY);
+ drop.add(new ItemStack(this.asItem()));
+ entity.addItemsToList(drop);
+ return drop;
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasitPillar.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasitPillar.java
new file mode 100644
index 0000000..67fc5fd
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasitPillar.java
@@ -0,0 +1,59 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockCincinnasitPillar extends BlockBase {
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", CincinnasitPillarShape.class);
+
+ public BlockCincinnasitPillar() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ boolean top = world.getBlockState(pos.up()).getBlock() == this;
+ boolean bottom = world.getBlockState(pos.down()).getBlock() == this;
+ if (top && bottom)
+ return state.with(SHAPE, CincinnasitPillarShape.MIDDLE);
+ else if (top)
+ return state.with(SHAPE, CincinnasitPillarShape.BOTTOM);
+ else if (bottom)
+ return state.with(SHAPE, CincinnasitPillarShape.TOP);
+ else
+ return state.with(SHAPE, CincinnasitPillarShape.SMALL);
+ }
+
+ public static enum CincinnasitPillarShape implements IStringSerializable {
+ SMALL("small"), TOP("top"), MIDDLE("middle"), BOTTOM("bottom");
+
+ final String name;
+
+ CincinnasitPillarShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasite.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasite.java
new file mode 100644
index 0000000..5d43b77
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasite.java
@@ -0,0 +1,15 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+
+public class BlockCincinnasite extends BlockBase {
+ public BlockCincinnasite() {
+ super(AbstractBlock.Properties.create(Material.IRON, MaterialColor.YELLOW)
+ .hardnessAndResistance(3F, 10F)
+ .setRequiresTool()
+ .sound(SoundType.METAL));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasiteAnvil.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteAnvil.java
new file mode 100644
index 0000000..c341e41
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteAnvil.java
@@ -0,0 +1,31 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.AnvilBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import redd90.betternether.registry.BlocksRegistry;
+
+
+public class BlockCincinnasiteAnvil extends AnvilBlock {
+ public BlockCincinnasiteAnvil() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.canHarvestBlock(state)) {
+ return Lists.newArrayList(new ItemStack(this));
+ }
+ else {
+ return Lists.newArrayList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasiteForge.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteForge.java
new file mode 100644
index 0000000..2916e17
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteForge.java
@@ -0,0 +1,73 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+import java.util.function.ToIntFunction;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.AbstractFurnaceBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.container.INamedContainerProvider;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.stats.Stats;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.Direction;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.tileentities.TileEntityForge;
+
+
+public class BlockCincinnasiteForge extends AbstractFurnaceBlock {
+ public BlockCincinnasiteForge() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).setRequiresTool().setLightLevel(getLuminance()));
+ }
+
+ private static ToIntFunction getLuminance() {
+ return (blockState) -> {
+ return (Boolean) blockState.get(BlockStateProperties.LIT) ? 13 : 0;
+ };
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(IBlockReader world) {
+ return new TileEntityForge();
+ }
+
+ @Override
+ protected void interactWith(World world, BlockPos pos, PlayerEntity player) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof TileEntityForge) {
+ player.openContainer((INamedContainerProvider) blockEntity);
+ player.addStat(Stats.INTERACT_WITH_FURNACE);
+ }
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if ((Boolean) state.get(LIT)) {
+ double d = (double) pos.getX() + 0.5D;
+ double e = (double) pos.getY();
+ double f = (double) pos.getZ() + 0.5D;
+ if (random.nextDouble() < 0.1D) {
+ world.playSound(d, e, f, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false);
+ }
+
+ Direction direction = (Direction) state.get(FACING);
+ Direction.Axis axis = direction.getAxis();
+ double h = random.nextDouble() * 0.6D - 0.3D;
+ double i = axis == Direction.Axis.X ? (double) direction.getYOffset() * 0.52D : h;
+ double j = random.nextDouble() * 6.0D / 16.0D;
+ double k = axis == Direction.Axis.Z ? (double) direction.getZOffset() * 0.52D : h;
+ world.addParticle(ParticleTypes.SMOKE, d + i, e + j, f + k, 0.0D, 0.0D, 0.0D);
+ world.addParticle(ParticleTypes.FLAME, d + i, e + j, f + k, 0.0D, 0.0D, 0.0D);
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasiteFrame.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteFrame.java
new file mode 100644
index 0000000..877e3d2
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteFrame.java
@@ -0,0 +1,34 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockCincinnasiteFrame extends BlockBaseNotFull {
+ public BlockCincinnasiteFrame() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).notSolid());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public boolean isSideInvisible(BlockState state, BlockState neighbor, Direction facing) {
+ return neighbor.getBlock() == this ? true : super.isSideInvisible(state, neighbor, facing);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasiteLantern.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteLantern.java
new file mode 100644
index 0000000..417a7df
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasiteLantern.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockCincinnasiteLantern extends BlockBase {
+ public BlockCincinnasiteLantern() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).setLightLevel((state) -> {return 15;}));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockCincinnasitePedestal.java b/src/main/java/redd90/betternether/blocks/BlockCincinnasitePedestal.java
new file mode 100644
index 0000000..b293925
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCincinnasitePedestal.java
@@ -0,0 +1,23 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockCincinnasitePedestal extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 16, 14);
+
+ public BlockCincinnasitePedestal() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).notSolid());
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockCommonPlant.java b/src/main/java/redd90/betternether/blocks/BlockCommonPlant.java
new file mode 100644
index 0000000..d45e7d5
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCommonPlant.java
@@ -0,0 +1,96 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.state.IntegerProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+
+public class BlockCommonPlant extends BlockBaseNotFull implements IGrowable {
+ public static final IntegerProperty AGE = IntegerProperty.create("age", 0, 3);
+
+ public BlockCommonPlant(MaterialColor color) {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.BLACK)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ }
+
+ public BlockCommonPlant(AbstractBlock.Properties settings) {
+ super(settings);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(AGE);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherGround(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return state.get(AGE) < 3;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ int age = state.get(AGE);
+ if (age < 3)
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextBoolean()) : (random.nextInt(4) == 0);
+ else
+ return false;
+ }
+
+ protected boolean canGrowTerrain(World world, Random random, BlockPos pos, BlockState state) {
+ int age = state.get(AGE);
+ if (age < 3)
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ else
+ return false;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ int age = state.get(AGE);
+ world.setBlockState(pos, state.with(AGE, age + 1));
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canGrowTerrain(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockCommonSapling.java b/src/main/java/redd90/betternether/blocks/BlockCommonSapling.java
new file mode 100644
index 0000000..0195709
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockCommonSapling.java
@@ -0,0 +1,83 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+
+public class BlockCommonSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 14, 12);
+ private Block plant;
+
+ public BlockCommonSapling(Block plant, MaterialColor color) {
+ super(AbstractBlock.Properties.create(Material.PLANTS, color)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.plant = plant;
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherGround(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextBoolean()) : (random.nextInt(4) == 0);
+ }
+
+ protected boolean canGrowTerrain(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ world.setBlockState(pos, plant.getDefaultState());
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canGrowTerrain(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockEggPlant.java b/src/main/java/redd90/betternether/blocks/BlockEggPlant.java
new file mode 100644
index 0000000..ca1a886
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockEggPlant.java
@@ -0,0 +1,117 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.particles.BlockParticleData;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.potion.EffectInstance;
+import net.minecraft.potion.Effects;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.config.Configs;
+import redd90.betternether.registry.EntityRegistry;
+
+public class BlockEggPlant extends BlockCommonPlant {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(0, 0, 0, 16, 8, 16);
+ public static final BooleanProperty DESTRUCTED = BooleanProperty.create("destructed");
+
+ private boolean enableModDamage = true;
+ private boolean enablePlayerDamage = true;
+
+ public BlockEggPlant() {
+ super(MaterialColor.WHITE_TERRACOTTA);
+ enableModDamage = Configs.MAIN.getBoolean("egg_plant", "mob_damage", true);
+ enablePlayerDamage = Configs.MAIN.getBoolean("egg_plant", "player_damage", true);
+ this.setDefaultState(getStateContainer().getBaseState().with(DESTRUCTED, false));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ super.fillStateContainer(stateManager);
+ stateManager.add(DESTRUCTED);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (!state.get(DESTRUCTED))
+ world.addParticle(
+ ParticleTypes.ENTITY_EFFECT,
+ pos.getX() + random.nextDouble(),
+ pos.getY() + 0.4,
+ pos.getZ() + random.nextDouble(),
+ 0.46, 0.28, 0.55);
+ }
+
+ @Override
+ public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
+ if (!state.get(DESTRUCTED)) {
+ if (enableModDamage && entity instanceof LivingEntity && !((LivingEntity) entity).isPotionActive(Effects.POISON)) {
+ if (!EntityRegistry.isNetherEntity(entity))
+ ((LivingEntity) entity).addPotionEffect(new EffectInstance(Effects.POISON, 100, 3));
+ }
+ else if (enablePlayerDamage && entity instanceof PlayerEntity && !((PlayerEntity) entity).isPotionActive(Effects.POISON))
+ ((PlayerEntity) entity).addPotionEffect(new EffectInstance(Effects.POISON, 100, 3));
+
+ double px = pos.getX() + 0.5;
+ double py = pos.getY() + 0.125;
+ double pz = pos.getZ() + 0.5;
+ if (world.isRemote) {
+ world.playSound(px, py, pz, SoundType.WART.getBreakSound(), SoundCategory.BLOCKS, 1, 1, false);
+ BlockParticleData effect = new BlockParticleData(ParticleTypes.BLOCK, state);
+ Random random = world.rand;
+ for (int i = 0; i < 24; i++)
+ world.addParticle(effect,
+ px + random.nextGaussian() * 0.2,
+ py + random.nextGaussian() * 0.2,
+ pz + random.nextGaussian() * 0.2,
+ random.nextGaussian(),
+ random.nextGaussian(),
+ random.nextGaussian());
+ }
+
+ world.setBlockState(pos, state.with(DESTRUCTED, true));
+ }
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (builder.get(LootParameters.TOOL).getItem().isIn(Tags.Items.SHEARS))
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return super.getDrops(state, builder);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ if (state.get(DESTRUCTED))
+ world.setBlockState(pos, this.getDefaultState());
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockEyeBase.java b/src/main/java/redd90/betternether/blocks/BlockEyeBase.java
new file mode 100644
index 0000000..9c36727
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockEyeBase.java
@@ -0,0 +1,39 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockEyeBase extends BlockBase {
+ public BlockEyeBase(AbstractBlock.Properties settings) {
+ super(settings.setAllowsSpawn((state, world, pos, type) -> {
+ return false;
+ }));
+ setDropItself(false);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ BlockPos blockPos = pos.up();
+ Block up = world.getBlockState(blockPos).getBlock();
+ if (up != BlocksRegistry.EYE_VINE && up != Blocks.NETHERRACK)
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.EYE_SEED);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockEyeSeed.java b/src/main/java/redd90/betternether/blocks/BlockEyeSeed.java
new file mode 100644
index 0000000..9a7c24d
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockEyeSeed.java
@@ -0,0 +1,79 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureEye;
+
+public class BlockEyeSeed extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 6, 4, 12, 16, 12);
+ private static final StructureEye STRUCTURE = new StructureEye();
+
+ public BlockEyeSeed() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return random.nextInt(4) == 0 && world.getBlockState(pos.down()).getBlock() == Blocks.AIR;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.generate(world, pos, random);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherrack(world.getBlockState(pos.up()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state)) {
+ grow(world, random, pos, state);
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockEyeVine.java b/src/main/java/redd90/betternether/blocks/BlockEyeVine.java
new file mode 100644
index 0000000..088917e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockEyeVine.java
@@ -0,0 +1,68 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockEyeVine extends BlockBaseNotFull {
+ protected static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+
+ public BlockEyeVine() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .notSolid());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ setDropItself(false);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ Block up = world.getBlockState(pos.up()).getBlock();
+ Block down = world.getBlockState(pos.down()).getBlock();
+ if (up != this && up != Blocks.NETHERRACK)
+ return Blocks.AIR.getDefaultState();
+ else if (down != this && !(down instanceof BlockEyeBase))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.EYE_SEED);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockEyeball.java b/src/main/java/redd90/betternether/blocks/BlockEyeball.java
new file mode 100644
index 0000000..1200be2
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockEyeball.java
@@ -0,0 +1,54 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.CauldronBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+
+
+public class BlockEyeball extends BlockEyeBase {
+ public BlockEyeball() {
+ super(AbstractBlock.Properties.create(Material.WOOD, MaterialColor.BROWN)
+ .sound(SoundType.SLIME)
+ .hardnessAndResistance(0.5F,0.5F)
+ .tickRandomly());
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (random.nextInt(5) == 0) {
+ double x = pos.getX() + random.nextDouble();
+ double y = pos.getY() + random.nextDouble() * 0.3;
+ double z = pos.getZ() + random.nextDouble();
+ world.addParticle(ParticleTypes.DRIPPING_WATER, x, y, z, 0, 0, 0);
+ }
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ if (random.nextInt(64) == 0) {
+ int y = BlocksHelper.downRay(world, pos, 64) + 1;
+ BlockPos down = pos.down(y);
+ BlockState cauldron = world.getBlockState(down);
+ if (cauldron.getBlock() == Blocks.CAULDRON) {
+ int level = cauldron.get(CauldronBlock.LEVEL);
+ if (level < 3) {
+ world.setBlockState(down, cauldron.with(CauldronBlock.LEVEL, level + 1));
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockEyeballSmall.java b/src/main/java/redd90/betternether/blocks/BlockEyeballSmall.java
new file mode 100644
index 0000000..73bebb2
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockEyeballSmall.java
@@ -0,0 +1,46 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public class BlockEyeballSmall extends BlockEyeBase {
+ protected static final VoxelShape SHAPE = Block.makeCuboidShape(4, 8, 4, 12, 16, 12);
+
+ public BlockEyeballSmall() {
+ super(AbstractBlock.Properties.create(Material.WOOD, MaterialColor.BROWN)
+ .sound(SoundType.SLIME)
+ .hardnessAndResistance(0.5F, 0.5F)
+ .notSolid());
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (random.nextInt(5) == 0) {
+ double x = pos.getX() + random.nextDouble() * 0.5 + 0.25;
+ double y = pos.getY() + random.nextDouble() * 0.1 + 0.5;
+ double z = pos.getZ() + random.nextDouble() * 0.5 + 0.25;
+ world.addParticle(ParticleTypes.DRIPPING_WATER, x, y, z, 0, 0, 0);
+ }
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockFarmland.java b/src/main/java/redd90/betternether/blocks/BlockFarmland.java
new file mode 100644
index 0000000..057d226
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockFarmland.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockFarmland extends BlockBase {
+ public BlockFarmland() {
+ super(MaterialBuilder.makeWood(MaterialColor.LIME_TERRACOTTA));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockFeatherFern.java b/src/main/java/redd90/betternether/blocks/BlockFeatherFern.java
new file mode 100644
index 0000000..5dfbf7c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockFeatherFern.java
@@ -0,0 +1,29 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+
+public class BlockFeatherFern extends BlockCommonPlant {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 14, 14);
+
+ public BlockFeatherFern() {
+ super(MaterialColor.LIGHT_BLUE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ public Block.OffsetType getOffsetType() {
+ return Block.OffsetType.XZ;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockFireBowl.java b/src/main/java/redd90/betternether/blocks/BlockFireBowl.java
new file mode 100644
index 0000000..206c4ff
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockFireBowl.java
@@ -0,0 +1,94 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+import java.util.function.ToIntFunction;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.item.Items;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+
+public class BlockFireBowl extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(0, 0, 0, 16, 12, 16);
+ public static final BooleanProperty FIRE = BooleanProperty.create("fire");
+
+ public BlockFireBowl(Block source) {
+ super(AbstractBlock.Properties.from(source).notSolid().setLightLevel(getLuminance()));
+ this.setDefaultState(getStateContainer().getBaseState().with(FIRE, false));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ protected static ToIntFunction getLuminance() {
+ return (state) -> {
+ return state.get(FIRE) ? 15 : 0;
+ };
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FIRE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ if (hit.getFace() == Direction.UP) {
+ if (player.getHeldItemMainhand().getItem() == Items.FLINT_AND_STEEL && !state.get(FIRE)) {
+ world.setBlockState(pos, state.with(FIRE, true));
+ if (!player.isCreative() && !world.isRemote)
+ player.getHeldItemMainhand().attemptDamageItem(1, world.rand, (ServerPlayerEntity) player);
+ world.playSound(player, pos, SoundEvents.ITEM_FLINTANDSTEEL_USE, SoundCategory.BLOCKS, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
+ return ActionResultType.SUCCESS;
+ }
+ else if (player.getHeldItemMainhand().isEmpty() && state.get(FIRE)) {
+ world.setBlockState(pos, state.with(FIRE, false));
+ world.playSound(player, pos, SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.BLOCKS, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F);
+ return ActionResultType.SUCCESS;
+ }
+ }
+ return ActionResultType.FAIL;
+ }
+
+ @Override
+ public void onEntityWalk(World world, BlockPos pos, Entity entity) {
+ if (!entity.isImmuneToFire() && entity instanceof LivingEntity && world.getBlockState(pos).get(FIRE)) {
+ entity.attackEntityFrom(DamageSource.HOT_FLOOR, 1.0F);
+ }
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (state.get(FIRE)) {
+ if (random.nextInt(24) == 0)
+ world.playSound(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 1.0F + random.nextFloat(), random.nextFloat() * 0.7F + 0.3F, false);
+ if (random.nextInt(4) == 0)
+ world.addParticle(ParticleTypes.LARGE_SMOKE, pos.getX() + random.nextDouble(), pos.getY() + 0.75, pos.getZ() + random.nextDouble(), 0.0D, 0.0D, 0.0D);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockGeyser.java b/src/main/java/redd90/betternether/blocks/BlockGeyser.java
new file mode 100644
index 0000000..a512762
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockGeyser.java
@@ -0,0 +1,106 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+
+public class BlockGeyser extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(1, 0, 1, 15, 4, 15);
+
+ public BlockGeyser() {
+ super(AbstractBlock.Properties.from(Blocks.NETHERRACK).notSolid().setLightLevel((state) -> {return 10;}));
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ for (int i = 0; i < 5; i++) {
+ world.addParticle(
+ ParticleTypes.FLAME,
+ pos.getX() + 0.4 + random.nextDouble() * 0.1,
+ pos.getY() + 0.125,
+ pos.getZ() + 0.4 + random.nextDouble() * 0.1,
+ random.nextDouble() * 0.02 - 0.01,
+ 0.05D + random.nextDouble() * 0.05,
+ random.nextDouble() * 0.02 - 0.01);
+
+ world.addParticle(
+ ParticleTypes.LARGE_SMOKE,
+ pos.getX() + 0.4 + random.nextDouble() * 0.1,
+ pos.getY() + 0.125,
+ pos.getZ() + 0.4 + random.nextDouble() * 0.1,
+ random.nextDouble() * 0.02 - 0.01,
+ 0.05D + random.nextDouble() * 0.05,
+ random.nextDouble() * 0.02 - 0.01);
+
+ world.addParticle(
+ ParticleTypes.LAVA,
+ pos.getX() + 0.4 + random.nextDouble() * 0.1,
+ pos.getY() + 0.125 + random.nextDouble() * 0.1,
+ pos.getZ() + 0.4 + random.nextDouble() * 0.1,
+ random.nextDouble() * 0.02 - 0.01,
+ 0.05D + random.nextDouble() * 0.05,
+ random.nextDouble() * 0.02 - 0.01);
+ }
+
+ if (random.nextDouble() < 0.1D) {
+ world.playSound(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, SoundEvents.BLOCK_FIRE_AMBIENT, SoundCategory.BLOCKS, 1.0F, 1.0F, false);
+ }
+ if (random.nextDouble() < 0.1D) {
+ world.playSound(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false);
+ }
+ if (random.nextDouble() < 0.1D) {
+ world.playSound(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, SoundEvents.BLOCK_LAVA_POP, SoundCategory.BLOCKS, 1.0F, 1.0F, false);
+ }
+ }
+
+ @Override
+ public void onEntityWalk(World world, BlockPos pos, Entity entity) {
+ if (!entity.isImmuneToFire() && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) {
+ entity.attackEntityFrom(DamageSource.IN_FIRE, 3F);
+ entity.setFire(1);
+ }
+
+ super.onEntityWalk(world, pos, entity);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).isSolidSide(world, pos.down(), Direction.UP);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockGiantLucis.java b/src/main/java/redd90/betternether/blocks/BlockGiantLucis.java
new file mode 100644
index 0000000..aa01708
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockGiantLucis.java
@@ -0,0 +1,40 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.HugeMushroomBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraftforge.common.ToolType;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.ItemsRegistry;
+
+public class BlockGiantLucis extends HugeMushroomBlock {
+ public BlockGiantLucis() {
+ super(AbstractBlock.Properties.create(Material.ORGANIC, MaterialColor.YELLOW)
+ .harvestTool(ToolType.AXE)
+ .sound(SoundType.WOOD)
+ .hardnessAndResistance(1F)
+ .setLightLevel((state) -> {return 15;})
+ .notSolid());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) return Lists.newArrayList(new ItemStack(this.asItem()));
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.LUCIS_SPORE, MHelper.randRange(0, 1, MHelper.RANDOM)),
+ new ItemStack(ItemsRegistry.GLOWSTONE_PILE, MHelper.randRange(0, 2, MHelper.RANDOM)));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockGiantMold.java b/src/main/java/redd90/betternether/blocks/BlockGiantMold.java
new file mode 100644
index 0000000..86d0f18
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockGiantMold.java
@@ -0,0 +1,62 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockGiantMold extends BlockBaseNotFull {
+ private static final VoxelShape TOP_SHAPE = Block.makeCuboidShape(2, 2, 2, 14, 14, 14);
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockGiantMold() {
+ super(MaterialBuilder.makeWood(MaterialColor.GRAY).sound(SoundType.FUNGUS).notSolid());
+ this.setDropItself(false);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(SHAPE) == TripleShape.TOP ? TOP_SHAPE : MIDDLE_SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ TripleShape shape = state.get(SHAPE);
+ return shape == TripleShape.TOP ? new ItemStack(BlocksRegistry.GIANT_MOLD_SAPLING) : new ItemStack(BlocksRegistry.MUSHROOM_STEM);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ switch (state.get(SHAPE)) {
+ case BOTTOM:
+ return state;
+ case MIDDLE:
+ case TOP:
+ default:
+ return world.getBlockState(pos.down()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockGiantMoldSapling.java b/src/main/java/redd90/betternether/blocks/BlockGiantMoldSapling.java
new file mode 100644
index 0000000..6021947
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockGiantMoldSapling.java
@@ -0,0 +1,81 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.plants.StructureGiantMold;
+
+
+public class BlockGiantMoldSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 14, 12);
+ private static final StructureGiantMold STRUCTURE = new StructureGiantMold();
+
+ public BlockGiantMoldSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.LIME)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).getBlock() == BlocksRegistry.NETHER_MYCELIUM;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.grow(world, pos, random);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockGoldenVine.java b/src/main/java/redd90/betternether/blocks/BlockGoldenVine.java
new file mode 100644
index 0000000..42142fd
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockGoldenVine.java
@@ -0,0 +1,129 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.BlocksHelper;
+
+public class BlockGoldenVine extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 16, 14);
+ public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
+
+ public BlockGoldenVine() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .notSolid()
+ .setLightLevel((state) -> {return 15;}));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(BOTTOM, true));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(BOTTOM);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState upState = world.getBlockState(pos.up());
+ return upState.getBlock() == this || upState.isSolidSide(world, pos, Direction.DOWN);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return world.getBlockState(pos.down()).getBlock() == this ? state.with(BOTTOM, false) : state.with(BOTTOM, true);
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ Mutable blockPos = new Mutable().setPos(pos);
+ for (int y = pos.getY() - 1; y > 1; y--) {
+ blockPos.setY(y);
+ if (world.getBlockState(blockPos).getBlock() != this)
+ return world.getBlockState(blockPos).getBlock() == Blocks.AIR;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return true;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ Mutable blockPos = new Mutable().setPos(pos);
+ for (int y = pos.getY(); y > 1; y--) {
+ blockPos.setY(y);
+ if (world.getBlockState(blockPos).getBlock() != this)
+ break;
+ }
+ BlocksHelper.setWithUpdate(world, blockPos.up(), getDefaultState().with(BOTTOM, false));
+ BlocksHelper.setWithUpdate(world, blockPos, getDefaultState().with(BOTTOM, true));
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.getItem().isIn(Tags.Items.SHEARS) || EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ }
+ else {
+ return Lists.newArrayList();
+ }
+ }
+}
+
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockGrayMold.java b/src/main/java/redd90/betternether/blocks/BlockGrayMold.java
new file mode 100644
index 0000000..ee20d12
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockGrayMold.java
@@ -0,0 +1,39 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+
+public class BlockGrayMold extends BlockMold {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 8, 12);
+
+ public BlockGrayMold() {
+ super(MaterialColor.GRAY);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (random.nextInt(3) == 0) {
+ world.addParticle(ParticleTypes.MYCELIUM, pos.getX() + random.nextDouble(), pos.getY() + random.nextDouble() * 0.5, pos.getZ() + random.nextDouble(), 0.0D, 0.0D, 0.0D);
+ }
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockHookMushroom.java b/src/main/java/redd90/betternether/blocks/BlockHookMushroom.java
new file mode 100644
index 0000000..a56f573
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockHookMushroom.java
@@ -0,0 +1,26 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockHookMushroom extends BlockMold {
+ public BlockHookMushroom() {
+ super(MaterialBuilder.makeGrass(MaterialColor.PINK)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .tickRandomly()
+ .setLightLevel((state) -> {return 13;}));
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherrack(world.getBlockState(pos.up()));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockInkBush.java b/src/main/java/redd90/betternether/blocks/BlockInkBush.java
new file mode 100644
index 0000000..9106565
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockInkBush.java
@@ -0,0 +1,22 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockInkBush extends BlockCommonPlant {
+ public BlockInkBush() {
+ super(MaterialColor.BLACK);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.INK_BUSH_SEED);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockInkBushSeed.java b/src/main/java/redd90/betternether/blocks/BlockInkBushSeed.java
new file mode 100644
index 0000000..4a53054
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockInkBushSeed.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockInkBushSeed extends BlockCommonSapling {
+ public BlockInkBushSeed() {
+ super(BlocksRegistry.INK_BUSH, MaterialColor.RED);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockJellyfishMushroom.java b/src/main/java/redd90/betternether/blocks/BlockJellyfishMushroom.java
new file mode 100644
index 0000000..8c0b63c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockJellyfishMushroom.java
@@ -0,0 +1,160 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.ItemsRegistry;
+
+public class BlockJellyfishMushroom extends BlockBaseNotFull {
+ private static final VoxelShape TOP_SHAPE = Block.makeCuboidShape(1, 0, 1, 15, 16, 15);
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+ public static final EnumProperty VISUAL = EnumProperty.create("visual", JellyShape.class);
+
+ public BlockJellyfishMushroom() {
+ super(MaterialBuilder.makeWood(MaterialColor.CYAN).hardnessAndResistance(0.1F).sound(SoundType.FUNGUS).notSolid().setLightLevel((state) -> {return 13;}));
+ this.setRenderLayer(BNRenderLayer.TRANSLUCENT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE, VISUAL);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(SHAPE) == TripleShape.TOP ? TOP_SHAPE : MIDDLE_SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.JELLYFISH_MUSHROOM_SAPLING);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ switch (state.get(SHAPE)) {
+ case BOTTOM:
+ return world.getBlockState(pos.down()).isSolidSide(world, pos.down(), Direction.UP) ? state : Blocks.AIR.getDefaultState();
+ case MIDDLE:
+ return world.getBlockState(pos.up()).getBlock() == this && world.getBlockState(pos.down()).isSolidSide(world, pos.down(), Direction.UP) ? state : Blocks.AIR.getDefaultState();
+ case TOP:
+ default:
+ return world.getBlockState(pos.down()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ }
+
+ @Override
+ public void onFallenUpon(World world, BlockPos pos, Entity entity, float distance) {
+ if (world.getBlockState(pos).get(SHAPE) != TripleShape.TOP)
+ return;
+ if (entity.isSuppressingBounce())
+ super.onFallenUpon(world, pos, entity, distance);
+ else
+ entity.onLivingFall(distance, 0.0F);
+ }
+
+ @Override
+ public void onLanded(IBlockReader world, Entity entity) {
+ if (entity.isSuppressingBounce())
+ super.onLanded(world, entity);
+ else
+ this.bounce(entity);
+ }
+
+ private void bounce(Entity entity) {
+ Vector3d vec3d = entity.getMotion();
+ if (vec3d.y < 0.0D) {
+ double d = entity instanceof LivingEntity ? 1.0D : 0.8D;
+ entity.setVelocity(vec3d.x, -vec3d.y * d, vec3d.z);
+ }
+ }
+
+ @Override
+ public void onEntityWalk(World world, BlockPos pos, Entity entity) {
+ if (world.getBlockState(pos).get(SHAPE) != TripleShape.TOP) {
+ super.onEntityWalk(world, pos, entity);
+ return;
+ }
+
+ double d = Math.abs(entity.getMotion().y);
+ if (d < 0.1D && !entity.isSuppressingBounce()) {
+ double e = 0.4D + d * 0.2D;
+ entity.setMotion(entity.getMotion().mul(e, 1.0D, e));
+ }
+ super.onEntityWalk(world, pos, entity);
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (state.get(SHAPE) == TripleShape.TOP) {
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.JELLYFISH_MUSHROOM_SAPLING, MHelper.randRange(1, 2, MHelper.RANDOM)),
+ new ItemStack(ItemsRegistry.GLOWSTONE_PILE, MHelper.randRange(0, 2, MHelper.RANDOM)),
+ new ItemStack(Items.SLIME_BALL, MHelper.randRange(0, 1, MHelper.RANDOM)));
+ }
+ else if (state.get(SHAPE) == TripleShape.BOTTOM)
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.JELLYFISH_MUSHROOM_SAPLING, MHelper.randRange(1, 2, MHelper.RANDOM)));
+ else
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.MUSHROOM_STEM));
+ }
+
+ public static enum JellyShape implements IStringSerializable {
+ NORMAL("normal"), SEPIA("sepia"), POOR("poor");
+
+ final String name;
+
+ JellyShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockJellyfishMushroomSapling.java b/src/main/java/redd90/betternether/blocks/BlockJellyfishMushroomSapling.java
new file mode 100644
index 0000000..90123ae
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockJellyfishMushroomSapling.java
@@ -0,0 +1,80 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.tags.BlockTags;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureJellyfishMushroom;
+
+public class BlockJellyfishMushroomSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 6, 12);
+ private static final StructureJellyfishMushroom STRUCTURE = new StructureJellyfishMushroom();
+
+ public BlockJellyfishMushroomSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.CYAN)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly()
+ .setLightLevel((state) -> {return 9;}));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).getBlock().isIn(BlockTags.NYLIUM);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.grow(world, pos, random);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockLucisMushroom.java b/src/main/java/redd90/betternether/blocks/BlockLucisMushroom.java
new file mode 100644
index 0000000..1dc0d20
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockLucisMushroom.java
@@ -0,0 +1,114 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.ToolType;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.ItemsRegistry;
+
+public class BlockLucisMushroom extends BlockBaseNotFull {
+ private static final VoxelShape V_SHAPE = Block.makeCuboidShape(0, 0, 0, 16, 9, 16);
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", EnumShape.class);
+
+ public BlockLucisMushroom() {
+ super(AbstractBlock.Properties.create(Material.ORGANIC, MaterialColor.YELLOW)
+ .harvestTool(ToolType.AXE)
+ .sound(SoundType.WOOD)
+ .hardnessAndResistance(1F)
+ .setLightLevel((state) -> {return 15;})
+ .notSolid());
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.NORTH).with(SHAPE, EnumShape.CORNER));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING, SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return V_SHAPE;
+ }
+
+ public enum EnumShape implements IStringSerializable {
+ CORNER("corner"), SIDE("side"), CENTER("center");
+
+ final String name;
+
+ EnumShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.LUCIS_SPORE), new ItemStack(ItemsRegistry.GLOWSTONE_PILE, MHelper.randRange(2, 4, MHelper.RANDOM)));
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ if (mirror == Mirror.FRONT_BACK) {
+ if (state.get(SHAPE) == EnumShape.SIDE) state = state.with(FACING, state.get(FACING).rotateYCCW());
+ if (state.get(FACING) == Direction.NORTH) return state.with(FACING, Direction.WEST);
+ if (state.get(FACING) == Direction.WEST) return state.with(FACING, Direction.NORTH);
+ if (state.get(FACING) == Direction.SOUTH) return state.with(FACING, Direction.EAST);
+ if (state.get(FACING) == Direction.EAST) return state.with(FACING, Direction.SOUTH);
+ }
+ else if (mirror == Mirror.LEFT_RIGHT) {
+ if (state.get(SHAPE) == EnumShape.SIDE) state = state.with(FACING, state.get(FACING).rotateYCCW());
+ if (state.get(FACING) == Direction.NORTH) return state.with(FACING, Direction.EAST);
+ if (state.get(FACING) == Direction.EAST) return state.with(FACING, Direction.NORTH);
+ if (state.get(FACING) == Direction.SOUTH) return state.with(FACING, Direction.WEST);
+ if (state.get(FACING) == Direction.WEST) return state.with(FACING, Direction.SOUTH);
+ }
+ return state;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.LUCIS_SPORE);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockLucisSpore.java b/src/main/java/redd90/betternether/blocks/BlockLucisSpore.java
new file mode 100644
index 0000000..8198a56
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockLucisSpore.java
@@ -0,0 +1,133 @@
+package redd90.betternether.blocks;
+
+import java.util.EnumMap;
+import java.util.Random;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.plants.StructureLucis;
+
+public class BlockLucisSpore extends BlockBaseNotFull implements IGrowable {
+ private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(ImmutableMap.of(
+ Direction.NORTH, Block.makeCuboidShape(4, 4, 8, 12, 12, 16),
+ Direction.SOUTH, Block.makeCuboidShape(4, 4, 0, 12, 12, 8),
+ Direction.WEST, Block.makeCuboidShape(8, 4, 4, 16, 12, 12),
+ Direction.EAST, Block.makeCuboidShape(0, 4, 4, 8, 12, 12)));
+ private static final StructureLucis STRUCTURE = new StructureLucis();
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+
+ public BlockLucisSpore() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.LIME)
+ .sound(SoundType.CROP)
+ .zeroHardnessAndResistance()
+ .notSolid()
+ .doesNotBlockMovement()
+ .tickRandomly()
+ .setLightLevel((state) -> {return 7;}));
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.NORTH));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return BOUNDING_SHAPES.get(state.get(FACING));
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return random.nextInt(16) == 0;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.generate(world, pos, random);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state)) {
+ grow(world, random, pos, state);
+ }
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING);
+ BlockPos blockPos = pos.offset(direction.getOpposite());
+ BlockState blockState = world.getBlockState(blockPos);
+ return BlocksHelper.isNetherrack(blockState) || BlocksRegistry.ANCHOR_TREE.isTreeLog(blockState.getBlock());
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ IWorldReader worldView = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ for (int i = 0; i < directions.length; ++i) {
+ Direction direction = directions[i];
+ if (direction.getAxis().isHorizontal()) {
+ Direction direction2 = direction.getOpposite();
+ blockState = blockState.with(FACING, direction2);
+ if (blockState.isValidPosition(worldView, blockPos)) {
+ return blockState;
+ }
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockLumabusSeed.java b/src/main/java/redd90/betternether/blocks/BlockLumabusSeed.java
new file mode 100644
index 0000000..0f0e2ed
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockLumabusSeed.java
@@ -0,0 +1,81 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.structures.IStructure;
+
+
+public class BlockLumabusSeed extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 6, 4, 12, 16, 12);
+ private final IStructure structure;
+
+ public BlockLumabusSeed(IStructure structure) {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.structure = structure;
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return random.nextInt(4) == 0 && world.getBlockState(pos.down()).getBlock() == Blocks.AIR;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ structure.generate(world, pos, random);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState upState = world.getBlockState(pos.up());
+ return upState.isSolidSide(world, pos, Direction.DOWN);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state)) {
+ grow(world, random, pos, state);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockLumabusVine.java b/src/main/java/redd90/betternether/blocks/BlockLumabusVine.java
new file mode 100644
index 0000000..9ce3524
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockLumabusVine.java
@@ -0,0 +1,104 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+import java.util.function.ToIntFunction;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.ItemsRegistry;
+
+public class BlockLumabusVine extends BlockBaseNotFull {
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ private static final VoxelShape BOTTOM_SHAPE = Block.makeCuboidShape(2, 4, 2, 14, 16, 14);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+ private static final Random RANDOM = new Random();
+ private final Block seed;
+
+ public BlockLumabusVine(Block seed) {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.CYAN)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .notSolid()
+ .setLightLevel(getLuminance()));
+ this.seed = seed;
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, TripleShape.TOP));
+ }
+
+ private static ToIntFunction getLuminance() {
+ return (blockState) -> {
+ return blockState.get(SHAPE) == TripleShape.BOTTOM ? 15 : 0;
+ };
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(SHAPE) == TripleShape.BOTTOM ? BOTTOM_SHAPE : MIDDLE_SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState upState = world.getBlockState(pos.up());
+ return upState.getBlock() == this || upState.isSolidSide(world, pos, Direction.DOWN);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ return isValidPosition(state, world, pos) && (world.getBlockState(pos.down()).getBlock() == this || state.get(SHAPE) == TripleShape.BOTTOM) ? state : Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (state.get(SHAPE) == TripleShape.BOTTOM) {
+ return Lists.newArrayList(new ItemStack(seed, MHelper.randRange(1, 3, RANDOM)), new ItemStack(ItemsRegistry.GLOWSTONE_PILE, MHelper.randRange(1, 3, RANDOM)));
+ }
+ return Lists.newArrayList();
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(seed);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockMagmaFlower.java b/src/main/java/redd90/betternether/blocks/BlockMagmaFlower.java
new file mode 100644
index 0000000..aa27fd8
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockMagmaFlower.java
@@ -0,0 +1,29 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorldReader;
+
+public class BlockMagmaFlower extends BlockCommonPlant {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(1, 0, 1, 15, 12, 15);
+
+ public BlockMagmaFlower() {
+ super(MaterialColor.ORANGE_TERRACOTTA);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).getBlock() == Blocks.MAGMA_BLOCK;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockMold.java b/src/main/java/redd90/betternether/blocks/BlockMold.java
new file mode 100644
index 0000000..4084381
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockMold.java
@@ -0,0 +1,110 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.ShearsItem;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockMold extends BlockBaseNotFull {
+ public BlockMold(MaterialColor color) {
+ super(MaterialBuilder.makeGrass(color)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ }
+
+ public BlockMold(AbstractBlock.Properties settings) {
+ super(settings);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public Block.OffsetType getOffsetType() {
+ return Block.OffsetType.XZ;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherMycelium(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (random.nextInt(16) == 0) {
+ int c = 0;
+ c = world.getBlockState(pos.north()).getBlock() == this ? c++ : c;
+ c = world.getBlockState(pos.south()).getBlock() == this ? c++ : c;
+ c = world.getBlockState(pos.east()).getBlock() == this ? c++ : c;
+ c = world.getBlockState(pos.west()).getBlock() == this ? c++ : c;
+ if (c < 2) {
+ BlockPos npos = new BlockPos(pos);
+ switch (random.nextInt(4)) {
+ case 0:
+ npos = npos.add(-1, 0, 0);
+ break;
+ case 1:
+ npos = npos.add(1, 0, 0);
+ break;
+ case 2:
+ npos = npos.add(0, 0, -1);
+ break;
+ default:
+ npos = npos.add(0, 0, 1);
+ break;
+ }
+ if (world.isAirBlock(npos) && isValidPosition(state, world, npos)) {
+ BlocksHelper.setWithoutUpdate(world, npos, getDefaultState());
+ }
+ }
+ }
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (builder.get(LootParameters.TOOL).getItem() instanceof ShearsItem)
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return super.getDrops(state, builder);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockMossCover.java b/src/main/java/redd90/betternether/blocks/BlockMossCover.java
new file mode 100644
index 0000000..cfeac1b
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockMossCover.java
@@ -0,0 +1,34 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorldReader;
+
+public class BlockMossCover extends BlockMold {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(0, 0, 0, 16, 4, 16);
+
+ public BlockMossCover() {
+ super(MaterialColor.GREEN);
+ }
+
+ @Override
+ public Block.OffsetType getOffsetType() {
+ return Block.OffsetType.NONE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).isSolidSide(world, pos, Direction.UP);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockMushroomFir.java b/src/main/java/redd90/betternether/blocks/BlockMushroomFir.java
new file mode 100644
index 0000000..eb56bd9
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockMushroomFir.java
@@ -0,0 +1,123 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockMushroomFir extends BlockBaseNotFull {
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", MushroomFirShape.class);
+
+ private static final VoxelShape BOTTOM_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ private static final VoxelShape TOP_SHAPE = Block.makeCuboidShape(6, 0, 6, 10, 16, 10);
+ private static final VoxelShape SIDE_BIG_SHAPE = Block.makeCuboidShape(0.01, 0.01, 0.01, 15.99, 13, 15.99);
+ private static final VoxelShape SIDE_SMALL_N_SHAPE = Block.makeCuboidShape(4, 1, 0, 12, 8, 8);
+ private static final VoxelShape SIDE_SMALL_S_SHAPE = Block.makeCuboidShape(4, 1, 8, 12, 8, 16);
+ private static final VoxelShape SIDE_SMALL_E_SHAPE = Block.makeCuboidShape(8, 1, 4, 16, 8, 12);
+ private static final VoxelShape SIDE_SMALL_W_SHAPE = Block.makeCuboidShape(0, 1, 4, 8, 8, 12);
+ private static final VoxelShape END_SHAPE = Block.makeCuboidShape(0.01, 0, 0.01, 15.99, 15.99, 15.99);
+
+ public BlockMushroomFir() {
+ super(MaterialBuilder.makeWood(MaterialColor.CYAN).sound(SoundType.FUNGUS).notSolid());
+ this.setDropItself(false);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ switch (state.get(SHAPE)) {
+ case BOTTOM:
+ return BOTTOM_SHAPE;
+ case END:
+ return END_SHAPE;
+ case MIDDLE:
+ default:
+ return MIDDLE_SHAPE;
+ case SIDE_BIG_E:
+ case SIDE_BIG_N:
+ case SIDE_BIG_S:
+ case SIDE_BIG_W:
+ return SIDE_BIG_SHAPE;
+ case SIDE_SMALL_E:
+ return SIDE_SMALL_E_SHAPE;
+ case SIDE_SMALL_N:
+ return SIDE_SMALL_N_SHAPE;
+ case SIDE_SMALL_S:
+ return SIDE_SMALL_S_SHAPE;
+ case SIDE_SMALL_W:
+ return SIDE_SMALL_W_SHAPE;
+ case TOP:
+ return TOP_SHAPE;
+ }
+ }
+
+ public enum MushroomFirShape implements IStringSerializable {
+ BOTTOM("bottom"), MIDDLE("middle"), TOP("top"), SIDE_BIG_N("side_big_n"), SIDE_BIG_S("side_big_s"), SIDE_BIG_E("side_big_e"), SIDE_BIG_W("side_big_w"), SIDE_SMALL_N("side_small_n"), SIDE_SMALL_S("side_small_s"), SIDE_SMALL_E(
+ "side_small_e"), SIDE_SMALL_W("side_small_w"), END("end");
+
+ final String name;
+
+ MushroomFirShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ MushroomFirShape shape = state.get(SHAPE);
+ return shape == MushroomFirShape.BOTTOM || shape == MushroomFirShape.MIDDLE ? new ItemStack(BlocksRegistry.MUSHROOM_FIR_STEM) : new ItemStack(BlocksRegistry.MUSHROOM_FIR_SAPLING);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ MushroomFirShape shape = state.get(SHAPE);
+ if (shape == MushroomFirShape.SIDE_BIG_N || shape == MushroomFirShape.SIDE_SMALL_N)
+ return world.getBlockState(pos.north()).getBlock() == this;
+ else if (shape == MushroomFirShape.SIDE_BIG_S || shape == MushroomFirShape.SIDE_SMALL_S)
+ return world.getBlockState(pos.south()).getBlock() == this;
+ else if (shape == MushroomFirShape.SIDE_BIG_E || shape == MushroomFirShape.SIDE_SMALL_E)
+ return world.getBlockState(pos.east()).getBlock() == this;
+ else if (shape == MushroomFirShape.SIDE_BIG_W || shape == MushroomFirShape.SIDE_SMALL_W)
+ return world.getBlockState(pos.west()).getBlock() == this;
+ BlockState down = world.getBlockState(pos.down());
+ return down.getBlock() == this || down.isSolidSide(world, pos.down(), Direction.UP);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ return isValidPosition(state, world, pos) ? state : Blocks.AIR.getDefaultState();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockMushroomFirSapling.java b/src/main/java/redd90/betternether/blocks/BlockMushroomFirSapling.java
new file mode 100644
index 0000000..af9e72c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockMushroomFirSapling.java
@@ -0,0 +1,80 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.plants.StructureMushroomFir;
+
+public class BlockMushroomFirSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 14, 12);
+ private static final StructureMushroomFir STRUCTURE = new StructureMushroomFir();
+
+ public BlockMushroomFirSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.LIME)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).getBlock() == BlocksRegistry.NETHER_MYCELIUM;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.generate(world, pos, random);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockNeonEquisetum.java b/src/main/java/redd90/betternether/blocks/BlockNeonEquisetum.java
new file mode 100644
index 0000000..bb4e24e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNeonEquisetum.java
@@ -0,0 +1,150 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import javax.annotation.Nullable;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.shapes.TripleShape;
+
+public class BlockNeonEquisetum extends BlockBaseNotFull implements IGrowable {
+ protected static final VoxelShape SHAPE_SELECTION = Block.makeCuboidShape(2, 0, 2, 14, 16, 14);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockNeonEquisetum() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.GREEN)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .notSolid()
+ .setLightLevel((state) -> {return 15;}));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, TripleShape.BOTTOM));
+ setDropItself(false);
+ }
+
+ public AbstractBlock.OffsetType getOffsetType() {
+ return AbstractBlock.OffsetType.XZ;
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE_SELECTION.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState up = world.getBlockState(pos.up());
+ return up.getBlock() == this || BlocksHelper.isNetherrack(up);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
+ BlockPos upPos = pos.up();
+ if (world.getBlockState(upPos).getBlock() == this) {
+ world.setBlockState(upPos, getDefaultState().with(SHAPE, TripleShape.MIDDLE));
+ upPos = upPos.up();
+ if (world.getBlockState(upPos).getBlock() == this) {
+ world.setBlockState(upPos, getDefaultState().with(SHAPE, TripleShape.TOP));
+ }
+ }
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.getItem().isIn(Tags.Items.SHEARS) || EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ }
+ else {
+ return Lists.newArrayList();
+ }
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ Mutable blockPos = new Mutable().setPos(pos);
+ for (int y = pos.getY() - 1; y > 1; y--) {
+ blockPos.setY(y);
+ if (world.getBlockState(blockPos).getBlock() != this)
+ return world.getBlockState(blockPos).getBlock() == Blocks.AIR;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return true;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ Mutable blockPos = new Mutable().setPos(pos);
+ for (int y = pos.getY(); y > 1; y--) {
+ blockPos.setY(y);
+ if (world.getBlockState(blockPos).getBlock() != this)
+ break;
+ }
+ BlocksHelper.setWithoutUpdate(world, blockPos, this.getDefaultState());
+ this.onBlockPlacedBy(world, blockPos, state, null, null);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherCactus.java b/src/main/java/redd90/betternether/blocks/BlockNetherCactus.java
new file mode 100644
index 0000000..e1f3fa4
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherCactus.java
@@ -0,0 +1,91 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.Entity;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+
+public class BlockNetherCactus extends BlockBaseNotFull {
+ private static final VoxelShape TOP_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 8, 12);
+ private static final VoxelShape SIDE_SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ public static final BooleanProperty TOP = BooleanProperty.create("top");
+
+ public BlockNetherCactus() {
+ super(AbstractBlock.Properties.create(Material.CACTUS, MaterialColor.ORANGE_TERRACOTTA)
+ .sound(SoundType.CLOTH)
+ .notSolid()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(TOP, true));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(TOP);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(TOP).booleanValue() ? TOP_SHAPE : SIDE_SHAPE;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos)) {
+ Block up = world.getBlockState(pos.up()).getBlock();
+ if (up == this)
+ return state.with(TOP, false);
+ else
+ return this.getDefaultState();
+ }
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Block down = world.getBlockState(pos.down()).getBlock();
+ return down == Blocks.GRAVEL || down == this;
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ if (!isValidPosition(state, world, pos)) {
+ world.destroyBlock(pos, true);
+ return;
+ }
+ if (state.get(TOP).booleanValue() && random.nextInt(16) == 0) {
+ BlockPos up = pos.up();
+ boolean grow = world.getBlockState(up).getBlock() == Blocks.AIR;
+ grow = grow && (BlocksHelper.getLengthDown(world, pos, this) < 3);
+ if (grow) {
+ BlocksHelper.setWithUpdate(world, up, getDefaultState());
+ BlocksHelper.setWithUpdate(world, pos, getDefaultState().with(TOP, false));
+ }
+ }
+ }
+
+ @Override
+ public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
+ entity.attackEntityFrom(DamageSource.CACTUS, 1.0F);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherFurnace.java b/src/main/java/redd90/betternether/blocks/BlockNetherFurnace.java
new file mode 100644
index 0000000..9273db8
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherFurnace.java
@@ -0,0 +1,80 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+import java.util.function.ToIntFunction;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.AbstractFurnaceBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.container.INamedContainerProvider;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.stats.Stats;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.Direction;
+import net.minecraft.util.SoundCategory;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.tileentities.TileEntityFurnace;
+
+
+public class BlockNetherFurnace extends AbstractFurnaceBlock {
+ public BlockNetherFurnace(Block source) {
+ super(AbstractBlock.Properties.from(source).setRequiresTool().setLightLevel(getLuminance()));
+ }
+
+ private static ToIntFunction getLuminance() {
+ return (blockState) -> {
+ return (Boolean) blockState.get(BlockStateProperties.LIT) ? 13 : 0;
+ };
+ }
+
+ public TileEntity createNewTileEntity(IBlockReader view) {
+ return new TileEntityFurnace();
+ }
+
+ @Override
+ protected void interactWith(World world, BlockPos pos, PlayerEntity player) {
+ TileEntity blockEntity = world.getTileEntity(pos);
+ if (blockEntity instanceof TileEntityFurnace) {
+ player.openContainer((INamedContainerProvider) blockEntity);
+ player.addStat(Stats.INTERACT_WITH_FURNACE);
+ }
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if ((Boolean) state.get(LIT)) {
+ double d = (double) pos.getX() + 0.5D;
+ double e = (double) pos.getY();
+ double f = (double) pos.getZ() + 0.5D;
+ if (random.nextDouble() < 0.1D) {
+ world.playSound(d, e, f, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, SoundCategory.BLOCKS, 1.0F, 1.0F, false);
+ }
+ Direction direction = (Direction) state.get(FACING);
+ Direction.Axis axis = direction.getAxis();
+ double h = random.nextDouble() * 0.6D - 0.3D;
+ double i = axis == Direction.Axis.X ? (double) direction.getXOffset() * 0.52D : h;
+ double j = random.nextDouble() * 6.0D / 16.0D;
+ double k = axis == Direction.Axis.Z ? (double) direction.getZOffset() * 0.52D : h;
+ world.addParticle(ParticleTypes.SMOKE, d + i, e + j, f + k, 0.0D, 0.0D, 0.0D);
+ world.addParticle(ParticleTypes.FLAME, d + i, e + j, f + k, 0.0D, 0.0D, 0.0D);
+ }
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ List drop = super.getDrops(state, builder);
+ drop.add(new ItemStack(this.asItem()));
+ return drop;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherGrass.java b/src/main/java/redd90/betternether/blocks/BlockNetherGrass.java
new file mode 100644
index 0000000..560bb12
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherGrass.java
@@ -0,0 +1,75 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+
+public class BlockNetherGrass extends BlockBase {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 12, 14);
+
+ public BlockNetherGrass() {
+ super(MaterialBuilder.makeGrass(MaterialColor.GRAY_TERRACOTTA).tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+
+ @Override
+ public Block.OffsetType getOffsetType() {
+ return Block.OffsetType.XZ;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherrack(world.getBlockState(pos.down())) || BlocksHelper.isNylium(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (builder.get(LootParameters.TOOL).getItem().isIn(Tags.Items.SHEARS))
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return super.getDrops(state, builder);
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherMycelium.java b/src/main/java/redd90/betternether/blocks/BlockNetherMycelium.java
new file mode 100644
index 0000000..bdcc6a5
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherMycelium.java
@@ -0,0 +1,61 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Block;
+import net.minecraft.block.Blocks;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public class BlockNetherMycelium extends BlockBase {
+ public static final BooleanProperty IS_BLUE = BooleanProperty.create("blue");
+
+ public BlockNetherMycelium() {
+ super(AbstractBlock.Properties.from(Blocks.NETHERRACK).setRequiresTool());
+ this.setDefaultState(getStateContainer().getBaseState().with(IS_BLUE, false));
+ this.setDropItself(false);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(IS_BLUE);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ super.animateTick(state, world, pos, random);
+ world.addParticle(ParticleTypes.MYCELIUM,
+ pos.getX() + random.nextDouble(),
+ pos.getY() + 1.1D,
+ pos.getZ() + random.nextDouble(),
+ 0.0D, 0.0D, 0.0D);
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool.canHarvestBlock(state)) {
+ if (EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0)
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return Collections.singletonList(new ItemStack(Blocks.NETHERRACK));
+ }
+ else
+ return super.getDrops(state, builder);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherReed.java b/src/main/java/redd90/betternether/blocks/BlockNetherReed.java
new file mode 100644
index 0000000..3a00c67
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherReed.java
@@ -0,0 +1,108 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+
+public class BlockNetherReed extends BlockBase {
+ public static final BooleanProperty TOP = BooleanProperty.create("top");
+
+ public BlockNetherReed() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.CYAN)
+ .sound(SoundType.CROP)
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .notSolid()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(TOP, true));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(TOP);
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightLevel(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ Block up = world.getBlockState(pos.up()).getBlock();
+ BlockState down = world.getBlockState(pos.down());
+ if (BlocksHelper.isNetherGround(down)) {
+ BlockPos posDown = pos.down();
+ boolean lava = BlocksHelper.isLava(world.getBlockState(posDown.north()));
+ lava = lava || BlocksHelper.isLava(world.getBlockState(posDown.south()));
+ lava = lava || BlocksHelper.isLava(world.getBlockState(posDown.east()));
+ lava = lava || BlocksHelper.isLava(world.getBlockState(posDown.west()));
+ if (lava) {
+ return up == this ? this.getDefaultState().with(TOP, false) : this.getDefaultState();
+ }
+ return Blocks.AIR.getDefaultState();
+ }
+ else if (down.getBlock() != this)
+ return Blocks.AIR.getDefaultState();
+ else if (up != this)
+ return this.getDefaultState();
+ else
+ return this.getDefaultState().with(TOP, false);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockPos posDown = pos.down();
+ BlockState down = world.getBlockState(posDown);
+ if (BlocksHelper.isNetherGround(down)) {
+ boolean lava = BlocksHelper.isLava(world.getBlockState(posDown.north()));
+ lava = lava || BlocksHelper.isLava(world.getBlockState(posDown.south()));
+ lava = lava || BlocksHelper.isLava(world.getBlockState(posDown.east()));
+ lava = lava || BlocksHelper.isLava(world.getBlockState(posDown.west()));
+ return lava;
+ }
+ else
+ return down.getBlock() == this;
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ if (!isValidPosition(state, world, pos)) {
+ world.destroyBlock(pos, true);
+ return;
+ }
+ if (state.get(TOP).booleanValue()) {
+ BlockPos up = pos.up();
+ boolean grow = world.isAirBlock(up);
+ if (grow) {
+ int length = BlocksHelper.getLengthDown(world, pos, this);
+ boolean isFertile = BlocksHelper.isFertile(world.getBlockState(pos.down(length)));
+ if (isFertile)
+ length -= 2;
+ grow = (length < 3) && (isFertile ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0));
+ if (grow) {
+ BlocksHelper.setWithUpdate(world, up, getDefaultState());
+ BlocksHelper.setWithUpdate(world, pos, getDefaultState().with(TOP, false));
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherRuby.java b/src/main/java/redd90/betternether/blocks/BlockNetherRuby.java
new file mode 100644
index 0000000..953b5ca
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherRuby.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Blocks;
+
+public class BlockNetherRuby extends BlockBase {
+ public BlockNetherRuby() {
+ super(AbstractBlock.Properties.from(Blocks.DIAMOND_BLOCK));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherSakuraLeaves.java b/src/main/java/redd90/betternether/blocks/BlockNetherSakuraLeaves.java
new file mode 100644
index 0000000..1cb42eb
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherSakuraLeaves.java
@@ -0,0 +1,86 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.particles.BlockParticleData;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockNetherSakuraLeaves extends BlockBaseNotFull {
+ private static final Random RANDOM = new Random();
+ private static final int COLOR = MHelper.color(251, 113, 143);
+
+ public BlockNetherSakuraLeaves() {
+ super(MaterialBuilder.makeLeaves(MaterialColor.PINK).setLightLevel((state) -> {
+ return 13;
+ }));
+ this.setDropItself(false);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return super.getAmbientOcclusionLightValue(state, view, pos) * 0.5F + 0.5F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos) {
+ return VoxelShapes.empty();
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.getItem().isIn(Tags.Items.SHEARS) || EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ }
+ else {
+ return RANDOM.nextInt(5) == 0 ? Lists.newArrayList(new ItemStack(BlocksRegistry.NETHER_SAKURA_SAPLING)) : super.getDrops(state, builder);
+ }
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (random.nextInt(10) == 0) {
+ BlockPos blockPos = pos.down();
+ if (world.isAirBlock(blockPos)) {
+ double x = (double) pos.getX() + random.nextDouble();
+ double y = (double) pos.getY() - 0.05D;
+ double z = (double) pos.getZ() + random.nextDouble();
+ world.addParticle(new BlockParticleData(ParticleTypes.FALLING_DUST, state), x, y, z, 0.0D, 0.0D, 0.0D);
+ }
+ }
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public int getColor(BlockState state, IBlockReader world, BlockPos pos) {
+ return COLOR;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockNetherSakuraSapling.java b/src/main/java/redd90/betternether/blocks/BlockNetherSakuraSapling.java
new file mode 100644
index 0000000..ef6babd
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockNetherSakuraSapling.java
@@ -0,0 +1,80 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureNetherSakura;
+
+public class BlockNetherSakuraSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 2, 4, 12, 16, 12);
+ private static final StructureNetherSakura STRUCTURE = new StructureNetherSakura();
+
+ public BlockNetherSakuraSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.PINK)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly()
+ .setLightLevel((state) -> {return 10;}));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherrack(world.getBlockState(pos.up()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return random.nextInt(16) == 0;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.grow(world, pos, random, false);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockObsidianGlass.java b/src/main/java/redd90/betternether/blocks/BlockObsidianGlass.java
new file mode 100644
index 0000000..a63d730
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockObsidianGlass.java
@@ -0,0 +1,41 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public class BlockObsidianGlass extends BlockBaseNotFull {
+ public BlockObsidianGlass() {
+ super(AbstractBlock.Properties.from(Blocks.OBSIDIAN)
+ .notSolid()
+ .setSuffocates((arg1, arg2, arg3) -> {
+ return false;
+ })
+ .setBlocksVision((arg1, arg2, arg3) -> {
+ return false;
+ }));
+ this.setRenderLayer(BNRenderLayer.TRANSLUCENT);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public boolean isSideInvisible(BlockState state, BlockState neighbor, Direction facing) {
+ return neighbor.getBlock() == this ? true : super.isSideInvisible(state, neighbor, facing);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockOrangeMushroom.java b/src/main/java/redd90/betternether/blocks/BlockOrangeMushroom.java
new file mode 100644
index 0000000..d1cc732
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockOrangeMushroom.java
@@ -0,0 +1,42 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.BlocksHelper;
+
+public class BlockOrangeMushroom extends BlockCommonPlant {
+ private static final VoxelShape[] SHAPES = new VoxelShape[] {
+ VoxelShapes.create(0.25, 0.0, 0.25, 0.75, 0.375, 0.75),
+ VoxelShapes.create(0.125, 0.0, 0.125, 0.875, 0.625, 0.875),
+ VoxelShapes.create(0.0625, 0.0, 0.0625, 0.9375, 0.875, 0.9375),
+ VoxelShapes.create(0.0, 0.0, 0.0, 1.0, 1.0, 1.0)
+ };
+
+ public BlockOrangeMushroom() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.ADOBE)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .hardnessAndResistance(0.5F)
+ .tickRandomly()
+ .doesNotBlockMovement());
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherMycelium(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPES[state.get(AGE)];
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockOre.java b/src/main/java/redd90/betternether/blocks/BlockOre.java
new file mode 100644
index 0000000..9c403b2
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockOre.java
@@ -0,0 +1,53 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.OreBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.util.math.MathHelper;
+import redd90.betternether.MHelper;
+
+public class BlockOre extends OreBlock {
+ private final Item dropItem;
+ private final int minCount;
+ private final int maxCount;
+
+ public BlockOre(Item drop, int minCount, int maxCount) {
+ super(AbstractBlock.Properties.create(Material.ROCK)
+ .setRequiresTool()
+ .hardnessAndResistance(3F, 5F)
+ .sound(SoundType.NETHERRACK));
+ this.dropItem = drop;
+ this.minCount = minCount;
+ this.maxCount = maxCount;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool.canHarvestBlock(state)) {
+ int enchant = EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool);
+ if (enchant > 0) {
+ return Lists.newArrayList(new ItemStack(this));
+ }
+ enchant = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, tool);
+ int min = MathHelper.clamp(minCount + enchant, 0, maxCount);
+ if (min == maxCount)
+ return Lists.newArrayList(new ItemStack(dropItem, maxCount));
+ int count = MHelper.randRange(min, maxCount, MHelper.RANDOM);
+ return Lists.newArrayList(new ItemStack(dropItem, count));
+ }
+ return Lists.newArrayList();
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockPlantWall.java b/src/main/java/redd90/betternether/blocks/BlockPlantWall.java
new file mode 100644
index 0000000..05ad59e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockPlantWall.java
@@ -0,0 +1,103 @@
+package redd90.betternether.blocks;
+
+import java.util.EnumMap;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockPlantWall extends BlockBaseNotFull {
+ private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(ImmutableMap.of(
+ Direction.NORTH, Block.makeCuboidShape(2, 2, 10, 14, 14, 16),
+ Direction.SOUTH, Block.makeCuboidShape(2, 2, 0, 14, 14, 6),
+ Direction.WEST, Block.makeCuboidShape(10, 2, 2, 16, 14, 14),
+ Direction.EAST, Block.makeCuboidShape(0, 2, 2, 6, 14, 14)));
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+
+ public BlockPlantWall(MaterialColor color) {
+ super(MaterialBuilder.makeGrass(color));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return BOUNDING_SHAPES.get(state.get(FACING));
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING);
+ BlockPos blockPos = pos.offset(direction.getOpposite());
+ BlockState blockState = world.getBlockState(blockPos);
+ return blockState.isSolidSide(world, blockPos, direction);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ IWorldReader IWorldReader = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ for (int i = 0; i < directions.length; ++i) {
+ Direction direction = directions[i];
+ if (direction.getAxis().isHorizontal()) {
+ Direction direction2 = direction.getOpposite();
+ blockState = blockState.with(FACING, direction2);
+ if (blockState.isValidPosition(IWorldReader, blockPos)) {
+ return blockState;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockPottedPlant.java b/src/main/java/redd90/betternether/blocks/BlockPottedPlant.java
new file mode 100644
index 0000000..40ee22f
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockPottedPlant.java
@@ -0,0 +1,130 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.ToIntFunction;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockPottedPlant extends BlockBaseNotFull {
+ public static final EnumProperty PLANT = EnumProperty.create("plant", PottedPlantShape.class);
+
+ public BlockPottedPlant() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.BLACK)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .setLightLevel(getLuminance()));
+ this.setDropItself(false);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(PLANT, PottedPlantShape.AGAVE));
+ }
+
+ private static ToIntFunction getLuminance() {
+ return (blockState) -> {
+ if (blockState.get(PLANT) == PottedPlantShape.WILLOW)
+ return 12;
+ else if (blockState.get(PLANT) == PottedPlantShape.JELLYFISH_MUSHROOM)
+ return 13;
+ else
+ return 0;
+ };
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Block block = state.get(PLANT).getBlock();
+ Vector3d vec3d = block.getDefaultState().getOffset(view, pos);
+ return block.getShape(block.getDefaultState(), view, pos, ePos).withOffset(-vec3d.x, -0.5 - vec3d.y, -vec3d.z);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(PLANT);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.down()).getBlock() instanceof BlockBNPot;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ Block block = state.get(PLANT).getBlock();
+ return Collections.singletonList(new ItemStack(block.asItem()));
+ }
+
+ public static BlockState getPlant(Item item) {
+ for (PottedPlantShape shape : PottedPlantShape.values()) {
+ if (shape.getItem().equals(item))
+ return BlocksRegistry.POTTED_PLANT.getDefaultState().with(PLANT, shape);
+ }
+ return null;
+ }
+
+ public static enum PottedPlantShape implements IStringSerializable {
+ AGAVE("agave", BlocksRegistry.AGAVE), BARREL_CACTUS("barrel_cactus", BlocksRegistry.BARREL_CACTUS), BLACK_APPLE("black_apple", BlocksRegistry.BLACK_APPLE_SEED), BLACK_BUSH("black_bush", BlocksRegistry.BLACK_BUSH), EGG_PLANT("egg_plant",
+ BlocksRegistry.EGG_PLANT), INK_BUSH("ink_bush", BlocksRegistry.INK_BUSH_SEED), REEDS("reeds", BlocksRegistry.NETHER_REED), NETHER_CACTUS("nether_cactus", BlocksRegistry.NETHER_CACTUS), NETHER_GRASS("nether_grass",
+ BlocksRegistry.NETHER_GRASS), ORANGE_MUSHROOM("orange_mushroom", BlocksRegistry.ORANGE_MUSHROOM), RED_MOLD("red_mold", BlocksRegistry.RED_MOLD), GRAY_MOLD("gray_mold", BlocksRegistry.GRAY_MOLD), MAGMA_FLOWER("magma_flower",
+ BlocksRegistry.MAGMA_FLOWER), NETHER_WART("nether_wart", BlocksRegistry.WART_SEED), WILLOW("willow", BlocksRegistry.WILLOW_SAPLING), SMOKER("smoker", BlocksRegistry.SMOKER), WART("wart",
+ Blocks.NETHER_WART), JUNGLE_PLANT("jungle_plant", BlocksRegistry.JUNGLE_PLANT), JELLYFISH_MUSHROOM("jellyfish_mushroom", BlocksRegistry.JELLYFISH_MUSHROOM_SAPLING), SWAMP_GRASS("swamp_grass",
+ BlocksRegistry.SWAMP_GRASS), SOUL_GRASS("soul_grass", BlocksRegistry.SOUL_GRASS), BONE_GRASS("bone_grass", BlocksRegistry.BONE_GRASS), BONE_MUSHROOM("bone_mushroom", BlocksRegistry.BONE_MUSHROOM);
+
+ private final Block block;
+ private final String name;
+
+ private PottedPlantShape(String name, Block block) {
+ this.name = name;
+ this.block = block;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public Item getItem() {
+ return block.asItem();
+ }
+
+ public Block getBlock() {
+ return block;
+ }
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockRedLargeMushroom.java b/src/main/java/redd90/betternether/blocks/BlockRedLargeMushroom.java
new file mode 100644
index 0000000..ea1d923
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockRedLargeMushroom.java
@@ -0,0 +1,61 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockRedLargeMushroom extends BlockBaseNotFull {
+ private static final VoxelShape TOP_SHAPE = Block.makeCuboidShape(0, 0.1, 0, 16, 16, 16);
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockRedLargeMushroom() {
+ super(MaterialBuilder.makeWood(MaterialColor.RED).notSolid());
+ this.setDropItself(false);
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(SHAPE) == TripleShape.TOP ? TOP_SHAPE : MIDDLE_SHAPE;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return state.get(SHAPE) == TripleShape.TOP ? new ItemStack(Items.RED_MUSHROOM) : new ItemStack(BlocksRegistry.MUSHROOM_STEM);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ switch (state.get(SHAPE)) {
+ case BOTTOM:
+ return state;
+ case MIDDLE:
+ case TOP:
+ default:
+ return world.getBlockState(pos.down()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockRedMold.java b/src/main/java/redd90/betternether/blocks/BlockRedMold.java
new file mode 100644
index 0000000..6e832b1
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockRedMold.java
@@ -0,0 +1,24 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.IBlockReader;
+
+public class BlockRedMold extends BlockMold {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(2, 0, 2, 14, 12, 14);
+
+ public BlockRedMold() {
+ super(MaterialColor.RED_TERRACOTTA);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ Vector3d vec3d = state.getOffset(view, pos);
+ return SHAPE.withOffset(vec3d.x, vec3d.y, vec3d.z);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockReedsBlock.java b/src/main/java/redd90/betternether/blocks/BlockReedsBlock.java
new file mode 100644
index 0000000..a0200b1
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockReedsBlock.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockReedsBlock extends BNPillar {
+ public BlockReedsBlock() {
+ super(MaterialBuilder.makeWood(MaterialColor.CYAN));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockRubeusCone.java b/src/main/java/redd90/betternether/blocks/BlockRubeusCone.java
new file mode 100644
index 0000000..9694935
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockRubeusCone.java
@@ -0,0 +1,40 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockRubeusCone extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(3, 3, 3, 13, 16, 13);
+
+ public BlockRubeusCone() {
+ super(MaterialBuilder.makeWood(MaterialColor.CYAN).notSolid().setLightLevel((state) -> {return 15;}));
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return world.getBlockState(pos.up()).isSolidSide(world, pos.up(), Direction.DOWN);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockRubeusLeaves.java b/src/main/java/redd90/betternether/blocks/BlockRubeusLeaves.java
new file mode 100644
index 0000000..5576312
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockRubeusLeaves.java
@@ -0,0 +1,116 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.IntegerProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockRubeusLeaves extends BlockBase {
+ private static final int MAX_DIST = 10;
+ public static final IntegerProperty DISTANCE_CUSTOM = IntegerProperty.create("dist_custom", 1, MAX_DIST);
+ public static final BooleanProperty PERSISTENT = BlockStateProperties.PERSISTENT;
+
+ public BlockRubeusLeaves() {
+ super(MaterialBuilder.makeLeaves(MaterialColor.LIGHT_BLUE));
+ this.setDefaultState(this.stateContainer.getBaseState().with(DISTANCE_CUSTOM, 1).with(PERSISTENT, false));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder builder) {
+ builder.add(PERSISTENT, DISTANCE_CUSTOM);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return updateDistanceFromLogs((BlockState) this.getDefaultState().with(PERSISTENT, true), ctx.getWorld(), ctx.getPos());
+ }
+
+ @Override
+ public boolean ticksRandomly(BlockState state) {
+ return state.get(DISTANCE_CUSTOM) == MAX_DIST && !(Boolean) state.get(PERSISTENT);
+ }
+
+ @Override
+ public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ if (!state.get(PERSISTENT) && state.get(DISTANCE_CUSTOM) == MAX_DIST) {
+ spawnDrops(state, world, pos);
+ world.removeBlock(pos, false);
+ }
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ world.setBlockState(pos, updateDistanceFromLogs(state, world, pos), 3);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState newState, IWorld world, BlockPos pos, BlockPos posFrom) {
+ int dist = getDistanceFromLog(newState) + 1;
+ if (dist != 1 || state.get(DISTANCE_CUSTOM) != dist) {
+ world.getPendingBlockTicks().scheduleTick(pos, this, 1);
+ }
+
+ return state;
+ }
+
+ private static BlockState updateDistanceFromLogs(BlockState state, IWorld world, BlockPos pos) {
+ int dist = MAX_DIST;
+ BlockPos.Mutable mutable = new BlockPos.Mutable();
+ Direction[] dirs = Direction.values();
+ int count = dirs.length;
+
+ for (int n = 0; n < count; ++n) {
+ Direction dir = dirs[n];
+ mutable.setAndMove(pos, dir);
+ dist = Math.min(dist, getDistanceFromLog(world.getBlockState(mutable)) + 1);
+ if (dist == 1) {
+ break;
+ }
+ }
+
+ return (BlockState) state.with(DISTANCE_CUSTOM, dist);
+ }
+
+ private static int getDistanceFromLog(BlockState state) {
+ if (state.getBlock() == BlocksRegistry.RUBEUS_LOG || state.getBlock() == BlocksRegistry.RUBEUS_BARK) {
+ return 0;
+ }
+ else {
+ return state.getBlock() instanceof BlockRubeusLeaves ? state.get(DISTANCE_CUSTOM) : MAX_DIST;
+ }
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (world.isRainingAt(pos.up())) {
+ if (random.nextInt(15) == 1) {
+ BlockPos blockPos = pos.down();
+ BlockState blockState = world.getBlockState(blockPos);
+ if (!blockState.isSolid() || !blockState.isSolidSide(world, blockPos, Direction.UP)) {
+ double d = (double) ((float) pos.getX() + random.nextFloat());
+ double e = (double) pos.getY() - 0.05D;
+ double f = (double) ((float) pos.getZ() + random.nextFloat());
+ world.addParticle(ParticleTypes.DRIPPING_WATER, d, e, f, 0.0D, 0.0D, 0.0D);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockRubeusSapling.java b/src/main/java/redd90/betternether/blocks/BlockRubeusSapling.java
new file mode 100644
index 0000000..14ef4ac
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockRubeusSapling.java
@@ -0,0 +1,79 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureRubeus;
+
+public class BlockRubeusSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 14, 12);
+ private static final StructureRubeus STRUCTURE = new StructureRubeus();
+
+ public BlockRubeusSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .noDrops()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherGround(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.grow(world, pos, random, false);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockSmallLantern.java b/src/main/java/redd90/betternether/blocks/BlockSmallLantern.java
new file mode 100644
index 0000000..2048678
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSmallLantern.java
@@ -0,0 +1,104 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockSmallLantern extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE_NORTH = Block.makeCuboidShape(5, 0, 8, 11, 16, 16);
+ private static final VoxelShape SHAPE_SOUTH = Block.makeCuboidShape(5, 0, 0, 11, 16, 8);
+ private static final VoxelShape SHAPE_WEST = Block.makeCuboidShape(8, 0, 5, 16, 16, 11);
+ private static final VoxelShape SHAPE_EAST = Block.makeCuboidShape(0, 0, 5, 8, 16, 11);
+ private static final VoxelShape SHAPE_UP = Block.makeCuboidShape(5, 0, 5, 11, 9, 11);
+ private static final VoxelShape SHAPE_DOWN = Block.makeCuboidShape(5, 3, 5, 11, 16, 11);
+
+ public static final DirectionProperty FACING = BlockStateProperties.FACING;
+
+ public BlockSmallLantern() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_LANTERN).notSolid());
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.DOWN));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ switch (state.get(FACING)) {
+ case NORTH:
+ return SHAPE_NORTH;
+ case SOUTH:
+ return SHAPE_SOUTH;
+ case EAST:
+ return SHAPE_EAST;
+ case WEST:
+ return SHAPE_WEST;
+ case UP:
+ return SHAPE_UP;
+ case DOWN:
+ default:
+ return SHAPE_DOWN;
+ }
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING).getOpposite();
+ return Block.hasEnoughSolidSide(world, pos.offset(direction), direction.getOpposite());
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ IWorldReader worldView = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ for (int i = 0; i < directions.length; ++i) {
+ Direction direction = directions[i];
+ Direction direction2 = direction.getOpposite();
+ blockState = blockState.with(FACING, direction2);
+ if (blockState.isValidPosition(worldView, blockPos)) {
+ return blockState;
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockSmoker.java b/src/main/java/redd90/betternether/blocks/BlockSmoker.java
new file mode 100644
index 0000000..a96a03c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSmoker.java
@@ -0,0 +1,74 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.blocks.shapes.TripleShape;
+
+public class BlockSmoker extends BlockBaseNotFull {
+ private static final VoxelShape TOP_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 8, 12);
+ private static final VoxelShape MIDDLE_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockSmoker() {
+ super(MaterialBuilder.makeWood(MaterialColor.BROWN));
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, TripleShape.TOP));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (world.isAirBlock(pos.up()))
+ world.addParticle(ParticleTypes.LARGE_SMOKE, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 0, 0, 0);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(SHAPE) == TripleShape.TOP ? TOP_SHAPE : MIDDLE_SHAPE;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos)) {
+ return Blocks.AIR.getDefaultState();
+ }
+ Block side = world.getBlockState(pos.up()).getBlock();
+ if (side != this)
+ return state.with(SHAPE, TripleShape.TOP);
+ side = world.getBlockState(pos.down()).getBlock();
+ if (side == this)
+ return state.with(SHAPE, TripleShape.MIDDLE);
+ else
+ return state.with(SHAPE, TripleShape.BOTTOM);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState down = world.getBlockState(pos.down());
+ return down.getBlock() == this || BlocksHelper.isNetherGround(down);
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockSoulGrass.java b/src/main/java/redd90/betternether/blocks/BlockSoulGrass.java
new file mode 100644
index 0000000..5241b46
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSoulGrass.java
@@ -0,0 +1,34 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+
+public class BlockSoulGrass extends BlockNetherGrass {
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isSoulSand(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public void animateTick(BlockState state, World world, BlockPos pos, Random random) {
+ if (random.nextInt(4) == 0) {
+ world.addParticle(
+ ParticleTypes.PORTAL,
+ pos.getX() + random.nextDouble(),
+ pos.getY() + random.nextDouble() * 2,
+ pos.getZ() + random.nextDouble(),
+ random.nextDouble() * 0.05,
+ -1,
+ random.nextDouble() * 0.05);
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockSoulLily.java b/src/main/java/redd90/betternether/blocks/BlockSoulLily.java
new file mode 100644
index 0000000..6ef2605
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSoulLily.java
@@ -0,0 +1,240 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.structures.plants.StructureSoulLily;
+
+public class BlockSoulLily extends BlockBaseNotFull {
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", SoulLilyShape.class);
+
+ private static final VoxelShape SHAPE_SMALL = Block.makeCuboidShape(6, 0, 6, 10, 16, 10);
+ private static final VoxelShape SHAPE_MEDIUM_BOTTOM = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ private static final VoxelShape SHAPE_MEDIUM_TOP = Block.makeCuboidShape(0, 0, 0, 16, 3, 16);
+ private static final VoxelShape SHAPE_BIG_BOTTOM = Block.makeCuboidShape(3, 0, 3, 13, 16, 13);
+ private static final VoxelShape SHAPE_BIG_MIDDLE = Block.makeCuboidShape(6, 0, 6, 10, 16, 10);
+ private static final VoxelShape SHAPE_BIG_TOP_CENTER = Block.makeCuboidShape(0, 0, 0, 16, 4, 16);
+ private static final VoxelShape SHAPE_BIG_TOP_SIDE_N = Block.makeCuboidShape(0, 4, 0, 16, 6, 8);
+ private static final VoxelShape SHAPE_BIG_TOP_SIDE_S = Block.makeCuboidShape(0, 4, 8, 16, 6, 16);
+ private static final VoxelShape SHAPE_BIG_TOP_SIDE_E = Block.makeCuboidShape(8, 4, 0, 16, 6, 16);
+ private static final VoxelShape SHAPE_BIG_TOP_SIDE_W = Block.makeCuboidShape(0, 4, 0, 8, 6, 16);
+
+ private static final StructureSoulLily STRUCTURE = new StructureSoulLily();
+
+ private static final SoulLilyShape[] ROT = new SoulLilyShape[] {
+ SoulLilyShape.BIG_TOP_SIDE_N,
+ SoulLilyShape.BIG_TOP_SIDE_E,
+ SoulLilyShape.BIG_TOP_SIDE_S,
+ SoulLilyShape.BIG_TOP_SIDE_W
+ };
+
+ public BlockSoulLily() {
+ super(MaterialBuilder.makeWood(MaterialColor.ADOBE).notSolid().tickRandomly());
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, SoulLilyShape.SMALL));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ public VoxelShape getOutlineShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ switch (state.get(SHAPE)) {
+ case BIG_BOTTOM:
+ return SHAPE_BIG_BOTTOM;
+ case BIG_MIDDLE:
+ return SHAPE_BIG_MIDDLE;
+ case BIG_TOP_CENTER:
+ return SHAPE_BIG_TOP_CENTER;
+ case MEDIUM_BOTTOM:
+ return SHAPE_MEDIUM_BOTTOM;
+ case MEDIUM_TOP:
+ return SHAPE_MEDIUM_TOP;
+ case BIG_TOP_SIDE_N:
+ return SHAPE_BIG_TOP_SIDE_N;
+ case BIG_TOP_SIDE_S:
+ return SHAPE_BIG_TOP_SIDE_S;
+ case BIG_TOP_SIDE_E:
+ return SHAPE_BIG_TOP_SIDE_E;
+ case BIG_TOP_SIDE_W:
+ return SHAPE_BIG_TOP_SIDE_W;
+ case SMALL:
+ default:
+ return SHAPE_SMALL;
+ }
+ }
+
+ public enum SoulLilyShape implements IStringSerializable {
+ SMALL("small"), MEDIUM_BOTTOM("medium_bottom"), MEDIUM_TOP("medium_top"), BIG_BOTTOM("big_bottom"), BIG_MIDDLE("big_middle"), BIG_TOP_CENTER("big_top_center"), BIG_TOP_SIDE_N("big_top_side_n"), BIG_TOP_SIDE_S(
+ "big_top_side_s"), BIG_TOP_SIDE_E("big_top_side_e"), BIG_TOP_SIDE_W("big_top_side_w");
+
+ final String name;
+
+ SoulLilyShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ public boolean canGrow(World world, BlockPos pos, Random random) {
+ BlockState state = world.getBlockState(pos.down());
+ if (state.getBlock() == this || state.getBlock() == Blocks.SOUL_SAND || BlocksHelper.isFertile(world.getBlockState(pos.down()))) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+ return false;
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canGrow(world, pos, random)) {
+ SoulLilyShape shape = state.get(SHAPE);
+ if (shape == SoulLilyShape.SMALL && world.isAirBlock(pos.up())) {
+ STRUCTURE.growMedium(world, pos);
+ }
+ else if (shape == SoulLilyShape.MEDIUM_BOTTOM && world.isAirBlock(pos.up(2)) && isAirSides(world, pos.up(2))) {
+ STRUCTURE.growBig(world, pos);
+ }
+ }
+ }
+
+ private boolean isAirSides(World world, BlockPos pos) {
+ return world.isAirBlock(pos.north()) && world.isAirBlock(pos.south()) && world.isAirBlock(pos.east()) && world.isAirBlock(pos.west());
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ SoulLilyShape shape = state.get(SHAPE);
+ int index = getRotationIndex(shape);
+ if (index < 0)
+ return state;
+ int offset = rotOffset(rotation);
+ return state.with(SHAPE, ROT[(index + offset) & 3]);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ SoulLilyShape shape = state.get(SHAPE);
+ int index = getRotationIndex(shape);
+ if (index < 0)
+ return state;
+ if (mirror == Mirror.FRONT_BACK) {
+ if (shape == SoulLilyShape.BIG_TOP_SIDE_E)
+ shape = SoulLilyShape.BIG_TOP_SIDE_W;
+ else if (shape == SoulLilyShape.BIG_TOP_SIDE_W)
+ shape = SoulLilyShape.BIG_TOP_SIDE_E;
+ }
+ else if (mirror == Mirror.LEFT_RIGHT) {
+ if (shape == SoulLilyShape.BIG_TOP_SIDE_N)
+ shape = SoulLilyShape.BIG_TOP_SIDE_S;
+ else if (shape == SoulLilyShape.BIG_TOP_SIDE_S)
+ shape = SoulLilyShape.BIG_TOP_SIDE_N;
+ }
+ return state.with(SHAPE, shape);
+ }
+
+ private int getRotationIndex(SoulLilyShape shape) {
+ for (int i = 0; i < 4; i++) {
+ if (shape == ROT[i])
+ return i;
+ }
+ return -1;
+ }
+
+ private int rotOffset(Rotation rotation) {
+ if (rotation == Rotation.NONE)
+ return 0;
+ else if (rotation == Rotation.CLOCKWISE_90)
+ return 1;
+ else if (rotation == Rotation.CLOCKWISE_180)
+ return 2;
+ else
+ return 3;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.SOUL_LILY_SAPLING);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ SoulLilyShape shape = state.get(SHAPE);
+ if (shape == SoulLilyShape.BIG_TOP_SIDE_N)
+ return world.getBlockState(pos.north()).getBlock() == this;
+ if (shape == SoulLilyShape.BIG_TOP_SIDE_S)
+ return world.getBlockState(pos.south()).getBlock() == this;
+ if (shape == SoulLilyShape.BIG_TOP_SIDE_E)
+ return world.getBlockState(pos.east()).getBlock() == this;
+ if (shape == SoulLilyShape.BIG_TOP_SIDE_W)
+ return world.getBlockState(pos.west()).getBlock() == this;
+ BlockState down = world.getBlockState(pos.down());
+ return down.getBlock() == this || BlocksHelper.isSoulSand(down);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ return isValidPosition(state, world, pos) ? state : Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ switch (state.get(SHAPE)) {
+ case BIG_BOTTOM:
+ case BIG_MIDDLE:
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.MUSHROOM_STEM));
+ case BIG_TOP_CENTER:
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.MUSHROOM_STEM), new ItemStack(BlocksRegistry.SOUL_LILY_SAPLING));
+ case MEDIUM_BOTTOM:
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.MUSHROOM_STEM));
+ case BIG_TOP_SIDE_N:
+ case BIG_TOP_SIDE_S:
+ case BIG_TOP_SIDE_E:
+ case BIG_TOP_SIDE_W:
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.MUSHROOM_STEM), new ItemStack(BlocksRegistry.SOUL_LILY_SAPLING, MHelper.randRange(0, 1, MHelper.RANDOM)));
+ case SMALL:
+ case MEDIUM_TOP:
+ default:
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.MUSHROOM_STEM), new ItemStack(BlocksRegistry.SOUL_LILY_SAPLING));
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockSoulLilySapling.java b/src/main/java/redd90/betternether/blocks/BlockSoulLilySapling.java
new file mode 100644
index 0000000..80f98fe
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSoulLilySapling.java
@@ -0,0 +1,20 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockSoulLilySapling extends BlockCommonSapling {
+ public BlockSoulLilySapling() {
+ super(BlocksRegistry.SOUL_LILY, MaterialColor.ADOBE);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState ground = world.getBlockState(pos.down());
+ return BlocksHelper.isSoulSand(ground) || ground.getBlock() == BlocksRegistry.FARMLAND;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockSoulSandstone.java b/src/main/java/redd90/betternether/blocks/BlockSoulSandstone.java
new file mode 100644
index 0000000..11a4f36
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSoulSandstone.java
@@ -0,0 +1,35 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IWorld;
+
+public class BlockSoulSandstone extends BlockBase {
+ public static final BooleanProperty UP = BooleanProperty.create("up");
+
+ public BlockSoulSandstone() {
+ super(AbstractBlock.Properties.from(Blocks.SANDSTONE));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(UP);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ return state.with(UP, world.getBlockState(pos.up()).getBlock() != this);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return this.getDefaultState().with(UP, ctx.getWorld().getBlockState(ctx.getPos().up()).getBlock() != this);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockSoulVein.java b/src/main/java/redd90/betternether/blocks/BlockSoulVein.java
new file mode 100644
index 0000000..7227031
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockSoulVein.java
@@ -0,0 +1,91 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockSoulVein extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(0, 0, 0, 16, 1, 16);
+
+ public BlockSoulVein() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.PURPLE)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Block block = world.getBlockState(pos.down()).getBlock();
+ return block == Blocks.SOUL_SAND || block == BlocksRegistry.VEINED_SAND;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return true;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ spawnAsEntity(world, pos, new ItemStack(this.asItem()));
+ }
+
+ public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
+ if (world.getBlockState(pos.down()).getBlock() == Blocks.SOUL_SAND)
+ world.setBlockState(pos.down(), BlocksRegistry.VEINED_SAND.getDefaultState());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (builder.get(LootParameters.TOOL).getItem().isIn(Tags.Items.SHEARS))
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return super.getDrops(state, builder);
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockStalactite.java b/src/main/java/redd90/betternether/blocks/BlockStalactite.java
new file mode 100644
index 0000000..dc09fd6
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockStalactite.java
@@ -0,0 +1,113 @@
+package redd90.betternether.blocks;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.state.IntegerProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+
+public class BlockStalactite extends BlockBaseNotFull {
+ public static final IntegerProperty SIZE = IntegerProperty.create("size", 0, 7);
+ private static final Mutable POS = new Mutable();
+ private static final VoxelShape[] SHAPES;
+
+ public BlockStalactite(Block source) {
+ super(AbstractBlock.Properties.from(source).notSolid());
+ this.setDefaultState(getStateContainer().getBaseState().with(SIZE, 0));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SIZE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPES[state.get(SIZE)];
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
+ if (world.getBlockState(pos.down()).getBlock() instanceof BlockStalactite) {
+ POS.setX(pos.getX());
+ POS.setZ(pos.getZ());
+ for (int i = 1; i < 8; i++) {
+ POS.setY(pos.getY() - i);
+ if (world.getBlockState(POS).getBlock() instanceof BlockStalactite) {
+ BlockState state2 = world.getBlockState(POS);
+ int size = state2.get(SIZE);
+ if (size < i) {
+ world.setBlockState(POS, state2.with(SIZE, i));
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ }
+ if (world.getBlockState(pos.up()).getBlock() instanceof BlockStalactite) {
+ POS.setX(pos.getX());
+ POS.setZ(pos.getZ());
+ for (int i = 1; i < 8; i++) {
+ POS.setY(pos.getY() + i);
+ if (world.getBlockState(POS).getBlock() instanceof BlockStalactite) {
+ BlockState state2 = world.getBlockState(POS);
+ int size = state2.get(SIZE);
+ if (size < i) {
+ world.setBlockState(POS, state2.with(SIZE, i));
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void onPlayerDestroy(IWorld world, BlockPos pos, BlockState state) {
+ BlockPos pos2 = pos.up();
+ BlockState state2 = world.getBlockState(pos2);
+ if (state2.getBlock() instanceof BlockStalactite && state2.get(SIZE) < state.get(SIZE)) {
+ state2.getBlock().onPlayerDestroy(world, pos2, state2);
+ world.destroyBlock(pos2, true);
+ }
+
+ pos2 = pos.down();
+ state2 = world.getBlockState(pos2);
+ if (state2.getBlock() instanceof BlockStalactite && state2.get(SIZE) < state.get(SIZE)) {
+ state2.getBlock().onPlayerDestroy(world, pos2, state2);
+ world.destroyBlock(pos2, true);
+ }
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return canPlace(world, pos, Direction.UP) || canPlace(world, pos, Direction.DOWN);
+ }
+
+ private boolean canPlace(IWorldReader world, BlockPos pos, Direction dir) {
+ return world.getBlockState(pos.offset(dir)).getBlock() instanceof BlockStalactite || Block.hasEnoughSolidSide(world, pos.offset(dir), dir.getOpposite());
+ }
+
+ static {
+ SHAPES = new VoxelShape[8];
+ for (int i = 0; i < 8; i++)
+ SHAPES[i] = Block.makeCuboidShape(7 - i, 0, 7 - i, 9 + i, 16, 9 + i);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockStalagnate.java b/src/main/java/redd90/betternether/blocks/BlockStalagnate.java
new file mode 100644
index 0000000..1292dec
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockStalagnate.java
@@ -0,0 +1,51 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockStalagnate extends BlockBaseNotFull {
+ private static final VoxelShape SELECT_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ private static final VoxelShape COLLISION_SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 16, 11);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockStalagnate() {
+ super(MaterialBuilder.makeWood(MaterialColor.LIME_TERRACOTTA).notSolid());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, TripleShape.MIDDLE));
+ this.setDropItself(false);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SELECT_SHAPE;
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return COLLISION_SHAPE;
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(BlocksRegistry.STALAGNATE_STEM);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockStalagnateBowl.java b/src/main/java/redd90/betternether/blocks/BlockStalagnateBowl.java
new file mode 100644
index 0000000..c773104
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockStalagnateBowl.java
@@ -0,0 +1,62 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.blocks.shapes.FoodShape;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockStalagnateBowl extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(5, 0, 5, 11, 3, 11);
+ public static final EnumProperty FOOD = EnumProperty.create("food", FoodShape.class);
+
+ public BlockStalagnateBowl() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.STALAGNATE).notSolid());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(FOOD, FoodShape.NONE));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FOOD);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ return Collections.singletonList(new ItemStack(state.get(FOOD).getItem()));
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockPos down = pos.down();
+ return world.getBlockState(down).isSolidSide(world, down, Direction.UP);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockStalagnateSeed.java b/src/main/java/redd90/betternether/blocks/BlockStalagnateSeed.java
new file mode 100644
index 0000000..1fd3a74
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockStalagnateSeed.java
@@ -0,0 +1,117 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureStalagnate;
+
+public class BlockStalagnateSeed extends BlockBaseNotFull implements IGrowable {
+ protected static final VoxelShape SHAPE_TOP = Block.makeCuboidShape(4, 6, 4, 12, 16, 12);
+ protected static final VoxelShape SHAPE_BOTTOM = Block.makeCuboidShape(4, 0, 4, 12, 12, 12);
+ private static final StructureStalagnate STRUCTURE = new StructureStalagnate();
+ public static final BooleanProperty TOP = BooleanProperty.create("top");
+
+ public BlockStalagnateSeed() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.CYAN)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(TOP, true));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(TOP);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ if (ctx.getFace() == Direction.DOWN)
+ return blockState;
+ else if (ctx.getFace() == Direction.UP)
+ return blockState.with(TOP, false);
+ else
+ return null;
+ }
+
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(TOP).booleanValue() ? SHAPE_TOP : SHAPE_BOTTOM;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ if (random.nextInt(16) == 0) {
+ if (state.get(TOP).booleanValue())
+ return BlocksHelper.downRay(world, pos, StructureStalagnate.MIN_LENGTH) > 0;
+ else
+ return BlocksHelper.upRay(world, pos, StructureStalagnate.MIN_LENGTH) > 0;
+ }
+ return false;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ if (state.get(TOP).booleanValue())
+ STRUCTURE.generateDown(world, pos, random);
+ else
+ STRUCTURE.generate(world, pos, random);
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherrack(world.getBlockState(pos.up())) || BlocksHelper.isNetherrack(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (state.get(TOP).booleanValue()) {
+ if (BlocksHelper.isNetherrack(world.getBlockState(pos.up())))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+ else {
+ if (BlocksHelper.isNetherrack(world.getBlockState(pos.down())))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state)) {
+ grow(world, random, pos, state);
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockStatueRespawner.java b/src/main/java/redd90/betternether/blocks/BlockStatueRespawner.java
new file mode 100644
index 0000000..adfe640
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockStatueRespawner.java
@@ -0,0 +1,145 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.particles.RedstoneParticleData;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.text.TranslationTextComponent;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.registries.ForgeRegistries;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.config.Configs;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockStatueRespawner extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(1, 0, 1, 15, 16, 15);
+ private static final RedstoneParticleData EFFECT = new RedstoneParticleData(1, 0, 0, 1.0F);
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+ public static final BooleanProperty TOP = BooleanProperty.create("top");
+ private final ItemStack requiredItem;
+
+ public BlockStatueRespawner() {
+ super(AbstractBlock.Properties.from(BlocksRegistry.CINCINNASITE_BLOCK).notSolid().setLightLevel((state) -> {return 15;}));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.NORTH).with(TOP, false));
+ this.setDropItself(false);
+
+ String itemName = Configs.MAIN.getString("respawn_statue", "respawn_item", ForgeRegistries.ITEMS.getKey(Items.GLOWSTONE).toString());
+ Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemName));
+ if (item == Items.AIR)
+ item = Items.GLOWSTONE;
+ int count = Configs.MAIN.getInt("respawn_statue", "item_count", 4);
+ requiredItem = new ItemStack(item, count);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING, TOP);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return this.getDefaultState().with(FACING, ctx.getPlacementHorizontalFacing().getOpposite());
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ ItemStack stack = player.getHeldItemMainhand();
+ if (stack.getItem() == requiredItem.getItem() && stack.getCount() >= requiredItem.getCount()) {
+ float y = state.get(TOP) ? 0.4F : 1.4F;
+ if (!player.isCreative()) {
+ player.getHeldItemMainhand().shrink(requiredItem.getCount());
+ }
+ for (int i = 0; i < 50; i++)
+ world.addParticle(EFFECT,
+ pos.getX() + world.rand.nextFloat(),
+ pos.getY() + y + world.rand.nextFloat() * 0.2,
+ pos.getZ() + world.rand.nextFloat(), 0, 0, 0);
+ player.sendStatusMessage(new TranslationTextComponent("message.spawn_set", new Object[0]), true);
+ if (!world.isRemote) {
+ ((ServerPlayerEntity) player).func_242111_a(world.getDimensionKey(), pos, player.getRotationYawHead(), false, true);
+ }
+ player.playSound(SoundEvents.ITEM_TOTEM_USE, 0.7F, 1.0F);
+ return ActionResultType.SUCCESS;
+ }
+ else {
+ player.sendStatusMessage(new TranslationTextComponent("message.spawn_help", requiredItem), true);
+ }
+ return ActionResultType.SUCCESS;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ if (state.get(TOP))
+ return true;
+ BlockState up = world.getBlockState(pos.up());
+ return up.isAir() || (up.getBlock() == this && up.get(TOP));
+ }
+
+ @Override
+ public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
+ if (!world.isRemote())
+ BlocksHelper.setWithUpdate((ServerWorld) world, pos.up(), state.with(TOP, true));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (state.get(TOP)) {
+ return world.getBlockState(pos.down()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ else {
+ return world.getBlockState(pos.up()).getBlock() == this ? state : Blocks.AIR.getDefaultState();
+ }
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public void onBlockHarvested(World world, BlockPos pos, BlockState state, PlayerEntity player) {
+ if (player.isCreative() && state.get(TOP) && world.getBlockState(pos.down()).getBlock() == this) {
+ world.setBlockState(pos.down(), Blocks.AIR.getDefaultState());
+ }
+ super.onBlockHarvested(world, pos, state, player);
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockStem.java b/src/main/java/redd90/betternether/blocks/BlockStem.java
new file mode 100644
index 0000000..5025d6c
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockStem.java
@@ -0,0 +1,76 @@
+package redd90.betternether.blocks;
+
+import java.util.EnumMap;
+
+import com.google.common.collect.Maps;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Direction.Axis;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+
+public class BlockStem extends BlockBaseNotFull {
+ public static final EnumProperty AXIS = BlockStateProperties.AXIS;
+ private static final EnumMap OUTLINES = Maps.newEnumMap(Axis.class);
+
+ public BlockStem(MaterialColor color) {
+ super(MaterialBuilder.makeWood(color).notSolid());
+ this.setDefaultState(this.getDefaultState().with(AXIS, Axis.Y));
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return OUTLINES.get(state.get(AXIS));
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return OUTLINES.get(state.get(AXIS));
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ switch (rotation) {
+ case COUNTERCLOCKWISE_90:
+ case CLOCKWISE_90:
+ switch ((Direction.Axis) state.get(AXIS)) {
+ case X:
+ return (BlockState) state.with(AXIS, Direction.Axis.Z);
+ case Z:
+ return (BlockState) state.with(AXIS, Direction.Axis.X);
+ default:
+ return state;
+ }
+ default:
+ return state;
+ }
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder builder) {
+ builder.add(AXIS);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return (BlockState) this.getDefaultState().with(AXIS, ctx.getFace().getAxis());
+ }
+
+ static {
+ OUTLINES.put(Axis.X, Block.makeCuboidShape(0, 5, 5, 16, 11, 11));
+ OUTLINES.put(Axis.Y, Block.makeCuboidShape(5, 0, 5, 11, 16, 11));
+ OUTLINES.put(Axis.Z, Block.makeCuboidShape(5, 5, 0, 11, 11, 16));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockTerrain.java b/src/main/java/redd90/betternether/blocks/BlockTerrain.java
new file mode 100644
index 0000000..59ba47d
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockTerrain.java
@@ -0,0 +1,42 @@
+package redd90.betternether.blocks;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.enchantment.Enchantments;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.util.SoundEvents;
+
+public class BlockTerrain extends BlockBase {
+ public static final SoundType TERRAIN_SOUND = new SoundType(1.0F, 1.0F,
+ SoundEvents.BLOCK_NETHERRACK_BREAK,
+ SoundEvents.BLOCK_WART_BLOCK_STEP,
+ SoundEvents.BLOCK_NETHERRACK_PLACE,
+ SoundEvents.BLOCK_NETHERRACK_HIT,
+ SoundEvents.BLOCK_NETHERRACK_FALL);
+
+ public BlockTerrain() {
+ super(AbstractBlock.Properties.from(Blocks.NETHERRACK).sound(TERRAIN_SOUND).setRequiresTool());
+ this.setDropItself(false);
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool.canHarvestBlock(state)) {
+ if (EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0)
+ return Collections.singletonList(new ItemStack(this.asItem()));
+ else
+ return Collections.singletonList(new ItemStack(Blocks.NETHERRACK));
+ }
+ else
+ return super.getDrops(state, builder);
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockVeinedSand.java b/src/main/java/redd90/betternether/blocks/BlockVeinedSand.java
new file mode 100644
index 0000000..4fe2d2a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockVeinedSand.java
@@ -0,0 +1,39 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockVeinedSand extends BlockBase {
+ public BlockVeinedSand() {
+ super(AbstractBlock.Properties.create(Material.SAND, MaterialColor.BROWN)
+ .sound(SoundType.SAND)
+ .hardnessAndResistance(0.5F, 0.5F));
+ this.setDropItself(false);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (world.getBlockState(pos.up()).getBlock() == BlocksRegistry.SOUL_VEIN)
+ return state;
+ else
+ return Blocks.SOUL_SAND.getDefaultState();
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(Blocks.SOUL_SAND);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockWartRoots.java b/src/main/java/redd90/betternether/blocks/BlockWartRoots.java
new file mode 100644
index 0000000..571c5e6
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWartRoots.java
@@ -0,0 +1,12 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Blocks;
+
+public class BlockWartRoots extends BlockBase {
+ public BlockWartRoots() {
+ super(AbstractBlock.Properties.from(Blocks.NETHER_WART_BLOCK));
+ this.setDropItself(false);
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockWartSeed.java b/src/main/java/redd90/betternether/blocks/BlockWartSeed.java
new file mode 100644
index 0000000..0722f32
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWartSeed.java
@@ -0,0 +1,125 @@
+package redd90.betternether.blocks;
+
+import java.util.EnumMap;
+import java.util.Random;
+
+import com.google.common.collect.Maps;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureWartTree;
+
+public class BlockWartSeed extends BlockBaseNotFull implements IGrowable {
+ private static final EnumMap BOUNDING_SHAPES = Maps.newEnumMap(Direction.class);
+ private static final StructureWartTree STRUCTURE = new StructureWartTree();
+ public static final DirectionProperty FACING = BlockStateProperties.FACING;
+
+ static {
+ BOUNDING_SHAPES.put(Direction.UP, VoxelShapes.create(0.25, 0.0, 0.25, 0.75, 0.5, 0.75));
+ BOUNDING_SHAPES.put(Direction.DOWN, VoxelShapes.create(0.25, 0.5, 0.25, 0.75, 1.0, 0.75));
+ BOUNDING_SHAPES.put(Direction.NORTH, VoxelShapes.create(0.25, 0.25, 0.5, 0.75, 0.75, 1.0));
+ BOUNDING_SHAPES.put(Direction.SOUTH, VoxelShapes.create(0.25, 0.25, 0.0, 0.75, 0.75, 0.5));
+ BOUNDING_SHAPES.put(Direction.WEST, VoxelShapes.create(0.5, 0.25, 0.25, 1.0, 0.75, 0.75));
+ BOUNDING_SHAPES.put(Direction.EAST, VoxelShapes.create(0.0, 0.25, 0.25, 0.5, 0.75, 0.75));
+ }
+
+ public BlockWartSeed() {
+ super(AbstractBlock.Properties.create(Material.WOOD, MaterialColor.RED_TERRACOTTA)
+ .sound(SoundType.WART)
+ .hardnessAndResistance(1F)
+ .notSolid()
+ .doesNotBlockMovement());
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.UP));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return BOUNDING_SHAPES.get(state.get(FACING));
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ IWorldReader worldView = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ for (int i = 0; i < directions.length; ++i) {
+ Direction direction = directions[i];
+ Direction direction2 = direction.getOpposite();
+ blockState = (BlockState) blockState.with(FACING, direction2);
+ if (blockState.isValidPosition(worldView, blockPos)) {
+ return blockState;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING);
+ BlockPos blockPos = pos.offset(direction.getOpposite());
+ return hasEnoughSolidSide(world, blockPos, direction) || world.getBlockState(pos.down()).getBlock() == Blocks.SOUL_SAND;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ Direction direction = (Direction) state.get(FACING);
+ return direction == Direction.UP && BlocksHelper.isSoulSand(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return random.nextInt(8) == 0;
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.grow(world, pos, random);
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockWhisperingGourd.java b/src/main/java/redd90/betternether/blocks/BlockWhisperingGourd.java
new file mode 100644
index 0000000..95e2f5e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWhisperingGourd.java
@@ -0,0 +1,10 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockWhisperingGourd extends BlockBase {
+ public BlockWhisperingGourd() {
+ super(MaterialBuilder.makeWood(MaterialColor.BLUE));
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockWhisperingGourdLantern.java b/src/main/java/redd90/betternether/blocks/BlockWhisperingGourdLantern.java
new file mode 100644
index 0000000..2360190
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWhisperingGourdLantern.java
@@ -0,0 +1,40 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.HorizontalBlock;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockWhisperingGourdLantern extends Block {
+ public static final DirectionProperty FACING = HorizontalBlock.HORIZONTAL_FACING;
+
+ public BlockWhisperingGourdLantern() {
+ super(MaterialBuilder.makeWood(MaterialColor.BLUE).setLightLevel((state) -> {return 15;}));
+ }
+
+ protected void appendProperties(StateContainer.Builder builder) {
+ builder.add(FACING);
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return this.getDefaultState().with(FACING, ctx.getPlacementHorizontalFacing().getOpposite());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockWhisperingGourdVine.java b/src/main/java/redd90/betternether/blocks/BlockWhisperingGourdVine.java
new file mode 100644
index 0000000..84cc796
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWhisperingGourdVine.java
@@ -0,0 +1,152 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.Random;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.entity.item.ItemEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.loot.LootParameters;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.ActionResultType;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Hand;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockRayTraceResult;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.Tags;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.blocks.shapes.TripleShape;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockWhisperingGourdVine extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SELECTION = Block.makeCuboidShape(2, 0, 2, 14, 16, 14);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public BlockWhisperingGourdVine() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .doesNotBlockMovement()
+ .zeroHardnessAndResistance()
+ .notSolid()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, TripleShape.BOTTOM));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SELECTION;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ BlockState upState = world.getBlockState(pos.up());
+ return upState.getBlock() == this || upState.isSolidSide(world, pos, Direction.DOWN);
+ }
+
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightLevel(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else if (world.getBlockState(pos.down()).getBlock() != this)
+ return state.with(SHAPE, TripleShape.BOTTOM);
+ else if (state.get(SHAPE) == TripleShape.BOTTOM)
+ return state.with(SHAPE, TripleShape.TOP);
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isRemote) {
+ return world.getBlockState(pos.up(3)).getBlock() != this && world.getBlockState(pos.down()).getBlock() != this;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return world.getBlockState(pos.up(3)).getBlock() != this && world.getBlockState(pos.down()).getMaterial().isReplaceable();
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ BlocksHelper.setWithUpdate(world, pos, state.with(SHAPE, TripleShape.TOP));
+ BlocksHelper.setWithUpdate(world, pos.down(), getDefaultState());
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ ItemStack tool = builder.get(LootParameters.TOOL);
+ if (tool != null && tool.getItem().isIn(Tags.Items.SHEARS))
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ else if (state.get(SHAPE) == TripleShape.BOTTOM || MHelper.RANDOM.nextBoolean())
+ return Lists.newArrayList(new ItemStack(this.asItem()));
+ else
+ return Lists.newArrayList();
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state)) {
+ grow(world, random, pos, state);
+ }
+ if (state.get(SHAPE) != TripleShape.MIDDLE && state.get(SHAPE) != TripleShape.BOTTOM && random.nextInt(16) == 0) {
+ BlocksHelper.setWithUpdate(world, pos, state.with(SHAPE, TripleShape.MIDDLE));
+ }
+ }
+
+ public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult hit) {
+ ItemStack tool = player.getHeldItem(hand);
+ if (tool.getItem().isIn(Tags.Items.SHEARS) && state.get(SHAPE) == TripleShape.MIDDLE) {
+ if (!world.isRemote) {
+ BlocksHelper.setWithUpdate(world, pos, state.with(SHAPE, TripleShape.BOTTOM));
+ world.addEntity(new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(BlocksRegistry.WHISPERING_GOURD)));
+ if (world.rand.nextBoolean()) {
+ world.addEntity(new ItemEntity(world, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, new ItemStack(BlocksRegistry.WHISPERING_GOURD)));
+ }
+ }
+ return ActionResultType.func_233537_a_(world.isRemote);
+ }
+ else {
+ return super.onBlockActivated(state, world, pos, player, hand, hit);
+ }
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockWillowBranch.java b/src/main/java/redd90/betternether/blocks/BlockWillowBranch.java
new file mode 100644
index 0000000..3c6d307
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWillowBranch.java
@@ -0,0 +1,104 @@
+package redd90.betternether.blocks;
+
+import java.util.List;
+import java.util.function.ToIntFunction;
+
+import com.google.common.collect.Lists;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.ItemStack;
+import net.minecraft.loot.LootContext;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import net.minecraft.util.IStringSerializable;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class BlockWillowBranch extends BlockBaseNotFull {
+ private static final VoxelShape V_SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", WillowBranchShape.class);
+
+ public BlockWillowBranch() {
+ super(MaterialBuilder.makeWood(MaterialColor.RED_TERRACOTTA).notSolid().doesNotBlockMovement().setLightLevel(getLuminance()));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, WillowBranchShape.MIDDLE));
+ }
+
+ protected static ToIntFunction getLuminance() {
+ return (state) -> {
+ return state.get(SHAPE) == WillowBranchShape.END ? 15 : 0;
+ };
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return V_SHAPE;
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (world.isAirBlock(pos.up()))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ public enum WillowBranchShape implements IStringSerializable {
+ END("end"), MIDDLE("middle");
+
+ final String name;
+
+ WillowBranchShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public ItemStack getItem(IBlockReader world, BlockPos pos, BlockState state) {
+ return new ItemStack(state.get(SHAPE) == WillowBranchShape.END ? BlocksRegistry.WILLOW_TORCH : BlocksRegistry.WILLOW_LEAVES);
+ }
+
+ @Override
+ public List getDrops(BlockState state, LootContext.Builder builder) {
+ if (state.get(SHAPE) == WillowBranchShape.END) {
+ return Lists.newArrayList(new ItemStack(BlocksRegistry.WILLOW_TORCH));
+ }
+ else {
+ return Lists.newArrayList();
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockWillowLeaves.java b/src/main/java/redd90/betternether/blocks/BlockWillowLeaves.java
new file mode 100644
index 0000000..29225df
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWillowLeaves.java
@@ -0,0 +1,79 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Block;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.BooleanProperty;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.util.math.shapes.VoxelShapes;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockWillowLeaves extends BlockBaseNotFull {
+ public static final DirectionProperty FACING = BlockStateProperties.FACING;
+ public static final BooleanProperty NATURAL = BooleanProperty.create("natural");
+
+ public BlockWillowLeaves() {
+ super(MaterialBuilder.makeLeaves(MaterialColor.RED_TERRACOTTA));
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.UP).with(NATURAL, true));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING, NATURAL);
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ return this.getDefaultState().with(NATURAL, false);
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (state.get(NATURAL) && world.isAirBlock(pos.offset(state.get(FACING).getOpposite())))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getAmbientOcclusionLightValue(BlockState state, IBlockReader view, BlockPos pos) {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean propagatesSkylightDown(BlockState state, IBlockReader view, BlockPos pos) {
+ return true;
+ }
+
+ @Override
+ public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos) {
+ return VoxelShapes.empty();
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/BlockWillowSapling.java b/src/main/java/redd90/betternether/blocks/BlockWillowSapling.java
new file mode 100644
index 0000000..1403609
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWillowSapling.java
@@ -0,0 +1,78 @@
+package redd90.betternether.blocks;
+
+import java.util.Random;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.IGrowable;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.util.Direction;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.structures.plants.StructureWillow;
+
+public class BlockWillowSapling extends BlockBaseNotFull implements IGrowable {
+ private static final VoxelShape SHAPE = Block.makeCuboidShape(4, 0, 4, 12, 14, 12);
+ private static final StructureWillow STRUCTURE = new StructureWillow();
+
+ public BlockWillowSapling() {
+ super(AbstractBlock.Properties.create(Material.PLANTS, MaterialColor.RED)
+ .sound(SoundType.CROP)
+ .notSolid()
+ .zeroHardnessAndResistance()
+ .doesNotBlockMovement()
+ .tickRandomly());
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return SHAPE;
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ return BlocksHelper.isNetherGround(world.getBlockState(pos.down()));
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (!isValidPosition(state, world, pos))
+ return Blocks.AIR.getDefaultState();
+ else
+ return state;
+ }
+
+ @Override
+ public boolean canGrow(IBlockReader world, BlockPos pos, BlockState state, boolean isClient) {
+ return true;
+ }
+
+ @Override
+ public boolean canUseBonemeal(World world, Random random, BlockPos pos, BlockState state) {
+ return BlocksHelper.isFertile(world.getBlockState(pos.down())) ? (random.nextInt(8) == 0) : (random.nextInt(16) == 0);
+ }
+
+ @Override
+ public void grow(ServerWorld world, Random random, BlockPos pos, BlockState state) {
+ STRUCTURE.generate(world, pos, random);
+ }
+
+ @Override
+ public void tick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
+ super.tick(state, world, pos, random);
+ if (canUseBonemeal(world, random, pos, state))
+ grow(world, random, pos, state);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/BlockWillowTorch.java b/src/main/java/redd90/betternether/blocks/BlockWillowTorch.java
new file mode 100644
index 0000000..6b63da7
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWillowTorch.java
@@ -0,0 +1,104 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.item.BlockItemUseContext;
+import net.minecraft.state.DirectionProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.state.properties.BlockStateProperties;
+import net.minecraft.util.Direction;
+import net.minecraft.util.Mirror;
+import net.minecraft.util.Rotation;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+
+public class BlockWillowTorch extends BlockBaseNotFull {
+ private static final VoxelShape SHAPE_NORTH = Block.makeCuboidShape(5, 0, 8, 11, 16, 16);
+ private static final VoxelShape SHAPE_SOUTH = Block.makeCuboidShape(5, 0, 0, 11, 16, 8);
+ private static final VoxelShape SHAPE_WEST = Block.makeCuboidShape(8, 0, 5, 16, 16, 11);
+ private static final VoxelShape SHAPE_EAST = Block.makeCuboidShape(0, 0, 5, 8, 16, 11);
+ private static final VoxelShape SHAPE_UP = Block.makeCuboidShape(5, 0, 5, 11, 9, 11);
+ private static final VoxelShape SHAPE_DOWN = Block.makeCuboidShape(5, 3, 5, 11, 16, 11);
+
+ public static final DirectionProperty FACING = BlockStateProperties.FACING;
+
+ public BlockWillowTorch() {
+ super(MaterialBuilder.makeWood(MaterialColor.LIGHT_BLUE).setLightLevel((state) -> {return 15;}).doesNotBlockMovement().notSolid());
+ this.setDefaultState(getStateContainer().getBaseState().with(FACING, Direction.DOWN));
+ this.setRenderLayer(BNRenderLayer.CUTOUT);
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(FACING);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ switch (state.get(FACING)) {
+ case NORTH:
+ return SHAPE_NORTH;
+ case SOUTH:
+ return SHAPE_SOUTH;
+ case EAST:
+ return SHAPE_EAST;
+ case WEST:
+ return SHAPE_WEST;
+ case UP:
+ return SHAPE_UP;
+ case DOWN:
+ default:
+ return SHAPE_DOWN;
+ }
+ }
+
+ @Override
+ public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
+ Direction direction = (Direction) state.get(FACING).getOpposite();
+ return Block.hasEnoughSolidSide(world, pos.offset(direction), direction.getOpposite());
+ }
+
+ @Override
+ public BlockState rotate(BlockState state, Rotation rotation) {
+ return BlocksHelper.rotateHorizontal(state, rotation, FACING);
+ }
+
+ @Override
+ public BlockState mirror(BlockState state, Mirror mirror) {
+ return BlocksHelper.mirrorHorizontal(state, mirror, FACING);
+ }
+
+ @Override
+ public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState neighborState, IWorld world, BlockPos pos, BlockPos neighborPos) {
+ if (isValidPosition(state, world, pos))
+ return state;
+ else
+ return Blocks.AIR.getDefaultState();
+ }
+
+ @Override
+ public BlockState getStateForPlacement(BlockItemUseContext ctx) {
+ BlockState blockState = this.getDefaultState();
+ IWorldReader worldView = ctx.getWorld();
+ BlockPos blockPos = ctx.getPos();
+ Direction[] directions = ctx.getNearestLookingDirections();
+ for (int i = 0; i < directions.length; ++i) {
+ Direction direction = directions[i];
+ Direction direction2 = direction.getOpposite();
+ blockState = blockState.with(FACING, direction2);
+ if (blockState.isValidPosition(worldView, blockPos)) {
+ return blockState;
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/src/main/java/redd90/betternether/blocks/BlockWillowTrunk.java b/src/main/java/redd90/betternether/blocks/BlockWillowTrunk.java
new file mode 100644
index 0000000..b068c9a
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/BlockWillowTrunk.java
@@ -0,0 +1,35 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.shapes.ISelectionContext;
+import net.minecraft.util.math.shapes.VoxelShape;
+import net.minecraft.world.IBlockReader;
+import redd90.betternether.blocks.materials.MaterialBuilder;
+import redd90.betternether.blocks.shapes.TripleShape;
+
+public class BlockWillowTrunk extends BlockBaseNotFull {
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+ private static final VoxelShape SHAPE_BOTTOM = Block.makeCuboidShape(4, 0, 4, 12, 16, 12);
+ private static final VoxelShape SHAPE_TOP = Block.makeCuboidShape(4, 0, 4, 12, 12, 12);
+
+ public BlockWillowTrunk() {
+ super(MaterialBuilder.makeWood(MaterialColor.RED_TERRACOTTA).notSolid());
+ this.setDropItself(false);
+ this.setDefaultState(getStateContainer().getBaseState().with(SHAPE, TripleShape.TOP));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ stateManager.add(SHAPE);
+ }
+
+ @Override
+ public VoxelShape getShape(BlockState state, IBlockReader view, BlockPos pos, ISelectionContext ePos) {
+ return state.get(SHAPE) == TripleShape.TOP ? SHAPE_TOP : SHAPE_BOTTOM;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/RubeusLog.java b/src/main/java/redd90/betternether/blocks/RubeusLog.java
new file mode 100644
index 0000000..598a712
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/RubeusLog.java
@@ -0,0 +1,24 @@
+package redd90.betternether.blocks;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraft.state.EnumProperty;
+import net.minecraft.state.StateContainer;
+import net.minecraft.util.Direction;
+import redd90.betternether.blocks.shapes.TripleShape;
+
+public class RubeusLog extends BNLogStripable {
+ public static final EnumProperty SHAPE = EnumProperty.create("shape", TripleShape.class);
+
+ public RubeusLog(Block striped) {
+ super(MaterialColor.MAGENTA, striped);
+ this.setDefaultState(this.getDefaultState().with(AXIS, Direction.Axis.Y).with(SHAPE, TripleShape.BOTTOM));
+ }
+
+ @Override
+ protected void fillStateContainer(StateContainer.Builder stateManager) {
+ super.fillStateContainer(stateManager);
+ stateManager.add(SHAPE);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/complex/ColoredGlassMaterial.java b/src/main/java/redd90/betternether/blocks/complex/ColoredGlassMaterial.java
new file mode 100644
index 0000000..cd19638
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/complex/ColoredGlassMaterial.java
@@ -0,0 +1,105 @@
+package redd90.betternether.blocks.complex;
+
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import net.minecraft.block.Block;
+import net.minecraft.item.BlockItem;
+import net.minecraft.item.DyeItem;
+import net.minecraft.item.Item;
+import net.minecraft.item.Items;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.RegistryObject;
+import redd90.betternether.BetterNether;
+import redd90.betternether.blocks.BNGlass;
+import redd90.betternether.blocks.BNPane;
+import redd90.betternether.recipes.RecipesHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.ItemsRegistry;
+import redd90.betternether.tab.CreativeTab;
+
+public class ColoredGlassMaterial {
+ public final Block white;
+ public final Block orange;
+ public final Block magenta;
+ public final Block light_blue;
+ public final Block yellow;
+ public final Block lime;
+ public final Block pink;
+ public final Block gray;
+ public final Block light_gray;
+ public final Block cyan;
+ public final Block purple;
+ public final Block blue;
+ public final Block brown;
+ public final Block green;
+ public final Block red;
+ public final Block black;
+
+ /**
+ * Full Block Constructor
+ *
+ * @param name
+ * - base name of block (prefix) and it's group
+ * @param base
+ * - block base for material properties and crafting
+ */
+ public ColoredGlassMaterial(String name, Block base) {
+ white = makeInstance(name, base, Items.WHITE_DYE, true, false);
+ orange = makeInstance(name, base, Items.ORANGE_DYE, true, false);
+ magenta = makeInstance(name, base, Items.MAGENTA_DYE, true, false);
+ light_blue = makeInstance(name, base, Items.LIGHT_BLUE_DYE, true, false);
+ yellow = makeInstance(name, base, Items.YELLOW_DYE, true, false);
+ lime = makeInstance(name, base, Items.LIME_DYE, true, false);
+ pink = makeInstance(name, base, Items.PINK_DYE, true, false);
+ gray = makeInstance(name, base, Items.GRAY_DYE, true, false);
+ light_gray = makeInstance(name, base, Items.LIGHT_GRAY_DYE, true, false);
+ cyan = makeInstance(name, base, Items.CYAN_DYE, true, false);
+ purple = makeInstance(name, base, Items.PURPLE_DYE, true, false);
+ blue = makeInstance(name, base, Items.BLUE_DYE, true, false);
+ brown = makeInstance(name, base, Items.BROWN_DYE, true, false);
+ green = makeInstance(name, base, Items.GREEN_DYE, true, false);
+ red = makeInstance(name, base, Items.RED_DYE, true, false);
+ black = makeInstance(name, base, Items.BLACK_DYE, true, false);
+ }
+
+ /**
+ * Pane Block Constructor
+ *
+ * @param name
+ * - base name of block (prefix) and it's group
+ * @param base
+ * - block base for material properties and crafting
+ * @param paneDropItself
+ * - will pane drop itself on break or not (will require silk
+ * touch)
+ */
+ public ColoredGlassMaterial(String name, Block base, boolean paneDropItself) {
+ white = makeInstance(name, base, Items.WHITE_DYE, false, paneDropItself);
+ orange = makeInstance(name, base, Items.ORANGE_DYE, false, paneDropItself);
+ magenta = makeInstance(name, base, Items.MAGENTA_DYE, false, paneDropItself);
+ light_blue = makeInstance(name, base, Items.LIGHT_BLUE_DYE, false, paneDropItself);
+ yellow = makeInstance(name, base, Items.YELLOW_DYE, false, paneDropItself);
+ lime = makeInstance(name, base, Items.LIME_DYE, false, paneDropItself);
+ pink = makeInstance(name, base, Items.PINK_DYE, false, paneDropItself);
+ gray = makeInstance(name, base, Items.GRAY_DYE, false, paneDropItself);
+ light_gray = makeInstance(name, base, Items.LIGHT_GRAY_DYE, false, paneDropItself);
+ cyan = makeInstance(name, base, Items.CYAN_DYE, false, paneDropItself);
+ purple = makeInstance(name, base, Items.PURPLE_DYE, false, paneDropItself);
+ blue = makeInstance(name, base, Items.BLUE_DYE, false, paneDropItself);
+ brown = makeInstance(name, base, Items.BROWN_DYE, false, paneDropItself);
+ green = makeInstance(name, base, Items.GREEN_DYE, false, paneDropItself);
+ red = makeInstance(name, base, Items.RED_DYE, false, paneDropItself);
+ black = makeInstance(name, base, Items.BLACK_DYE, false, paneDropItself);
+ }
+
+ private Block makeInstance(String group, Block base, Item dye, boolean isFullBlock, boolean paneDropItself) {
+ Block block = isFullBlock ? new BNGlass(base) : new BNPane(base, paneDropItself);
+ String name = group + "_" + ((DyeItem) dye).getDyeColor().getString();
+ block.setRegistryName(new ResourceLocation(BetterNether.MOD_ID, name));
+ BlocksRegistry.BLOCKS.add(block);
+ ItemsRegistry.registerItem(name, new BlockItem(block, new Item.Properties().group(CreativeTab.BN_TAB)));
+ RecipesHelper.makeColoringRecipe(base, block, dye, group);
+ return block;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/complex/WoodenMaterial.java b/src/main/java/redd90/betternether/blocks/complex/WoodenMaterial.java
new file mode 100644
index 0000000..4d0cd23
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/complex/WoodenMaterial.java
@@ -0,0 +1,73 @@
+package redd90.betternether.blocks.complex;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.material.MaterialColor;
+import redd90.betternether.blocks.BNLogStripable;
+import redd90.betternether.blocks.BNPillar;
+import redd90.betternether.blocks.BNPlanks;
+import redd90.betternether.registry.BlocksRegistry;
+
+public class WoodenMaterial {
+ public final Block log;
+ public final Block bark;
+
+ public final Block log_striped;
+ public final Block bark_striped;
+
+ public final Block planks;
+
+ public final Block planks_stairs;
+ public final Block planks_slab;
+
+ public final Block fence;
+ public final Block gate;
+ public final Block button;
+ public final Block pressure_plate;
+ public final Block trapdoor;
+ public final Block door;
+
+ public final Block taburet;
+ public final Block chair;
+ public final Block bar_stool;
+
+ public final Block crafting_table;
+ public final Block ladder;
+ public final Block sign;
+
+ public final Block chest;
+ public final Block barrel;
+
+ public WoodenMaterial(String name, MaterialColor woodColor, MaterialColor planksColor) {
+ log_striped = BlocksRegistry.registerBlock("striped_log_" + name, new BNPillar(woodColor));
+ bark_striped = BlocksRegistry.registerBlock("striped_bark_" + name, new BNPillar(woodColor));
+
+ log = BlocksRegistry.registerBlock(name + "_log", new BNLogStripable(woodColor, log_striped));
+ bark = BlocksRegistry.registerBark(name + "_bark", new BNLogStripable(woodColor, bark_striped), log);
+
+ planks = BlocksRegistry.registerPlanks(name + "_planks", new BNPlanks(planksColor), log_striped, bark_striped, log, bark);
+ planks_stairs = BlocksRegistry.registerStairs(name + "_stairs", planks);
+ planks_slab = BlocksRegistry.registerSlab(name + "_slab", planks);
+
+ fence = BlocksRegistry.registerFence(name + "_fence", planks);
+ gate = BlocksRegistry.registerGate(name + "_gate", planks);
+ button = BlocksRegistry.registerButton(name + "_button", planks);
+ pressure_plate = BlocksRegistry.registerPlate(name + "_plate", planks);
+ trapdoor = BlocksRegistry.registerTrapdoor(name + "_trapdoor", planks);
+ door = BlocksRegistry.registerDoor(name + "_door", planks);
+
+ taburet = BlocksRegistry.registerTaburet("taburet_" + name, planks_slab);
+ chair = BlocksRegistry.registerChair("chair_" + name, planks_slab);
+ bar_stool = BlocksRegistry.registerBarStool("bar_stool_" + name, planks_slab);
+
+ crafting_table = BlocksRegistry.registerCraftingTable("crafting_table_" + name, planks);
+ ladder = BlocksRegistry.registerLadder(name + "_ladder", planks);
+ sign = BlocksRegistry.registerSign("sign_" + name, planks);
+
+ chest = BlocksRegistry.registerChest("chest_" + name, planks);
+ barrel = BlocksRegistry.registerBarrel("barrel_" + name, planks, planks_slab);
+ }
+
+ public boolean isTreeLog(Block block) {
+ return block == log || block == bark;
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/materials/MaterialBuilder.java b/src/main/java/redd90/betternether/blocks/materials/MaterialBuilder.java
new file mode 100644
index 0000000..dc7e64d
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/materials/MaterialBuilder.java
@@ -0,0 +1,48 @@
+package redd90.betternether.blocks.materials;
+
+import net.minecraft.block.AbstractBlock;
+import net.minecraft.block.SoundType;
+import net.minecraft.block.material.Material;
+import net.minecraft.block.material.MaterialColor;
+import net.minecraftforge.common.ToolType;
+
+public class MaterialBuilder {
+ public static final Material COMMON_WOOD = new Material.Builder(MaterialColor.WOOD).build();
+ public static final Material COMMON_GRASS = new Material.Builder(MaterialColor.FOLIAGE).doesNotBlockMovement().notSolid().replaceable().build();
+ public static final Material COMMON_LEAVES = new Material.Builder(MaterialColor.FOLIAGE).notSolid().build();
+
+ public static AbstractBlock.Properties makeWood(MaterialColor color) {
+ return AbstractBlock.Properties.create(COMMON_WOOD, color)
+ .sound(SoundType.WOOD)
+ .harvestTool(ToolType.AXE)
+ .hardnessAndResistance(1);
+ }
+
+ public static AbstractBlock.Properties makeGrass(MaterialColor color) {
+ return AbstractBlock.Properties.create(COMMON_GRASS, color)
+ .setAllowsSpawn((state, world, pos, type) -> {
+ return true;
+ })
+ .sound(SoundType.PLANT)
+ .doesNotBlockMovement()
+ .notSolid()
+ .zeroHardnessAndResistance();
+ }
+
+ public static AbstractBlock.Properties makeLeaves(MaterialColor color) {
+ return AbstractBlock.Properties.create(COMMON_LEAVES, color)
+ .harvestTool(ToolType.HOE)
+ .sound(SoundType.PLANT)
+ .notSolid()
+ .hardnessAndResistance(0.2F)
+ .setAllowsSpawn((state, world, pos, type) -> {
+ return false;
+ })
+ .setSuffocates((state, worls, pos) -> {
+ return false;
+ })
+ .setBlocksVision((state, worls, pos) -> {
+ return false;
+ });
+ }
+}
diff --git a/src/main/java/redd90/betternether/blocks/shapes/FoodShape.java b/src/main/java/redd90/betternether/blocks/shapes/FoodShape.java
new file mode 100644
index 0000000..3a31b1e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/shapes/FoodShape.java
@@ -0,0 +1,33 @@
+package redd90.betternether.blocks.shapes;
+
+import net.minecraft.item.Item;
+import net.minecraft.util.IStringSerializable;
+
+public enum FoodShape implements IStringSerializable {
+ NONE("none"), WART("wart"), MUSHROOM("mushroom"), APPLE("apple");
+
+ private final String name;
+ private Item item;
+
+ FoodShape(String name) {
+ this.name = name;
+ }
+
+ public void setItem(Item item) {
+ this.item = item;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public Item getItem() {
+ return item;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/blocks/shapes/TripleShape.java b/src/main/java/redd90/betternether/blocks/shapes/TripleShape.java
new file mode 100644
index 0000000..caeaf3e
--- /dev/null
+++ b/src/main/java/redd90/betternether/blocks/shapes/TripleShape.java
@@ -0,0 +1,23 @@
+package redd90.betternether.blocks.shapes;
+
+import net.minecraft.util.IStringSerializable;
+
+public enum TripleShape implements IStringSerializable {
+ TOP("top"), MIDDLE("middle"), BOTTOM("bottom");
+
+ final String name;
+
+ TripleShape(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getString() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/client/BetterNetherClient.java b/src/main/java/redd90/betternether/client/BetterNetherClient.java
new file mode 100644
index 0000000..36c00e9
--- /dev/null
+++ b/src/main/java/redd90/betternether/client/BetterNetherClient.java
@@ -0,0 +1,5 @@
+package redd90.betternether.client;
+
+public class BetterNetherClient {
+
+}
diff --git a/src/main/java/redd90/betternether/client/IRenderTypeable.java b/src/main/java/redd90/betternether/client/IRenderTypeable.java
new file mode 100644
index 0000000..1679ee1
--- /dev/null
+++ b/src/main/java/redd90/betternether/client/IRenderTypeable.java
@@ -0,0 +1,7 @@
+package redd90.betternether.client;
+
+import redd90.betternether.blocks.BNRenderLayer;
+
+public interface IRenderTypeable {
+ public BNRenderLayer getRenderLayer();
+}
diff --git a/src/main/java/redd90/betternether/config/Config.java b/src/main/java/redd90/betternether/config/Config.java
new file mode 100644
index 0000000..0a0ccf0
--- /dev/null
+++ b/src/main/java/redd90/betternether/config/Config.java
@@ -0,0 +1,261 @@
+package redd90.betternether.config;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+import redd90.betternether.BetterNether;
+
+public final class Config {
+ private static final List ALL = Lists.newArrayList();
+ private JsonObject config;
+ private boolean rewrite = false;
+ private final String name;
+
+ public Config(String name) {
+ this.name = name;
+ ALL.add(this);
+ }
+
+ private void load() {
+ if (config == null) {
+ File file = getFolder();
+ if (!file.exists())
+ file.mkdirs();
+ file = getFile();
+ if (file.exists()) {
+ Gson gson = new Gson();
+ try {
+ Reader reader = new FileReader(file);
+ config = gson.fromJson(reader, JsonObject.class);
+ if (config == null) {
+ config = new JsonObject();
+ rewrite = true;
+ }
+ else {
+ rewrite = false;
+ }
+ }
+ catch (FileNotFoundException e) {
+ e.printStackTrace();
+ config = new JsonObject();
+ rewrite = true;
+ }
+ }
+ else {
+ config = new JsonObject();
+ rewrite = true;
+ }
+ }
+ }
+
+ public static void save() {
+ ALL.forEach((config) -> {
+ if (config.rewrite) {
+ File file = config.getFolder();
+ if (!file.exists())
+ file.mkdirs();
+ file = config.getFile();
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ try {
+ FileWriter writer = new FileWriter(file);
+ String gstring = gson.toJson(config.config);
+ writer.write(gstring);
+ writer.flush();
+ writer.close();
+ config.rewrite = false;
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private File getFile() {
+ return new File(String.format("./config/%s/%s.json", BetterNether.MOD_ID, name));
+ }
+
+ private File getFolder() {
+ return new File("./config/" + BetterNether.MOD_ID + "/");
+ }
+
+ public boolean getBoolean(String groups, String name, boolean def) {
+ load();
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ JsonElement element = group.get(name);
+
+ if (element != null) {
+ return element.getAsBoolean();
+ }
+ else {
+ group.addProperty(name, def);
+ rewrite = true;
+ return def;
+ }
+ }
+
+ public void setBoolean(String groups, String name, boolean def, boolean value) {
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ group.addProperty(name, value);
+
+ rewrite = true;
+ }
+
+ public float getFloat(String groups, String name, float def) {
+ load();
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ JsonElement element = group.get(name);
+
+ if (element != null) {
+ return element.getAsFloat();
+ }
+ else {
+ group.addProperty(name, def);
+ rewrite = true;
+ return def;
+ }
+ }
+
+ public void setFloat(String groups, String name, float def, float value) {
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ group.addProperty(name, value);
+
+ rewrite = true;
+ }
+
+ public int getInt(String groups, String name, int def) {
+ load();
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ JsonElement element = group.get(name);
+
+ if (element != null) {
+ return element.getAsInt();
+ }
+ else {
+ group.addProperty(name, def);
+ rewrite = true;
+ return def;
+ }
+ }
+
+ public String getString(String groups, String name, String def) {
+ load();
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ JsonElement element = group.get(name);
+
+ if (element != null) {
+ return element.getAsString();
+ }
+ else {
+ group.addProperty(name, def);
+ rewrite = true;
+ return def;
+ }
+ }
+
+ public void setInt(String groups, String name, int def, int value) {
+ name += "[def: " + def + "]";
+
+ JsonObject group = getGroup(groups);
+ group.addProperty(name, value);
+
+ rewrite = true;
+ }
+
+ public void setStringLoad(String groups, String name, String value) {
+ JsonObject group = getGroup(groups);
+ group.addProperty(name, value);
+ }
+
+ public String[] getStringArray(String groups, String name, String[] def) {
+ load();
+
+ JsonObject group = getGroup(groups);
+ JsonElement element = group.get(name);
+
+ if (element != null) {
+ return toStringArray(element.getAsJsonArray());
+ }
+ else {
+ group.add(name, toJsonArray(def));
+ rewrite = true;
+ return def;
+ }
+ }
+
+ private String[] toStringArray(JsonArray array) {
+ load();
+ String[] result = new String[array.size()];
+ for (int i = 0; i < array.size(); i++)
+ result[i] = array.get(i).getAsString();
+ return result;
+ }
+
+ private JsonArray toJsonArray(String[] array) {
+ load();
+ JsonArray result = new JsonArray();
+ for (String s : array)
+ result.add(s);
+ return result;
+ }
+
+ public JsonObject getGroup(String groups) {
+ JsonObject obj = config;
+ String[] groupsArr = groups.split("\\.");
+ for (String group : groupsArr) {
+ JsonObject jGroup = obj.getAsJsonObject(group);
+ if (jGroup == null) {
+ jGroup = new JsonObject();
+ obj.add(group, jGroup);
+ }
+ obj = jGroup;
+ }
+ return obj;
+ }
+
+ public List getBaseGroups() {
+ List groups = new ArrayList();
+ Iterator> iterator = config.entrySet().iterator();
+ iterator.forEachRemaining((element) -> {
+ groups.add(element.getKey());
+ });
+ return groups;
+ }
+
+ public List> getGroupMembers(JsonObject group) {
+ List> result = new ArrayList>();
+ result.addAll(group.entrySet());
+ return result;
+ }
+
+ public void markToSave() {
+ rewrite = true;
+ }
+}
diff --git a/src/main/java/redd90/betternether/config/Configs.java b/src/main/java/redd90/betternether/config/Configs.java
new file mode 100644
index 0000000..1517b40
--- /dev/null
+++ b/src/main/java/redd90/betternether/config/Configs.java
@@ -0,0 +1,11 @@
+package redd90.betternether.config;
+
+public class Configs {
+ public static final Config MAIN = new Config("main");
+ public static final Config GENERATOR = new Config("generator");
+ public static final Config BIOMES = new Config("biomes");
+ public static final Config BLOCKS = new Config("blocks");
+ public static final Config ITEMS = new Config("items");
+ public static final Config MOBS = new Config("mobs");
+ public static final Config RECIPES = new Config("recipes");
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/datagen/BNRecipes.java b/src/main/java/redd90/betternether/datagen/BNRecipes.java
new file mode 100644
index 0000000..6cd10db
--- /dev/null
+++ b/src/main/java/redd90/betternether/datagen/BNRecipes.java
@@ -0,0 +1,444 @@
+package redd90.betternether.datagen;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+import net.minecraft.block.Block;
+import net.minecraft.data.DataGenerator;
+import net.minecraft.data.IFinishedRecipe;
+import net.minecraft.data.RecipeProvider;
+import net.minecraft.data.ShapedRecipeBuilder;
+import net.minecraft.data.ShapelessRecipeBuilder;
+import net.minecraft.item.Item;
+import net.minecraft.item.Items;
+import net.minecraft.util.IItemProvider;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.registries.ForgeRegistries;
+import redd90.betternether.BetterNether;
+
+public class BNRecipes extends RecipeProvider {
+
+ public static final ArrayList STAIRS = new ArrayList<>();
+ public static final ArrayList SLABS = new ArrayList<>();
+ public static final ArrayList ROOFS = new ArrayList<>();
+ public static final ArrayList PLATES = new ArrayList<>();
+ public static final ArrayList TWOBYTWO = new ArrayList<>();
+ public static final ArrayList FENCES = new ArrayList<>();
+ public static final ArrayList GATES = new ArrayList<>();
+ public static final ArrayList DOORS = new ArrayList<>();
+ public static final ArrayList TRAPDOORS = new ArrayList<>();
+ public static final ArrayList WALLS = new ArrayList<>();
+ public static final ArrayList ROUND = new ArrayList<>();
+ public static final ArrayList SIGNS = new ArrayList<>();
+ public static final ArrayList BARRELS = new ArrayList<>();
+ public static final ArrayList LADDERS = new ArrayList<>();
+ public static final ArrayList TABURETS = new ArrayList<>();
+ public static final ArrayList CHAIRS = new ArrayList<>();
+ public static final ArrayList BAR_STOOLS = new ArrayList<>();
+ public static final ArrayList FIRE_BOWLS = new ArrayList<>();
+ public static final ArrayList SHAPELESS = new ArrayList<>();
+
+ public BNRecipes(DataGenerator generatorIn) {
+ super(generatorIn);
+ }
+
+ @Override
+ protected void registerRecipes(Consumer consumer) {
+ for (SingleInputRecipe recipe : STAIRS) {
+ makeStairsRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : SLABS) {
+ makeSlabRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : ROOFS) {
+ makeRoofRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : PLATES) {
+ makePlateRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : TWOBYTWO) {
+ make2x2Recipe(recipe.input, recipe.output, recipe.quantityOut, consumer);
+ }
+
+ for (SingleInputRecipe recipe : FENCES) {
+ makeFenceRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : GATES) {
+ makeGateRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : DOORS) {
+ makeDoorRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : TRAPDOORS) {
+ makeTrapdoorRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : WALLS) {
+ makeWallRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : ROUND) {
+ makeRoundRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : SIGNS) {
+ makeSignRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (TwoInputRecipe recipe : BARRELS) {
+ makeBarrelRecipe(recipe.input1, recipe.input2, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : LADDERS) {
+ makeLadderRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : TABURETS) {
+ makeTaburetRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : CHAIRS) {
+ makeChairRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : BAR_STOOLS) {
+ makeBarStoolRecipe(recipe.input, recipe.output, consumer);
+ }
+
+ for (FireBowlRecipe recipe : FIRE_BOWLS) {
+ makeFireBowlRecipe(recipe.source, recipe.inside, recipe.legs, recipe.output, consumer);
+ }
+
+ for (SingleInputRecipe recipe : SHAPELESS) {
+ makeShapelessSingleInputRecipe(recipe.input, recipe.output, recipe.quantityOut, consumer);
+ }
+ }
+
+ // SHAPED RECIPES //
+
+ public static void makeStairsRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 4)
+ .patternLine("# ")
+ .patternLine("## ")
+ .patternLine("###")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeSlabRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 6)
+ .patternLine("###")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeRoofRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 6)
+ .patternLine("# #")
+ .patternLine("###")
+ .patternLine(" # ")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makePlateRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("##")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void make2x2Recipe(ResourceLocation input, ResourceLocation output, int outputQuantity, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, outputQuantity)
+ .patternLine("##")
+ .patternLine("##")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeFenceRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 3)
+ .patternLine("#I#")
+ .patternLine("#I#")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeGateRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("I#I")
+ .patternLine("I#I")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeDoorRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 3)
+ .patternLine("##")
+ .patternLine("##")
+ .patternLine("##")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeTrapdoorRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 2)
+ .patternLine("###")
+ .patternLine("###")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeWallRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result, 6)
+ .patternLine("###")
+ .patternLine("###")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeRoundRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("###")
+ .patternLine("# #")
+ .patternLine("###")
+ .key('#', ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeSignRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("###")
+ .patternLine("###")
+ .patternLine(" I ")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeBarrelRecipe(ResourceLocation input1, ResourceLocation input2, ResourceLocation output, Consumer consumer) {
+ IItemProvider block = getRegisteredItem(input1);
+ IItemProvider slab = getRegisteredItem(input2);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("#S#")
+ .patternLine("# #")
+ .patternLine("#S#")
+ .key('#', block)
+ .key('S', slab)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(block), hasItem(block))
+ .build(consumer, getPath(result) + "_from_" + getPath(block));
+ }
+
+ public static void makeLadderRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("I I")
+ .patternLine("I#I")
+ .patternLine("I I")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeTaburetRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("##")
+ .patternLine("II")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeChairRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("I ")
+ .patternLine("##")
+ .patternLine("II")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeBarStoolRecipe(ResourceLocation input, ResourceLocation output, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("##")
+ .patternLine("II")
+ .patternLine("II")
+ .key('#', ingredient)
+ .key('I', Items.STICK)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ public static void makeFireBowlRecipe(ResourceLocation input1, ResourceLocation input2, ResourceLocation input3, ResourceLocation output, Consumer consumer) {
+ IItemProvider block = getRegisteredItem(input1);
+ IItemProvider leg = getRegisteredItem(input2);
+ IItemProvider inside = getRegisteredItem(input3);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapedRecipeBuilder.shapedRecipe(result)
+ .patternLine("#I#")
+ .patternLine(" # ")
+ .patternLine("L L")
+ .key('#', block)
+ .key('I', inside)
+ .key('L', leg)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(block), hasItem(block))
+ .build(consumer, getPath(result) + "_from_" + getPath(block));
+ }
+
+ // SHAPELESS RECIPES //
+
+ public static void makeShapelessSingleInputRecipe(ResourceLocation input, ResourceLocation output, int outputQuantity, Consumer consumer) {
+ IItemProvider ingredient = getRegisteredItem(input);
+ IItemProvider result = getRegisteredItem(output);
+
+ ShapelessRecipeBuilder.shapelessRecipe(result, outputQuantity)
+ .addIngredient(ingredient)
+ .setGroup(BetterNether.MOD_ID)
+ .addCriterion(getPath(ingredient), hasItem(ingredient))
+ .build(consumer, getPath(result) + "_from_" + getPath(ingredient));
+ }
+
+ private static String getPath(IItemProvider item) {
+ return item.asItem().getRegistryName().getPath();
+ }
+
+ private static IItemProvider getRegisteredItem(ResourceLocation loc) {
+ return ForgeRegistries.ITEMS.getValue(loc);
+ }
+
+ public static class SingleInputRecipe {
+ public final ResourceLocation input;
+ public final ResourceLocation output;
+ public int quantityOut = 1;
+
+ public SingleInputRecipe(Block input, Block output) {
+ this.input = input.getRegistryName();
+ this.output = output.getRegistryName();
+ }
+
+ public SingleInputRecipe(Block input, Block output, int quantityOut) {
+ this.input = input.getRegistryName();
+ this.output = output.getRegistryName();
+ this.quantityOut = quantityOut;
+ }
+ }
+
+ public static class TwoInputRecipe {
+ public final ResourceLocation input1;
+ public final ResourceLocation input2;
+ public final ResourceLocation output;
+
+ public TwoInputRecipe(Block input1, Block input2, Block output) {
+ this.input1 = input1.getRegistryName();
+ this.input2 = input2.getRegistryName();
+ this.output = output.getRegistryName();
+ }
+ }
+
+ public static class FireBowlRecipe {
+ public final ResourceLocation source;
+ public final ResourceLocation inside;
+ public final ResourceLocation legs;
+ public final ResourceLocation output;
+
+ public FireBowlRecipe(Block input1, Block input2, Item input3, Block output) {
+ this.source = input1.getRegistryName();
+ this.inside = input2.getRegistryName();
+ this.legs = input3.getRegistryName();
+ this.output = output.getRegistryName();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/datagen/DataGenerators.java b/src/main/java/redd90/betternether/datagen/DataGenerators.java
new file mode 100644
index 0000000..380a136
--- /dev/null
+++ b/src/main/java/redd90/betternether/datagen/DataGenerators.java
@@ -0,0 +1,13 @@
+package redd90.betternether.datagen;
+
+import net.minecraft.data.DataGenerator;
+import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
+
+public class DataGenerators {
+ public static void gatherData(GatherDataEvent event) {
+ if(event.includeServer()) {
+ DataGenerator generator = event.getGenerator();
+ generator.addProvider(new BNRecipes(generator));
+ }
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/EntityChair.java b/src/main/java/redd90/betternether/entity/EntityChair.java
new file mode 100644
index 0000000..6ba9f18
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityChair.java
@@ -0,0 +1,38 @@
+package redd90.betternether.entity;
+
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.ai.attributes.AttributeModifierMap;
+import net.minecraft.entity.ai.attributes.Attributes;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.World;
+import redd90.betternether.blocks.BNChair;
+
+public class EntityChair extends MobEntity {
+ public EntityChair(EntityType extends EntityChair> type, World world) {
+ super(type, world);
+ }
+
+ @Override
+ public void tick() {
+ if (!this.isBeingRidden())
+ this.remove();
+ else if (this.getBlockState().getBlock() instanceof BNChair)
+ super.tick();
+ else {
+ this.removePassengers();
+ this.remove();
+ }
+ }
+
+ @Override
+ public void livingTick() {
+ super.livingTick();
+ this.setMotion(Vector3d.ZERO);
+ }
+
+ public static AttributeModifierMap getAttributeContainer() {
+ return MobEntity.func_233666_p_().createMutableAttribute(Attributes.MAX_HEALTH, 0).create();
+
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/EntityFirefly.java b/src/main/java/redd90/betternether/entity/EntityFirefly.java
new file mode 100644
index 0000000..501291e
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityFirefly.java
@@ -0,0 +1,560 @@
+package redd90.betternether.entity;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Random;
+
+import net.minecraft.block.Block;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.material.Material;
+import net.minecraft.entity.AgeableEntity;
+import net.minecraft.entity.CreatureAttribute;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.SpawnReason;
+import net.minecraft.entity.ai.RandomPositionGenerator;
+import net.minecraft.entity.ai.attributes.AttributeModifierMap;
+import net.minecraft.entity.ai.attributes.Attributes;
+import net.minecraft.entity.ai.controller.FlyingMovementController;
+import net.minecraft.entity.ai.controller.LookController;
+import net.minecraft.entity.ai.goal.BreedGoal;
+import net.minecraft.entity.ai.goal.FollowParentGoal;
+import net.minecraft.entity.ai.goal.Goal;
+import net.minecraft.entity.ai.goal.SwimGoal;
+import net.minecraft.entity.passive.AnimalEntity;
+import net.minecraft.entity.passive.IFlyingAnimal;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.network.datasync.DataParameter;
+import net.minecraft.network.datasync.DataSerializers;
+import net.minecraft.network.datasync.EntityDataManager;
+import net.minecraft.pathfinding.FlyingPathNavigator;
+import net.minecraft.pathfinding.Path;
+import net.minecraft.pathfinding.PathNavigator;
+import net.minecraft.pathfinding.PathNodeType;
+import net.minecraft.tags.ITag;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.util.math.vector.Vector3i;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.BlocksRegistry;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+
+public class EntityFirefly extends AnimalEntity implements IFlyingAnimal {
+ private static final HashSet FLOWERS;
+ private static final Vector3i[] SEARCH;
+
+ private static final DataParameter COLOR_RED = EntityDataManager.createKey(EntityFirefly.class, DataSerializers.FLOAT);
+ private static final DataParameter COLOR_GREEN = EntityDataManager.createKey(EntityFirefly.class, DataSerializers.FLOAT);
+ private static final DataParameter COLOR_BLUE = EntityDataManager.createKey(EntityFirefly.class, DataSerializers.FLOAT);
+
+ private boolean mustSit = false;
+
+ public EntityFirefly(EntityType extends EntityFirefly> type, World world) {
+ super(type, world);
+ this.moveController = new FlyingMovementController(this, 20, true);
+ this.lookController = new FreflyLookControl(this);
+ this.setPathPriority(PathNodeType.LAVA, -1.0F);
+ this.setPathPriority(PathNodeType.WATER, -1.0F);
+ this.setPathPriority(PathNodeType.DANGER_FIRE, 0.0F);
+ this.experienceValue = 1;
+ }
+
+ @Override
+ protected void registerData() {
+ super.registerData();
+ makeColor(rand.nextFloat(), rand.nextFloat() * 0.5F + 0.25F, 1);
+ }
+
+ public static AttributeModifierMap getAttributeContainer() {
+ return MobEntity
+ .func_233666_p_()
+ .createMutableAttribute(Attributes.MAX_HEALTH, 1.0)
+ .createMutableAttribute(Attributes.FLYING_SPEED, 0.6)
+ .createMutableAttribute(Attributes.MOVEMENT_SPEED, 0.25)
+ .createMutableAttribute(Attributes.FOLLOW_RANGE, 48.0)
+ .create();
+ }
+
+ @Override
+ protected PathNavigator createNavigator(World world) {
+ FlyingPathNavigator birdNavigation = new FlyingPathNavigator(this, world) {
+ public boolean canEntityStandOnPos(BlockPos pos) {
+ BlockState state = this.world.getBlockState(pos.down());
+ boolean valid = !state.getBlock().isAir(state, this.world, pos.down()) && state.getMaterial() != Material.LAVA;
+ if (valid) {
+ state = this.world.getBlockState(pos);
+ valid = state.getBlock().isAir(state, this.world, pos) || !state.getMaterial().blocksMovement();
+ valid = valid && state.getBlock() != BlocksRegistry.EGG_PLANT;
+ valid = valid && !state.getMaterial().blocksMovement();
+ }
+ return valid;
+ }
+
+ public void tick() {
+ super.tick();
+ }
+ };
+ birdNavigation.setCanOpenDoors(false);
+ birdNavigation.setCanSwim(false);
+ birdNavigation.setCanEnterDoors(true);
+ return birdNavigation;
+ }
+
+ @Override
+ protected void registerGoals() {
+ this.goalSelector.addGoal(1, new SwimGoal(this));
+ this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D));
+ this.goalSelector.addGoal(3, new FollowParentGoal(this, 1.0D));
+ this.goalSelector.addGoal(4, new SittingGoal());
+ this.goalSelector.addGoal(5, new MoveToFlowersGoal());
+ this.goalSelector.addGoal(6, new WanderAroundGoal());
+ this.goalSelector.addGoal(7, new MoveRandomGoal());
+ }
+
+ @Override
+ public float getBlockPathWeight(BlockPos pos, IWorldReader worldView) {
+ return worldView.getBlockState(pos).getBlock().isAir(worldView.getBlockState(pos), worldView, pos) ? 10.0F : 0.0F;
+ }
+
+ @Override
+ public boolean isBreedingItem(ItemStack stack) {
+ return stack.getItem() == Items.GLOWSTONE_DUST;
+ }
+
+ @Override
+ protected boolean makeFlySound() {
+ return true;
+ }
+
+ @Override
+ public CreatureAttribute getCreatureAttribute() {
+ return CreatureAttribute.ARTHROPOD;
+ }
+
+ @Override
+ protected void handleFluidJump(ITag fluid) {
+ this.setMotion(this.getMotion().add(0.0D, 0.01D, 0.0D));
+ }
+
+ @Override
+ public float getBrightness() {
+ return 1.0F;
+ }
+
+ @Override
+ public boolean onLivingFall(float fallDistance, float damageMultiplier) {
+ return false;
+ }
+
+ @Override
+ protected void updateFallState(double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition) {}
+
+ @Override
+ public boolean canTriggerWalking() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNoGravity() {
+ return true;
+ }
+
+ public float getRed() {
+ return this.dataManager.get(COLOR_RED);
+ }
+
+ public float getGreen() {
+ return this.dataManager.get(COLOR_GREEN);
+ }
+
+ public float getBlue() {
+ return this.dataManager.get(COLOR_BLUE);
+ }
+
+ @Override
+ public void writeAdditional(CompoundNBT tag) {
+ super.writeAdditional(tag);
+
+ tag.putFloat("ColorRed", getRed());
+ tag.putFloat("ColorGreen", getGreen());
+ tag.putFloat("ColorBlue", getBlue());
+ }
+
+ @Override
+ public void readAdditional(CompoundNBT tag) {
+ super.readAdditional(tag);
+
+ if (tag.contains("ColorRed")) {
+ this.dataManager.set(COLOR_RED, tag.getFloat("ColorRed"));
+ }
+
+ if (tag.contains("ColorGreen")) {
+ this.dataManager.set(COLOR_GREEN, tag.getFloat("ColorGreen"));
+ }
+
+ if (tag.contains("ColorBlue")) {
+ this.dataManager.set(COLOR_BLUE, tag.getFloat("ColorBlue"));
+ }
+ }
+
+ @Override
+ public AgeableEntity func_241840_a(ServerWorld world, AgeableEntity mate) {
+ return null; //EntityRegistry.FIREFLY.create(world);
+ }
+
+ class FreflyLookControl extends LookController {
+ FreflyLookControl(MobEntity entity) {
+ super(entity);
+ }
+
+ protected boolean shouldStayHorizontal() {
+ return true;
+ }
+ }
+
+ class WanderAroundGoal extends Goal {
+ WanderAroundGoal() {
+ this.setMutexFlags(EnumSet.of(Goal.Flag.MOVE));
+ }
+
+ @Override
+ public boolean shouldExecute() {
+ return EntityFirefly.this.navigator.noPath() && EntityFirefly.this.rand.nextInt(10) == 0;
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return EntityFirefly.this.navigator.hasPath();
+ }
+
+ @Override
+ public void startExecuting() {
+ BlockPos pos = this.getRandomLocation();
+ // if (pos != null)
+ // {
+ Path path = EntityFirefly.this.navigator.getPathToPos(pos, 1);
+ if (path != null)
+ EntityFirefly.this.navigator.setPath(path, 1.0D);
+ else
+ EntityFirefly.this.setVelocity(0, -0.2, 0);
+ // }
+ super.startExecuting();
+ }
+
+ private BlockPos getRandomLocation() {
+ World w = EntityFirefly.this.world;
+ Mutable bpos = new Mutable();
+ bpos.setPos(EntityFirefly.this.getPosX(), EntityFirefly.this.getPosY(), EntityFirefly.this.getPosZ());
+
+ if (w.isAirBlock(bpos.down(2)) && w.isAirBlock(bpos.down())) {
+ int y = bpos.getY() - 1;
+ while (w.isAirBlock(bpos.down(2)) && y > 0)
+ bpos.setY(y--);
+ return bpos;
+ }
+
+ Vector3d angle = EntityFirefly.this.getLook(0.0F);
+ Vector3d airTarget = RandomPositionGenerator.findAirTarget(EntityFirefly.this, 8, 7, angle, 1.5707964F, 2, 1);
+
+ if (airTarget == null) {
+ airTarget = RandomPositionGenerator.findAirTarget(EntityFirefly.this, 16, 10, angle, 1.5707964F, 3, 1);
+ }
+
+ if (airTarget == null) {
+ bpos.setX(bpos.getX() + randomRange(8));
+ bpos.setZ(bpos.getZ() + randomRange(8));
+ bpos.setY(bpos.getY() + randomRange(2));
+ return bpos;
+ }
+
+ bpos.setPos(airTarget.getX(), airTarget.getY(), airTarget.getZ());
+
+ return bpos;
+ }
+
+ private int randomRange(int side) {
+ Random rand = EntityFirefly.this.rand;
+ return rand.nextInt(side + 1) - (side >> 1);
+ }
+
+ @Override
+ public void tick() {
+ checkMovement();
+ super.tick();
+ }
+ }
+
+ class MoveToFlowersGoal extends Goal {
+ MoveToFlowersGoal() {
+ this.setMutexFlags(EnumSet.of(Goal.Flag.MOVE));
+ }
+
+ @Override
+ public boolean shouldExecute() {
+ return EntityFirefly.this.navigator.noPath() && EntityFirefly.this.rand.nextInt(30) == 0;
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return EntityFirefly.this.navigator.hasPath();
+ }
+
+ @Override
+ public void startExecuting() {
+ BlockPos pos = this.getFlowerLocation();
+ if (pos != null) {
+ Path path = EntityFirefly.this.navigator.getPathToPos((BlockPos) (new BlockPos(pos)), 1);
+ EntityFirefly.this.navigator.setPath(path, 1.0D);
+ }
+ super.startExecuting();
+ }
+
+ @Override
+ public void resetTask() {
+ if (isFlower(EntityFirefly.this.getBlockState()))
+ EntityFirefly.this.mustSit = true;
+ super.resetTask();
+ }
+
+ private BlockPos getFlowerLocation() {
+ World w = EntityFirefly.this.world;
+ Mutable bpos = new Mutable();
+
+ for (Vector3i offset : SEARCH) {
+ bpos.setPos(
+ EntityFirefly.this.getPosX() + offset.getX(),
+ EntityFirefly.this.getPosY() + offset.getY(),
+ EntityFirefly.this.getPosZ() + offset.getZ());
+ if (isFlower(w.getBlockState(bpos)))
+ return bpos;
+ }
+
+ return null;
+ }
+
+ private boolean isFlower(BlockState state) {
+ Block b = state.getBlock();
+ return FLOWERS.contains(b);
+ }
+
+ @Override
+ public void tick() {
+ checkMovement();
+ super.tick();
+ }
+ }
+
+ private void checkMovement() {
+ Vector3d vel = EntityFirefly.this.getMotion();
+ if (Math.abs(vel.x) > 0.1 || Math.abs(vel.z) > 0.1) {
+ double d = Math.abs(EntityFirefly.this.prevPosX - EntityFirefly.this.getPosX());
+ d += Math.abs(EntityFirefly.this.prevPosZ - EntityFirefly.this.getPosZ());
+ if (d < 0.1)
+ EntityFirefly.this.navigator.clearPath();
+ }
+ }
+
+ class SittingGoal extends Goal {
+ int timer;
+ int ammount;
+
+ SittingGoal() {}
+
+ @Override
+ public boolean shouldExecute() {
+ if (EntityFirefly.this.mustSit && EntityFirefly.this.navigator.noPath()) {
+ BlockPos pos = new BlockPos(EntityFirefly.this.getPosX(), EntityFirefly.this.getPosY(), EntityFirefly.this.getPosZ());
+ BlockState state = EntityFirefly.this.world.getBlockState(pos.down());
+ return !state.getBlock().isAir(state, EntityFirefly.this.world, pos.down()) && !state.getMaterial().isLiquid();
+ }
+ return false;
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return timer < ammount;
+ }
+
+ @Override
+ public void startExecuting() {
+ timer = 0;
+ ammount = EntityFirefly.this.rand.nextInt(21) + 20;
+ EntityFirefly.this.mustSit = false;
+ EntityFirefly.this.setVelocity(0, -0.1, 0);
+ super.startExecuting();
+ }
+
+ @Override
+ public void resetTask() {
+ EntityFirefly.this.setVelocity(0, 0.1, 0);
+ super.resetTask();
+ }
+
+ @Override
+ public void tick() {
+ timer++;
+ super.tick();
+ }
+ }
+
+ class MoveRandomGoal extends Goal {
+ int timer;
+ int ammount;
+
+ MoveRandomGoal() {}
+
+ @Override
+ public boolean shouldExecute() {
+ return EntityFirefly.this.navigator.noPath() && EntityFirefly.this.rand.nextInt(20) == 0;
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return timer < ammount;
+ }
+
+ @Override
+ public void startExecuting() {
+ timer = 0;
+ ammount = EntityFirefly.this.rand.nextInt(30) + 10;
+ Vector3d velocity = new Vector3d(
+ EntityFirefly.this.rand.nextDouble(),
+ EntityFirefly.this.rand.nextDouble(),
+ EntityFirefly.this.rand.nextDouble());
+ if (velocity.lengthSquared() == 0)
+ velocity = new Vector3d(1, 0, 0);
+ EntityFirefly.this.setMotion(velocity.normalize().scale(EntityFirefly.this.jumpMovementFactor));
+ super.startExecuting();
+ }
+
+ @Override
+ public void tick() {
+ timer++;
+ super.tick();
+ }
+ }
+
+ @Override
+ public SoundEvent getAmbientSound() {
+ return SoundsRegistry.MOB_FIREFLY_FLY;
+ }
+
+ @Override
+ protected float getSoundVolume() {
+ return MHelper.randRange(0.1F, 0.3F, rand);
+ }
+
+ private void makeColor(float hue, float saturation, float brightness) {
+ float red = 0;
+ float green = 0;
+ float blue = 0;
+ float f3 = (hue - (float) Math.floor(hue)) * 6F;
+ float f4 = f3 - (float) Math.floor(f3);
+ float f5 = brightness * (1.0F - saturation);
+ float f6 = brightness * (1.0F - saturation * f4);
+ float f7 = brightness * (1.0F - saturation * (1.0F - f4));
+ switch ((int) f3) {
+ case 0:
+ red = (byte) (brightness * 255F + 0.5F);
+ green = (byte) (f7 * 255F + 0.5F);
+ blue = (byte) (f5 * 255F + 0.5F);
+ break;
+ case 1:
+ red = (byte) (f6 * 255F + 0.5F);
+ green = (byte) (brightness * 255F + 0.5F);
+ blue = (byte) (f5 * 255F + 0.5F);
+ break;
+ case 2:
+ red = (byte) (f5 * 255F + 0.5F);
+ green = (byte) (brightness * 255F + 0.5F);
+ blue = (byte) (f7 * 255F + 0.5F);
+ break;
+ case 3:
+ red = (byte) (f5 * 255F + 0.5F);
+ green = (byte) (f6 * 255F + 0.5F);
+ blue = (byte) (brightness * 255F + 0.5F);
+ break;
+ case 4:
+ red = (byte) (f7 * 255F + 0.5F);
+ green = (byte) (f5 * 255F + 0.5F);
+ blue = (byte) (brightness * 255F + 0.5F);
+ break;
+ case 5:
+ red = (byte) (brightness * 255F + 0.5F);
+ green = (byte) (f5 * 255F + 0.5F);
+ blue = (byte) (f6 * 255F + 0.5F);
+ break;
+ }
+ this.dataManager.register(COLOR_RED, red / 255F);
+ this.dataManager.register(COLOR_GREEN, green / 255F);
+ this.dataManager.register(COLOR_BLUE, blue / 255F);
+ }
+
+ @Override
+ public int getMaxSpawnedInChunk() {
+ return 5;
+ }
+
+ static {
+ ArrayList points = new ArrayList();
+ int radius = 6;
+ int r2 = radius * radius;
+ for (int x = -radius; x <= radius; x++)
+ for (int y = -radius; y <= radius; y++)
+ for (int z = -radius; z <= radius; z++)
+ if (x * x + y * y + z * z <= r2)
+ points.add(new Vector3i(x, y, z));
+ points.sort(new Comparator() {
+ @Override
+ public int compare(Vector3i v1, Vector3i v2) {
+ int d1 = v1.getX() * v1.getX() + v1.getY() * v1.getY() + v1.getZ() * v1.getZ();
+ int d2 = v2.getX() * v2.getX() + v2.getY() * v2.getY() + v2.getZ() * v2.getZ();
+ return d1 - d2;
+ }
+ });
+ SEARCH = points.toArray(new Vector3i[] {});
+
+ FLOWERS = new HashSet();
+ FLOWERS.add(BlocksRegistry.NETHER_GRASS);
+ FLOWERS.add(BlocksRegistry.SOUL_GRASS);
+ FLOWERS.add(BlocksRegistry.SWAMP_GRASS);
+ FLOWERS.add(BlocksRegistry.BLACK_APPLE);
+ FLOWERS.add(BlocksRegistry.MAGMA_FLOWER);
+ FLOWERS.add(BlocksRegistry.SOUL_VEIN);
+ FLOWERS.add(BlocksRegistry.NETHER_REED);
+ FLOWERS.add(BlocksRegistry.INK_BUSH);
+ FLOWERS.add(BlocksRegistry.INK_BUSH_SEED);
+ FLOWERS.add(BlocksRegistry.POTTED_PLANT);
+ FLOWERS.add(Blocks.NETHER_WART);
+ }
+
+ public static boolean canSpawn(EntityType extends EntityFirefly> type, IWorld world, SpawnReason spawnReason, BlockPos pos, Random rand) {
+ if (pos.getY() >= world.getDimensionType().getLogicalHeight()) return false;
+ int h = BlocksHelper.downRay(world, pos, 10);
+ if (h > 8)
+ return false;
+ for (int i = 1; i <= h; i++)
+ if (BlocksHelper.isLava(world.getBlockState(pos.down(i))))
+ return false;
+ return true;
+ }
+
+ @Override
+ public boolean canBePushed() {
+ return false;
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/EntityFlyingPig.java b/src/main/java/redd90/betternether/entity/EntityFlyingPig.java
new file mode 100644
index 0000000..18eb3d1
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityFlyingPig.java
@@ -0,0 +1,459 @@
+package redd90.betternether.entity;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.entity.AgeableEntity;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.ai.RandomPositionGenerator;
+import net.minecraft.entity.ai.attributes.AttributeModifierMap;
+import net.minecraft.entity.ai.attributes.Attributes;
+import net.minecraft.entity.ai.controller.FlyingMovementController;
+import net.minecraft.entity.ai.goal.BreedGoal;
+import net.minecraft.entity.ai.goal.Goal;
+import net.minecraft.entity.ai.goal.LookAtGoal;
+import net.minecraft.entity.ai.goal.LookRandomlyGoal;
+import net.minecraft.entity.ai.goal.NearestAttackableTargetGoal;
+import net.minecraft.entity.item.ItemEntity;
+import net.minecraft.entity.passive.AnimalEntity;
+import net.minecraft.entity.passive.IFlyingAnimal;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.network.datasync.DataParameter;
+import net.minecraft.network.datasync.DataSerializers;
+import net.minecraft.network.datasync.EntityDataManager;
+import net.minecraft.network.play.server.SSpawnParticlePacket;
+import net.minecraft.particles.ItemParticleData;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.pathfinding.FlyingPathNavigator;
+import net.minecraft.pathfinding.Path;
+import net.minecraft.pathfinding.PathNavigator;
+import net.minecraft.pathfinding.PathNodeType;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Direction;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.BlockPos.Mutable;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.GameRules;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.BlocksHelper;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.EntityRegistry;
+
+public class EntityFlyingPig extends AnimalEntity implements IFlyingAnimal {
+ private static final DataParameter FLAGS;
+ private static final int BIT_ROOSTING = 0;
+ private static final int BIT_WARTED = 1;
+ private Goal preGoal;
+
+ public EntityFlyingPig(EntityType extends EntityFlyingPig> type, World world) {
+ super(type, world);
+ this.moveController = new FlyingMovementController(this, 20, true);
+ this.setPathPriority(PathNodeType.LAVA, 0.0F);
+ this.setPathPriority(PathNodeType.WATER, 0.0F);
+ this.experienceValue = 2;
+ this.jumpMovementFactor = 0.3F;
+ }
+
+ @Override
+ protected void registerGoals() {
+ this.targetSelector.addGoal(1, new NearestAttackableTargetGoal(this, PlayerEntity.class, true));
+ this.goalSelector.addGoal(2, new FindFoodGoal());
+ this.goalSelector.addGoal(3, new BreedGoal(this, 1.0D));
+ this.goalSelector.addGoal(4, new SittingGoal());
+ this.goalSelector.addGoal(5, new RoostingGoal());
+ this.goalSelector.addGoal(6, new WanderAroundGoal());
+ this.goalSelector.addGoal(7, new LookRandomlyGoal(this));
+ this.goalSelector.addGoal(8, new LookAtGoal(this, PlayerEntity.class, 8.0F));
+ }
+
+ public static AttributeModifierMap getAttributeContainer() {
+ return MobEntity
+ .func_233666_p_()
+ .createMutableAttribute(Attributes.MAX_HEALTH, 6.0)
+ .createMutableAttribute(Attributes.FOLLOW_RANGE, 12.0)
+ .createMutableAttribute(Attributes.MOVEMENT_SPEED, 0.3)
+ .createMutableAttribute(Attributes.FLYING_SPEED, 0.3)
+ .createMutableAttribute(Attributes.ATTACK_DAMAGE, 3.0)
+ .createMutableAttribute(Attributes.ARMOR, 1.0)
+ .create();
+ }
+
+ @Override
+ protected PathNavigator createNavigator(World world) {
+ FlyingPathNavigator birdnavigator = new FlyingPathNavigator(this, world) {
+ public boolean canEntityStandOnPos(BlockPos pos) {
+ return this.world.isAirBlock(pos);
+ }
+ };
+ birdnavigator.setCanOpenDoors(false);
+ birdnavigator.setCanSwim(true);
+ birdnavigator.setCanEnterDoors(true);
+ return birdnavigator;
+ }
+
+ @Override
+ protected void registerData() {
+ super.registerData();
+ this.dataManager.register(FLAGS, MHelper.setBit((byte) 0, BIT_WARTED, rand.nextInt(4) == 0));
+ }
+
+ @Override
+ public void writeAdditional(CompoundNBT tag) {
+ super.writeAdditional(tag);
+
+ tag.putByte("byteData", this.dataManager.get(FLAGS));
+ }
+
+ @Override
+ public void readAdditional(CompoundNBT tag) {
+ super.readAdditional(tag);
+
+ if (tag.contains("byteData")) {
+ this.dataManager.set(FLAGS, tag.getByte("byteData"));
+ }
+ }
+
+ public boolean isRoosting() {
+ byte b = this.dataManager.get(FLAGS);
+ return MHelper.getBit(b, BIT_ROOSTING);
+ }
+
+ public void setRoosting(boolean roosting) {
+ byte b = this.dataManager.get(FLAGS);
+ this.dataManager.set(FLAGS, MHelper.setBit(b, BIT_ROOSTING, roosting));
+ }
+
+ public boolean isWarted() {
+ byte b = this.dataManager.get(FLAGS);
+ return MHelper.getBit(b, BIT_WARTED);
+ }
+
+ public void setWarted(boolean warted) {
+ byte b = this.dataManager.get(FLAGS);
+ this.dataManager.set(FLAGS, MHelper.setBit(b, BIT_WARTED, warted));
+ }
+
+ @Override
+ protected float getSoundVolume() {
+ return MHelper.randRange(0.85F, 1.15F, rand);
+ }
+
+ @Override
+ protected float getSoundPitch() {
+ return MHelper.randRange(0.3F, 0.4F, rand);
+ }
+
+ @Override
+ protected SoundEvent getHurtSound(DamageSource source) {
+ return SoundEvents.ENTITY_PIG_HURT;
+ }
+
+ @Override
+ protected SoundEvent getDeathSound() {
+ return SoundEvents.ENTITY_PIG_DEATH;
+ }
+
+ @Override
+ public SoundEvent getAmbientSound() {
+ return SoundEvents.ENTITY_PIG_AMBIENT;
+ }
+
+ @Override
+ public boolean canBePushed() {
+ return false;
+ }
+
+ @Override
+ protected void collideWithEntity(Entity entity) {}
+
+ @Override
+ protected void collideWithNearbyEntities() {}
+
+ @Override
+ protected boolean makeFlySound() {
+ return true;
+ }
+
+ @Override
+ public boolean canTriggerWalking() {
+ return false;
+ }
+
+ @Override
+ public boolean onLivingFall(float fallDistance, float damageMultiplier) {
+ return false;
+ }
+
+ @Override
+ protected void updateFallState(double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition) {}
+
+ @Override
+ protected void onDeathUpdate() {
+ if (!world.isRemote && this.isWarted() && world.getServer().getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) {
+ this.entityDropItem(new ItemStack(Items.NETHER_WART, MHelper.randRange(1, 3, rand)));
+ }
+ super.onDeathUpdate();
+
+ }
+
+ @Override
+ public int getMaxSpawnedInChunk() {
+ return 5;
+ }
+
+ static {
+ FLAGS = EntityDataManager.createKey(EntityFlyingPig.class, DataSerializers.BYTE);
+ }
+
+ class WanderAroundGoal extends Goal {
+ WanderAroundGoal() {
+ this.setMutexFlags(EnumSet.of(Goal.Flag.MOVE));
+ }
+
+ public boolean shouldExecute() {
+ return EntityFlyingPig.this.navigator.noPath() && !EntityFlyingPig.this.isRoosting();
+ }
+
+ public boolean shouldContinueExecuting() {
+ return EntityFlyingPig.this.navigator.hasPath() && EntityFlyingPig.this.rand.nextInt(32) > 0;
+ }
+
+ public void startExecuting() {
+ if (EntityFlyingPig.this.world.getFluidState(EntityFlyingPig.this.getPosition()).isEmpty()) {
+ BlockPos pos = this.getRandomLocation();
+ Path path = EntityFlyingPig.this.navigator.getPathToPos(pos, 1);
+ if (path != null)
+ EntityFlyingPig.this.navigator.setPath(path, EntityFlyingPig.this.jumpMovementFactor);
+ else
+ EntityFlyingPig.this.setVelocity(0, -0.2, 0);
+ EntityFlyingPig.this.setRoosting(false);
+ }
+ else
+ EntityFlyingPig.this.setVelocity(0, 1, 0);
+ super.startExecuting();
+ }
+
+ private BlockPos getRandomLocation() {
+ Mutable bpos = new Mutable();
+ bpos.setPos(EntityFlyingPig.this.getPosX(), EntityFlyingPig.this.getPosY(), EntityFlyingPig.this.getPosZ());
+
+ Vector3d angle = EntityFlyingPig.this.getLook(0.0F);
+ Vector3d airTarget = RandomPositionGenerator.findAirTarget(EntityFlyingPig.this, 8, 7, angle, 1.5707964F, 2, 1);
+
+ if (airTarget == null) {
+ airTarget = RandomPositionGenerator.findAirTarget(EntityFlyingPig.this, 32, 10, angle, 1.5707964F, 3, 1);
+ }
+
+ if (airTarget == null) {
+ bpos.setX(bpos.getX() + randomRange(32));
+ bpos.setZ(bpos.getZ() + randomRange(32));
+ bpos.setY(bpos.getY() + randomRange(32));
+ return bpos;
+ }
+
+ bpos.setPos(airTarget.getX(), airTarget.getY(), airTarget.getZ());
+ BlockPos down = bpos.down();
+ if (EntityFlyingPig.this.world.getBlockState(down).hasOpaqueCollisionShape(EntityFlyingPig.this.world, down))
+ bpos.move(Direction.UP);
+
+ while (!EntityFlyingPig.this.world.getFluidState(bpos).isEmpty())
+ bpos.move(Direction.UP);
+
+ return bpos;
+ }
+
+ private int randomRange(int side) {
+ Random rand = EntityFlyingPig.this.rand;
+ return rand.nextInt(side + 1) - (side >> 1);
+ }
+
+ @Override
+ public void resetTask() {
+ EntityFlyingPig.this.preGoal = this;
+ super.resetTask();
+ }
+ }
+
+ class RoostingGoal extends Goal {
+ BlockPos roosting;
+
+ @Override
+ public boolean shouldExecute() {
+ return !(EntityFlyingPig.this.preGoal instanceof SittingGoal) &&
+ EntityFlyingPig.this.navigator.noPath() &&
+ !EntityFlyingPig.this.isRoosting() &&
+ EntityFlyingPig.this.rand.nextInt(4) == 0;
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return EntityFlyingPig.this.navigator.hasPath();
+ }
+
+ @Override
+ public void startExecuting() {
+ BlockPos pos = this.getRoostingLocation();
+ if (pos != null) {
+ Path path = EntityFlyingPig.this.navigator.getPathToPos(pos, 1);
+ if (path != null) {
+ EntityFlyingPig.this.navigator.setPath(path, EntityFlyingPig.this.jumpMovementFactor);
+ this.roosting = pos;
+ }
+ }
+ super.startExecuting();
+ }
+
+ @Override
+ public void resetTask() {
+ if (this.roosting != null) {
+ EntityFlyingPig.this.setPosition(roosting.getX() + 0.5, roosting.getY() - 0.25, roosting.getZ() + 0.5);
+ EntityFlyingPig.this.setRoosting(true);
+ EntityFlyingPig.this.preGoal = this;
+ }
+ super.resetTask();
+ }
+
+ private BlockPos getRoostingLocation() {
+ BlockPos pos = EntityFlyingPig.this.getPosition();
+ World world = EntityFlyingPig.this.world;
+ int up = BlocksHelper.upRay(world, pos, 16);
+ pos = pos.offset(Direction.UP, up);
+ if (world.getBlockState(pos.up()).getBlock() == Blocks.NETHER_WART_BLOCK)
+ return pos;
+ else
+ return null;
+ }
+ }
+
+ class SittingGoal extends Goal {
+ int timer;
+ int ammount;
+
+ @Override
+ public boolean shouldExecute() {
+ return EntityFlyingPig.this.isRoosting();
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return timer < ammount;
+ }
+
+ @Override
+ public void startExecuting() {
+ timer = 0;
+ ammount = MHelper.randRange(80, 160, EntityFlyingPig.this.rand);
+ EntityFlyingPig.this.setVelocity(0, 0, 0);
+ EntityFlyingPig.this.setRenderYawOffset(EntityFlyingPig.this.rand.nextFloat() * MHelper.PI2);
+ super.startExecuting();
+ }
+
+ @Override
+ public void resetTask() {
+ EntityFlyingPig.this.setRoosting(false);
+ EntityFlyingPig.this.setVelocity(0, -0.1F, 0);
+ EntityFlyingPig.this.preGoal = this;
+ super.resetTask();
+ }
+
+ @Override
+ public void tick() {
+ timer++;
+ super.tick();
+ }
+ }
+
+ class FindFoodGoal extends Goal {
+ private List foods;
+ private ItemEntity target;
+
+ @Override
+ public boolean shouldExecute() {
+ return hasNearFood();
+ }
+
+ @Override
+ public void startExecuting() {
+ BlockPos pos = getFood();
+ Path path = EntityFlyingPig.this.navigator.getPathToPos(pos, 1);
+ if (path != null) {
+ EntityFlyingPig.this.navigator.setPath(path, EntityFlyingPig.this.jumpMovementFactor);
+ EntityFlyingPig.this.setRoosting(false);
+ }
+ super.startExecuting();
+ }
+
+ @Override
+ public boolean shouldContinueExecuting() {
+ return target.isAlive() && EntityFlyingPig.this.navigator.hasPath();
+ }
+
+ @Override
+ public void resetTask() {
+ if (target.isAlive() && target.getDistance(EntityFlyingPig.this) < 1.3) {
+ ItemStack stack = ((ItemEntity) target).getItem();
+
+ ItemParticleData effect = new ItemParticleData(ParticleTypes.ITEM, new ItemStack(stack.getItem()));
+
+ Iterator> var14 = world.getPlayers().iterator();
+
+ while (var14.hasNext()) {
+ ServerPlayerEntity serverPlayerEntity = (ServerPlayerEntity) var14.next();
+ if (serverPlayerEntity.getDistanceSq(target.getPosX(), target.getPosY(), target.getPosZ()) < 4096.0D) {
+ serverPlayerEntity.connection.sendPacket(new SSpawnParticlePacket(effect, false,
+ target.getPosX(),
+ target.getPosY() + 0.2,
+ target.getPosZ(),
+ 0.2F, 0.2F, 0.2F, 0, 16));
+ }
+ }
+
+ EntityFlyingPig.this.onFoodEaten(world, stack);
+ target.onKillCommand();
+ EntityFlyingPig.this.heal(stack.getCount());
+ EntityFlyingPig.this.setVelocity(0, 0.2F, 0);
+ }
+ EntityFlyingPig.this.preGoal = this;
+ super.resetTask();
+ }
+
+ private BlockPos getFood() {
+ target = foods.get(EntityFlyingPig.this.rand.nextInt(foods.size()));
+ return target.getPosition();
+ }
+
+ private boolean hasNearFood() {
+ AxisAlignedBB AxisAlignedBB = new AxisAlignedBB(EntityFlyingPig.this.getPosition()).grow(16);
+ foods = EntityFlyingPig.this.world.getEntitiesWithinAABB(ItemEntity.class, AxisAlignedBB, (entity) -> {
+ return ((ItemEntity) entity).getItem().isFood();
+ });
+ return !foods.isEmpty();
+ }
+ }
+
+ @Override
+ public AgeableEntity func_241840_a(ServerWorld world, AgeableEntity mate) {
+ EntityFlyingPig pig = EntityRegistry.FLYING_PIG.create(this.world);
+ pig.setWarted(pig.isWarted());
+ return pig;
+ }
+
+ @Override
+ public boolean isBreedingItem(ItemStack stack) {
+ return stack.getItem() == Items.NETHER_WART;
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/EntityHydrogenJellyfish.java b/src/main/java/redd90/betternether/entity/EntityHydrogenJellyfish.java
new file mode 100644
index 0000000..e82dd85
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityHydrogenJellyfish.java
@@ -0,0 +1,242 @@
+package redd90.betternether.entity;
+
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.AgeableEntity;
+import net.minecraft.entity.EntitySize;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.Pose;
+import net.minecraft.entity.SpawnReason;
+import net.minecraft.entity.ai.attributes.AttributeModifierMap;
+import net.minecraft.entity.ai.attributes.Attributes;
+import net.minecraft.entity.passive.AnimalEntity;
+import net.minecraft.entity.passive.IFlyingAnimal;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.fluid.Fluid;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.network.datasync.DataParameter;
+import net.minecraft.network.datasync.DataSerializers;
+import net.minecraft.network.datasync.EntityDataManager;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.tags.ITag;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.EntityDamageSource;
+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.vector.Vector3d;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.GameRules;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraft.world.server.ServerWorld;
+import redd90.betternether.registry.SoundsRegistry;
+
+public class EntityHydrogenJellyfish extends AnimalEntity implements IFlyingAnimal {
+ private static final DataParameter SCALE = EntityDataManager.createKey(EntityHydrogenJellyfish.class, DataSerializers.FLOAT);
+
+ private Vector3d preVelocity;
+ private Vector3d newVelocity = new Vector3d(0, 0, 0);
+ private int timer;
+ private int timeOut;
+ private float prewYaw;
+ private float nextYaw;
+
+ public EntityHydrogenJellyfish(EntityType extends EntityHydrogenJellyfish> type, World world) {
+ super(type, world);
+ }
+
+ @Override
+ protected void registerData() {
+ super.registerData();
+ this.dataManager.register(SCALE, 0.5F + rand.nextFloat());
+ }
+
+ public static AttributeModifierMap getAttributeContainer() {
+ return MobEntity
+ .func_233666_p_()
+ .createMutableAttribute(Attributes.MAX_HEALTH, 0.5)
+ .createMutableAttribute(Attributes.FLYING_SPEED, 0.05)
+ .createMutableAttribute(Attributes.MOVEMENT_SPEED, 0.5)
+ .createMutableAttribute(Attributes.ATTACK_DAMAGE, 20.0)
+ .create();
+ }
+
+ @Override
+ protected boolean makeFlySound() {
+ return true;
+ }
+
+ @Override
+ protected void handleFluidJump(ITag fluid) {
+ this.setMotion(this.getMotion().add(0.0D, 0.01D, 0.0D));
+ }
+
+ @Override
+ public boolean canTriggerWalking() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNoGravity() {
+ return true;
+ }
+
+ @Override
+ public void writeAdditional(CompoundNBT tag) {
+ super.writeAdditional(tag);
+
+ tag.putFloat("Scale", getScale());
+ }
+
+ @Override
+ public void readAdditional(CompoundNBT tag) {
+ super.readAdditional(tag);
+
+ if (tag.contains("Scale")) {
+ this.dataManager.set(SCALE, tag.getFloat("Scale"));
+ }
+
+ this.recalculateSize();
+ }
+
+ public float getScale() {
+ return this.dataManager.get(SCALE);
+ }
+
+ public EntitySize getDimensions(Pose pose) {
+ return super.getSize(pose).scale(this.getScale());
+ }
+
+ @Override
+ public void onCollideWithPlayer(PlayerEntity player) {
+ player.attackEntityFrom(DamageSource.GENERIC, 3);
+ }
+
+ @Override
+ public void recalculateSize() {
+ double x = this.getPosX();
+ double y = this.getPosY();
+ double z = this.getPosZ();
+ super.recalculateSize();
+ this.setPosition(x, y, z);
+ }
+
+ @Override
+ public void notifyDataManagerChange(DataParameter> data) {
+ if (SCALE.equals(data)) {
+ this.recalculateSize();
+ }
+ }
+
+ @Override
+ protected void updateAITasks() {
+ timer++;
+ if (timer > timeOut) {
+ prewYaw = this.rotationYaw;
+ nextYaw = rand.nextFloat() * 360;
+
+ double rads = Math.toRadians(nextYaw + 90);
+
+ double vx = Math.cos(rads) * this.jumpMovementFactor;
+ double vz = Math.sin(rads) * this.jumpMovementFactor;
+
+ BlockPos bp = getPosition();
+ double vy = rand.nextDouble() * this.jumpMovementFactor * 0.75;
+ if (world.getBlockState(bp).getBlock().isAir(world.getBlockState(bp), world, bp) &&
+ world.getBlockState(bp.down(2)).getBlock().isAir(world.getBlockState(bp.down(2)), world, bp.down(2)) &&
+ world.getBlockState(bp.down(3)).getBlock().isAir(world.getBlockState(bp.down(3)), world, bp.down(3)) &&
+ world.getBlockState(bp.down(4)).getBlock().isAir(world.getBlockState(bp.down(4)), world, bp.down(4))) {
+ vy = -vy;
+ }
+
+ preVelocity = newVelocity;
+ newVelocity = new Vector3d(vx, vy, vz);
+ timer = 0;
+ timeOut = rand.nextInt(300) + 120;
+ }
+ if (timer <= 120) {
+ if (this.rotationYaw != nextYaw) {
+ float delta = timer / 120F;
+ this.rotationYaw = lerpAngleDegrees(delta, prewYaw, nextYaw);
+ this.setVelocity(
+ MathHelper.lerp(delta, preVelocity.x, newVelocity.x),
+ MathHelper.lerp(delta, preVelocity.y, newVelocity.y),
+ MathHelper.lerp(delta, preVelocity.z, newVelocity.z));
+ }
+ }
+ else {
+ this.setMotion(newVelocity);
+ }
+ }
+
+ public static float lerpAngleDegrees(float delta, float first, float second) {
+ return first + delta * MathHelper.wrapDegrees(second - first);
+ }
+
+ @Override
+ public int getMaxSpawnedInChunk() {
+ return 1;
+ }
+
+ @Override
+ public void onDeath(DamageSource source) {
+ super.onDeath(source);
+ if (world.isRemote) {
+ float scale = getScale() * 3;
+ for (int i = 0; i < 20; i++)
+ this.world.addParticle(ParticleTypes.EXPLOSION,
+ getPosX() + rand.nextGaussian() * scale,
+ getEyeHeight() + rand.nextGaussian() * scale,
+ getPosZ() + rand.nextGaussian() * scale,
+ 0, 0, 0);
+ }
+ else {
+ Explosion.Mode destructionType = this.world.getGameRules().getBoolean(GameRules.MOB_GRIEFING) ? Explosion.Mode.DESTROY : Explosion.Mode.NONE;
+ this.world.createExplosion(this, getPosX(), getEyeHeight(), getPosZ(), 7 * getScale(), destructionType);
+ }
+ }
+
+ @Override
+ public SoundEvent getAmbientSound() {
+ return SoundsRegistry.MOB_JELLYFISH;
+ }
+
+ @Override
+ protected float getSoundVolume() {
+ return 0.1F;
+ }
+
+ @Override
+ public AgeableEntity func_241840_a(ServerWorld world, AgeableEntity mate) {
+ return null;
+ }
+
+ @Override
+ public boolean onLivingFall(float fallDistance, float damageMultiplier) {
+ return false;
+ }
+
+ @Override
+ protected void updateFallState(double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition) {}
+
+ @Override
+ public boolean attackEntityFrom(DamageSource source, float amount) {
+ if (source == DamageSource.WITHER || source instanceof EntityDamageSource) {
+ return super.attackEntityFrom(source, amount);
+ }
+ return false;
+ }
+
+ public static boolean canSpawn(EntityType extends EntityHydrogenJellyfish> type, IWorld world, SpawnReason spawnReason, BlockPos pos, Random rand) {
+ AxisAlignedBB box = new AxisAlignedBB(pos).expand(64, 256, 64);
+ List list = world.getEntitiesWithinAABB(EntityHydrogenJellyfish.class, box, (entity) -> {
+ return true;
+ });
+ return list.size() < 4;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/entity/EntityJungleSkeleton.java b/src/main/java/redd90/betternether/entity/EntityJungleSkeleton.java
new file mode 100644
index 0000000..8bc1e02
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityJungleSkeleton.java
@@ -0,0 +1,81 @@
+package redd90.betternether.entity;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoField;
+import java.util.Random;
+
+import javax.annotation.Nullable;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.ILivingEntityData;
+import net.minecraft.entity.SpawnReason;
+import net.minecraft.entity.monster.SkeletonEntity;
+import net.minecraft.inventory.EquipmentSlotType;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.DifficultyInstance;
+import net.minecraft.world.IServerWorld;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+
+public class EntityJungleSkeleton extends SkeletonEntity {
+ public EntityJungleSkeleton(EntityType extends SkeletonEntity> entityType, World world) {
+ super(entityType, world);
+ }
+
+ @Override
+ public void livingTick() {
+ this.updateArmSwingProgress();
+ this.idle();
+ super.livingTick();
+ }
+
+ @Override
+ public ILivingEntityData onInitialSpawn(IServerWorld IServerWorld, DifficultyInstance difficulty, SpawnReason spawnReason, @Nullable ILivingEntityData entityData, @Nullable CompoundNBT entityTag) {
+ entityData = super.onInitialSpawn(IServerWorld, difficulty, spawnReason, entityData, entityTag);
+ super.setEquipmentBasedOnDifficulty(difficulty);
+
+ this.setItemStackToSlot(EquipmentSlotType.MAINHAND, getHandItem());
+ this.setItemStackToSlot(EquipmentSlotType.OFFHAND, getOffhandItem());
+
+ this.setEnchantmentBasedOnDifficulty(difficulty);
+ this.setCombatTask();
+ this.setCanPickUpLoot(this.rand.nextFloat() < 0.55F * difficulty.getClampedAdditionalDifficulty());
+ if (this.getItemStackFromSlot(EquipmentSlotType.HEAD).isEmpty()) {
+ LocalDate localDate = LocalDate.now();
+ int i = localDate.get(ChronoField.DAY_OF_MONTH);
+ int j = localDate.get(ChronoField.MONTH_OF_YEAR);
+ if (j == 10 && i == 31 && this.rand.nextFloat() < 0.25F) {
+ this.setItemStackToSlot(EquipmentSlotType.HEAD, new ItemStack(this.rand.nextFloat() < 0.1F ? Blocks.JACK_O_LANTERN : Blocks.CARVED_PUMPKIN));
+ this.inventoryArmorDropChances[EquipmentSlotType.HEAD.getIndex()] = 0.0F;
+ }
+ }
+
+ return entityData;
+ }
+
+ private ItemStack getHandItem() {
+ int n = this.rand.nextInt(3);
+ switch (n) {
+ case 0:
+ default:
+ return new ItemStack(this.rand.nextBoolean() ? Items.WOODEN_SWORD : Items.STONE_SWORD);
+ case 1:
+ return new ItemStack(Items.BOW);
+ case 2:
+ return new ItemStack(Items.AIR);
+ }
+ }
+
+ private ItemStack getOffhandItem() {
+ return this.rand.nextInt(8) == 0 ? new ItemStack(Items.SHIELD) : new ItemStack(Items.AIR);
+ }
+
+ public static boolean canSpawn(EntityType extends EntityJungleSkeleton> type, IWorld world, SpawnReason spawnReason, BlockPos pos, Random rand) {
+ return world.getDifficulty() != Difficulty.PEACEFUL;
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/EntityNaga.java b/src/main/java/redd90/betternether/entity/EntityNaga.java
new file mode 100644
index 0000000..419408e
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityNaga.java
@@ -0,0 +1,107 @@
+package redd90.betternether.entity;
+
+import java.util.Random;
+
+import net.minecraft.entity.CreatureAttribute;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.IRangedAttackMob;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.SpawnReason;
+import net.minecraft.entity.ai.attributes.AttributeModifierMap;
+import net.minecraft.entity.ai.attributes.Attributes;
+import net.minecraft.entity.ai.goal.LookAtGoal;
+import net.minecraft.entity.ai.goal.LookRandomlyGoal;
+import net.minecraft.entity.ai.goal.NearestAttackableTargetGoal;
+import net.minecraft.entity.ai.goal.RangedAttackGoal;
+import net.minecraft.entity.ai.goal.WaterAvoidingRandomWalkingGoal;
+import net.minecraft.entity.monster.IMob;
+import net.minecraft.entity.monster.MonsterEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.potion.EffectInstance;
+import net.minecraft.potion.Effects;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.EntityRegistry;
+import redd90.betternether.registry.SoundsRegistry;
+
+public class EntityNaga extends MonsterEntity implements IRangedAttackMob, IMob {
+ public EntityNaga(EntityType extends EntityNaga> type, World world) {
+ super(type, world);
+ this.experienceValue = 10;
+ }
+
+ @Override
+ protected void registerGoals() {
+ this.targetSelector.addGoal(1, new NearestAttackableTargetGoal(this, PlayerEntity.class, true));
+ this.goalSelector.addGoal(2, new RangedAttackGoal(this, 1.0D, 40, 20.0F));
+ this.goalSelector.addGoal(3, new LookAtGoal(this, PlayerEntity.class, 8.0F));
+ this.goalSelector.addGoal(4, new WaterAvoidingRandomWalkingGoal(this, 1.0D));
+ this.goalSelector.addGoal(5, new LookRandomlyGoal(this));
+ }
+
+ public static AttributeModifierMap getAttributeContainer() {
+ return MobEntity
+ .func_233666_p_()
+ .createMutableAttribute(Attributes.MAX_HEALTH, 10.0)
+ .createMutableAttribute(Attributes.FOLLOW_RANGE, 35.0)
+ .createMutableAttribute(Attributes.MOVEMENT_SPEED, 0.23)
+ .createMutableAttribute(Attributes.ATTACK_DAMAGE, 3.0)
+ .createMutableAttribute(Attributes.ARMOR, 2.0)
+ .create();
+ }
+
+ @Override
+ public void attackEntityWithRangedAttack(LivingEntity target, float f) {
+ EntityNagaProjectile projectile = EntityRegistry.NAGA_PROJECTILE.create(world);
+ projectile.setPositionAndRotation(getPosX(), getPosYEye(), getPosZ(), 0, 0);
+ projectile.setParams(this, target);
+ world.addEntity(projectile);
+ this.playSound(SoundsRegistry.MOB_NAGA_ATTACK, MHelper.randRange(3F, 5F, rand), MHelper.randRange(0.75F, 1.25F, rand));
+ }
+
+ @Override
+ public CreatureAttribute getCreatureAttribute() {
+ return CreatureAttribute.UNDEAD;
+ }
+
+ @Override
+ public boolean isPotionApplicable(EffectInstance effect) {
+ return effect.getPotion() == Effects.WITHER ? false : super.isPotionApplicable(effect);
+ }
+
+ @Override
+ public SoundEvent getAmbientSound() {
+ return SoundsRegistry.MOB_NAGA_IDLE;
+ }
+
+ @Override
+ protected SoundEvent getHurtSound(DamageSource source) {
+ return SoundEvents.ENTITY_SKELETON_HURT;
+ }
+
+ @Override
+ protected SoundEvent getDeathSound() {
+ return SoundEvents.ENTITY_SKELETON_DEATH;
+ }
+
+ @Override
+ protected boolean isDespawnPeaceful() {
+ return true;
+ }
+
+ @Override
+ public int getHorizontalFaceSpeed() {
+ return 1;
+ }
+
+ public static boolean canSpawn(EntityType extends EntityNaga> type, IWorld world, SpawnReason spawnReason, BlockPos pos, Random random) {
+ return world.getDifficulty() != Difficulty.PEACEFUL && world.getLight(pos) < 8;
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/EntityNagaProjectile.java b/src/main/java/redd90/betternether/entity/EntityNagaProjectile.java
new file mode 100644
index 0000000..a0ba60c
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityNagaProjectile.java
@@ -0,0 +1,142 @@
+package redd90.betternether.entity;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.FlyingEntity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.projectile.ProjectileHelper;
+import net.minecraft.nbt.CompoundNBT;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.potion.EffectInstance;
+import net.minecraft.potion.Effects;
+import net.minecraft.util.math.EntityRayTraceResult;
+import net.minecraft.util.math.RayTraceResult;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+
+public class EntityNagaProjectile extends FlyingEntity {
+ private static final int MAX_LIFE_TIME = 60; // 3 seconds * 20 ticks
+ private int lifeTime = 0;
+
+ public EntityNagaProjectile(EntityType extends EntityNagaProjectile> type, World world) {
+ super(type, world);
+ this.experienceValue = 0;
+ }
+
+ public void setParams(LivingEntity owner, Entity target) {
+ this.setPosition(getPosX(), getPosYEye() - this.getHeight(), getPosZ());
+ Vector3d dir = target.getPositionVec().add(0, target.getHeight() * 0.25, 0).subtract(getPositionVec()).normalize().scale(2);
+ this.setMotion(dir);
+ this.prevPosX = getPosX() - dir.x;
+ this.prevPosY = getPosY() - dir.y;
+ this.prevPosZ = getPosZ() - dir.z;
+ }
+
+ @Override
+ public boolean hasNoGravity() {
+ return true;
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public boolean isInRangeToRenderDist(double distance) {
+ return distance < 128;
+ }
+
+ @Override
+ public void tick() {
+ super.tick();
+ world.addParticle(ParticleTypes.LARGE_SMOKE,
+ getPosX() + rand.nextGaussian() * 0.2,
+ getPosY() + rand.nextGaussian() * 0.2,
+ getPosZ() + rand.nextGaussian() * 0.2,
+ 0, 0, 0);
+ world.addParticle(ParticleTypes.SMOKE,
+ getPosX() + rand.nextGaussian() * 0.2,
+ getPosY() + rand.nextGaussian() * 0.2,
+ getPosZ() + rand.nextGaussian() * 0.2,
+ 0, 0, 0);
+
+ RayTraceResult hitResult = ProjectileHelper.func_234618_a_(this, (entity) -> {
+ return entity.isAlive() && entity instanceof LivingEntity;
+ });
+ if (hitResult.getType() != RayTraceResult.Type.MISS) {
+ this.onCollision(hitResult);
+ }
+
+ lifeTime++;
+ if (lifeTime > MAX_LIFE_TIME)
+ effectKill();
+
+ if (isSame(this.prevPosX, this.getPosX()) && isSame(this.prevPosY, this.getPosY()) && isSame(this.prevPosZ, this.getPosZ()))
+ effectKill();
+ }
+
+ private boolean isSame(double a, double b) {
+ return Math.abs(a - b) < 0.1;
+ }
+
+ protected void onCollision(RayTraceResult hitResult) {
+ RayTraceResult.Type type = hitResult.getType();
+ if (type == RayTraceResult.Type.BLOCK) {
+ for (int i = 0; i < 10; i++) {
+ world.addParticle(ParticleTypes.LARGE_SMOKE,
+ getPosX() + rand.nextGaussian() * 0.5,
+ getPosY() + rand.nextGaussian() * 0.5,
+ getPosZ() + rand.nextGaussian() * 0.5,
+ rand.nextGaussian() * 0.2,
+ rand.nextGaussian() * 0.2,
+ rand.nextGaussian() * 0.2);
+ }
+ effectKill();
+ }
+ else if (type == RayTraceResult.Type.ENTITY) {
+ Entity entity = ((EntityRayTraceResult) hitResult).getEntity();
+ if (entity != this && entity instanceof LivingEntity && !(entity instanceof EntityNaga)) {
+ LivingEntity living = (LivingEntity) entity;
+ if (!(living.isPotionActive(Effects.WITHER))) {
+ living.addPotionEffect(new EffectInstance(Effects.WITHER, 40));
+ // living.damage(DamageSource.GENERIC, 0.5F);
+ }
+ effectKill();
+ }
+ }
+ }
+
+ private void effectKill() {
+ for (int i = 0; i < 10; i++) {
+ world.addParticle(ParticleTypes.ENTITY_EFFECT,
+ getPosX() + rand.nextGaussian() * 0.5,
+ getPosY() + rand.nextGaussian() * 0.5,
+ getPosZ() + rand.nextGaussian() * 0.5,
+ 0.1, 0.1, 0.1);
+ }
+ this.onKillCommand();
+ }
+
+ @Override
+ public boolean isPotionApplicable(EffectInstance effect) {
+ return false;
+ }
+
+ @Override
+ public boolean isSilent() {
+ return true;
+ }
+
+ @Override
+ public void writeAdditional(CompoundNBT tag) {
+ super.writeAdditional(tag);
+ tag.putInt("life", lifeTime);
+ }
+
+ @Override
+ public void readAdditional(CompoundNBT tag) {
+ super.readAdditional(tag);
+ if (tag.contains("life")) {
+ lifeTime = tag.getInt("life");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/entity/EntitySkull.java b/src/main/java/redd90/betternether/entity/EntitySkull.java
new file mode 100644
index 0000000..c5e1537
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntitySkull.java
@@ -0,0 +1,267 @@
+package redd90.betternether.entity;
+
+import java.util.List;
+import java.util.Random;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.entity.CreatureAttribute;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.MobEntity;
+import net.minecraft.entity.Pose;
+import net.minecraft.entity.SpawnReason;
+import net.minecraft.entity.ai.attributes.AttributeModifierMap;
+import net.minecraft.entity.ai.attributes.Attributes;
+import net.minecraft.entity.ai.controller.FlyingMovementController;
+import net.minecraft.entity.ai.controller.LookController;
+import net.minecraft.entity.monster.MonsterEntity;
+import net.minecraft.entity.passive.IFlyingAnimal;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.entity.player.ServerPlayerEntity;
+import net.minecraft.item.ShieldItem;
+import net.minecraft.particles.ParticleTypes;
+import net.minecraft.pathfinding.PathNodeType;
+import net.minecraft.util.DamageSource;
+import net.minecraft.util.Hand;
+import net.minecraft.util.SoundEvent;
+import net.minecraft.util.SoundEvents;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.vector.Vector3d;
+import net.minecraft.world.Difficulty;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraftforge.api.distmarker.Dist;
+import net.minecraftforge.api.distmarker.OnlyIn;
+import redd90.betternether.MHelper;
+import redd90.betternether.registry.SoundsRegistry;
+
+
+public class EntitySkull extends MonsterEntity implements IFlyingAnimal {
+ private static double particleX;
+ private static double particleY;
+ private static double particleZ;
+ private int attackTick;
+ private int dirTickTick;
+ private int collideTick;
+
+ public EntitySkull(EntityType extends EntitySkull> type, World world) {
+ super(type, world);
+ this.moveController = new FlyingMovementController(this, 20, true);
+ this.lookController = new SkullLookControl(this);
+ this.setPathPriority(PathNodeType.LAVA, -1.0F);
+ this.setPathPriority(PathNodeType.WATER, -1.0F);
+ this.setPathPriority(PathNodeType.DANGER_FIRE, 0.0F);
+ this.experienceValue = 1;
+ this.jumpMovementFactor = 0.5F;
+ }
+
+ public static AttributeModifierMap getAttributeContainer() {
+ return MobEntity
+ .func_233666_p_()
+ .createMutableAttribute(Attributes.MAX_HEALTH, 4.0)
+ .createMutableAttribute(Attributes.FOLLOW_RANGE, 20.0)
+ .createMutableAttribute(Attributes.MOVEMENT_SPEED, 0.5)
+ .createMutableAttribute(Attributes.FLYING_SPEED, 0.5)
+ .createMutableAttribute(Attributes.ATTACK_DAMAGE, 1.0)
+ .create();
+ }
+
+ class SkullLookControl extends LookController {
+ SkullLookControl(MobEntity entity) {
+ super(entity);
+ }
+
+ protected boolean shouldStayHorizontal() {
+ return false;
+ }
+ }
+
+ @Override
+ public void onCollideWithPlayer(PlayerEntity player) {
+ collideTick++;
+ if (collideTick > 3) {
+ collideTick = 0;
+
+ boolean shield = player.getActiveItemStack().getItem() instanceof ShieldItem && player.isHandActive();
+ if (shield) {
+ player.playSound(SoundEvents.ITEM_SHIELD_BLOCK, MHelper.randRange(0.8F, 1.2F, rand), MHelper.randRange(0.8F, 1.2F, rand));
+ this.setMotion(new Vector3d(0, 0, 0).subtract(getMotion()));
+ }
+ if (player instanceof ServerPlayerEntity) {
+ if (shield) {
+ player.getActiveItemStack().attemptDamageItem(1, rand, (ServerPlayerEntity) player);
+ if (player.getActiveItemStack().getDamage() > player.getActiveItemStack().getMaxDamage()) {
+ player.sendBreakAnimation(player.getActiveHand());
+ if (player.getActiveHand().equals(Hand.MAIN_HAND))
+ player.inventory.mainInventory.clear();
+ else if (player.getActiveHand().equals(Hand.OFF_HAND))
+ player.inventory.offHandInventory.clear();
+ player.resetActiveHand();
+ }
+ return;
+ }
+ player.attackEntityFrom(DamageSource.GENERIC, 1);
+ if (rand.nextInt(16) == 0)
+ player.setFire(3);
+ }
+ }
+ }
+
+ @Override
+ public void tick() {
+ super.tick();
+ if (rand.nextInt(3) == 0) {
+ updateParticlePos();
+ this.world.addParticle(ParticleTypes.SMOKE, particleX, particleY, particleZ, 0, 0, 0);
+ }
+ if (rand.nextInt(3) == 0) {
+ updateParticlePos();
+ this.world.addParticle(ParticleTypes.DRIPPING_LAVA, particleX, particleY, particleZ, 0, 0, 0);
+ }
+ if (rand.nextInt(3) == 0) {
+ updateParticlePos();
+ this.world.addParticle(ParticleTypes.FLAME, particleX, particleY, particleZ, 0, 0, 0);
+ }
+
+ if (attackTick > 40 && this.isAlive()) {
+ PlayerEntity target = EntitySkull.this.world.getClosestPlayer(getPosX(), getPosY(), getPosZ(), 20, true);
+ if (target != null && this.canEntityBeSeen(target)) {
+ attackTick = 0;
+ Vector3d velocity = target
+ .getPositionVec()
+ .add(0, target.getHeight() * 0.5F, 0)
+ .subtract(EntitySkull.this.getPositionVec())
+ .normalize()
+ .scale(EntitySkull.this.jumpMovementFactor);
+ setMotion(velocity);
+ this.faceEntity(target, 360, 360);
+ this.playSound(SoundsRegistry.MOB_SKULL_FLIGHT, MHelper.randRange(0.15F, 0.3F, rand), MHelper.randRange(0.9F, 1.5F, rand));
+ }
+ else if (dirTickTick < 0) {
+ dirTickTick = MHelper.randRange(20, 60, rand);
+ moveRandomDir();
+ }
+ }
+ else {
+ if (dirTickTick < 0) {
+ dirTickTick = MHelper.randRange(20, 60, rand);
+ moveRandomDir();
+ }
+ }
+ attackTick++;
+ dirTickTick--;
+ }
+
+ @Override
+ protected SoundEvent getAmbientSound() {
+ return SoundEvents.ENTITY_SKELETON_AMBIENT;
+ }
+
+ @Override
+ protected SoundEvent getHurtSound(DamageSource source) {
+ return SoundEvents.ENTITY_SKELETON_HURT;
+ }
+
+ @Override
+ protected SoundEvent getDeathSound() {
+ return SoundEvents.ENTITY_SKELETON_DEATH;
+ }
+
+ private void moveRandomDir() {
+ double dx = rand.nextDouble() - 0.5;
+ double dy = rand.nextDouble() - 0.5;
+ double dz = rand.nextDouble() - 0.5;
+ double l = dx * dx + dy * dy + dz * dz;
+ if (l == 0)
+ l = 1;
+ else
+ l = (float) Math.sqrt(l);
+ l /= this.jumpMovementFactor;
+ dx /= l;
+ dy /= l;
+ dz /= l;
+ setVelocity(dx, dy, dz);
+ lookAt(this.getPositionVec().add(this.getMotion()));
+ this.playSound(SoundsRegistry.MOB_SKULL_FLIGHT, MHelper.randRange(0.15F, 0.3F, rand), MHelper.randRange(0.75F, 1.25F, rand));
+ }
+
+ private void lookAt(Vector3d target) {
+ double d = target.getX() - this.getPosX();
+ double e = target.getZ() - this.getPosZ();
+ double g = target.getY() - this.getPosY();
+
+ double h = MathHelper.sqrt(d * d + e * e);
+ float i = (float) (MathHelper.atan2(e, d) * 57.2957763671875D) - 90.0F;
+ float j = (float) (-(MathHelper.atan2(g, h) * 57.2957763671875D));
+
+ this.rotationPitch = j;
+ this.rotationYaw = i;
+ }
+
+ private void updateParticlePos() {
+ particleX = rand.nextDouble() - 0.5;
+ particleY = rand.nextDouble() - 0.5;
+ particleZ = rand.nextDouble() - 0.5;
+ double l = particleX * particleX + particleY * particleY + particleZ * particleZ;
+ if (l == 0)
+ l = 1;
+ else
+ l = (float) Math.sqrt(l);
+ particleX = particleX * 0.5 / l + getPosX();
+ particleY = particleY * 0.5 / l + getPosY();
+ particleZ = particleZ * 0.5 / l + getPosZ();
+ }
+
+ @Override
+ @OnlyIn(Dist.CLIENT)
+ public float getEyeHeight(Pose pose) {
+ return this.getSize(pose).height * 0.5F;
+ }
+
+ @Override
+ protected boolean makeFlySound() {
+ return true;
+ }
+
+ @Override
+ public CreatureAttribute getCreatureAttribute() {
+ return CreatureAttribute.UNDEAD;
+ }
+
+ @Override
+ public boolean onLivingFall(float fallDistance, float damageMultiplier) {
+ return false;
+ }
+
+ @Override
+ protected void updateFallState(double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition) {}
+
+ @Override
+ public boolean canTriggerWalking() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNoGravity() {
+ return true;
+ }
+
+ @Override
+ public boolean canBePushed() {
+ return false;
+ }
+
+ public static boolean canSpawn(EntityType extends EntitySkull> type, IWorld world, SpawnReason spawnReason, BlockPos pos, Random rand) {
+ if (world.getDifficulty() == Difficulty.PEACEFUL || world.getLight(pos) > 7)
+ return false;
+
+ if (pos.getY() >= world.getDimensionType().getLogicalHeight()) return false;
+
+ AxisAlignedBB box = new AxisAlignedBB(pos).expand(256, 256, 256);
+ List list = world.getEntitiesWithinAABB(EntitySkull.class, box, (entity) -> {
+ return true;
+ });
+ return list.size() < 4;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/redd90/betternether/entity/EntityTypeBuilder.java b/src/main/java/redd90/betternether/entity/EntityTypeBuilder.java
new file mode 100644
index 0000000..d44138c
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/EntityTypeBuilder.java
@@ -0,0 +1,63 @@
+package redd90.betternether.entity;
+
+import java.util.Objects;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.google.common.collect.ImmutableSet;
+
+import net.minecraft.block.Block;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityClassification;
+import net.minecraft.entity.EntitySize;
+import net.minecraft.entity.EntityType;
+
+public class EntityTypeBuilder {
+
+ private static final Logger LOGGER = LogManager.getLogger();
+ private EntityClassification classification;
+ private EntityType.IFactory factory;
+ private boolean saveable = true;
+ private boolean summonable = true;
+ private int trackRange = 5;
+ private int trackedUpdateRate = 3;
+ private Boolean forceTrackedVelocityUpdates;
+ private boolean fireImmune = false;
+ private boolean spawnableFarFromPlayer;
+ private EntitySize size = EntitySize.flexible(-1.0f, -1.0f);
+ private ImmutableSet specificSpawnBlocks = ImmutableSet.of();
+
+ protected EntityTypeBuilder(EntityClassification classification, EntityType.IFactory factory) {
+ this.classification = classification;
+ this.factory = factory;
+ this.spawnableFarFromPlayer = classification == EntityClassification.CREATURE || classification == EntityClassification.MISC;
+ }
+
+ public static EntityTypeBuilder create(EntityClassification classification, EntityType.IFactory factory) {
+ return new EntityTypeBuilder<>(classification, factory);
+ }
+
+ public EntityTypeBuilder size(EntitySize size) {
+ Objects.requireNonNull(size, "Cannot set null size");
+ this.size = size;
+ return this;
+ }
+
+ public EntityTypeBuilder fireImmune() {
+ this.fireImmune = true;
+ return this;
+ }
+
+ public EntityTypeBuilder disableSummon() {
+ this.summonable = false;
+ return this;
+ }
+
+ public EntityType build() {
+
+ EntityType type = new EntityType(this.factory, this.classification, this.saveable, this.summonable, this.fireImmune, this.spawnableFarFromPlayer, this.specificSpawnBlocks, size, trackRange, trackedUpdateRate);
+
+ return type;
+ }
+}
diff --git a/src/main/java/redd90/betternether/entity/model/ModelEmpty.java b/src/main/java/redd90/betternether/entity/model/ModelEmpty.java
new file mode 100644
index 0000000..249d689
--- /dev/null
+++ b/src/main/java/redd90/betternether/entity/model/ModelEmpty.java
@@ -0,0 +1,24 @@
+package redd90.betternether.entity.model;
+
+import com.google.common.collect.ImmutableList;
+
+import net.minecraft.client.renderer.entity.model.AgeableModel;
+import net.minecraft.client.renderer.model.ModelRenderer;
+import redd90.betternether.entity.EntityChair;
+
+public class ModelEmpty extends AgeableModel {
+ @Override
+ protected Iterable getHeadParts() {
+ return ImmutableList.of();
+ }
+
+ @Override
+ protected Iterable