diff --git a/.gitignore b/.gitignore index a1c2a23..4dc7817 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ .mtj.tmp/ # Package Files # -*.jar +#*.jar *.war *.nar *.ear @@ -21,3 +21,8 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +build/ +out/ +run/ +*.iml \ No newline at end of file diff --git a/TerraForgedMod/README.md b/TerraForgedMod/README.md new file mode 100644 index 0000000..073aa26 --- /dev/null +++ b/TerraForgedMod/README.md @@ -0,0 +1,7 @@ +# TerraForged + +### Commands +- `/terra query` - print the Terrain and Biome types at your location +- `/terra find ` - find the nearest instance of the given biome type +- `/terra find ` - find the nearest instance of the given terrain type +- `/terra find ` - find the nearest instance of the given terrain and biome type \ No newline at end of file diff --git a/TerraForgedMod/build.gradle b/TerraForgedMod/build.gradle new file mode 100644 index 0000000..359d786 --- /dev/null +++ b/TerraForgedMod/build.gradle @@ -0,0 +1,107 @@ +buildscript { + repositories { + jcenter() + mavenCentral() + maven { url "https://files.minecraftforge.net/maven" } + } + dependencies { + classpath group: "net.minecraftforge.gradle", name: "ForgeGradle", version: "3.+", changing: true + } +} + +apply plugin: "net.minecraftforge.gradle" +apply plugin: "maven-publish" +apply plugin: "eclipse" + +version = "${mc_version}-${version}${getBuildNumber()}" +archivesBaseName = "TerraForged" + +repositories { + jcenter() + mavenCentral() +} + +dependencies { + minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}" + compile project(":Noise2D") + compile (project(":TerraForgedCore")) { + transitive false + } + compile (project(":FeatureManager")) { + transitive false + } + compile (project(":TerraForgedAPI")) { + transitive false + } +} + +minecraft { + mappings channel: mcp_channel, version: mcp_version + runs { + client { + workingDirectory project.file("run/client") + property "forge.logging.markers", "SCAN,REGISTRIES,REGISTRYDUMP" + property "forge.logging.console.level", "debug" + jvmArgs "-Xmx8G", "-Xms6G", "-Ddev" + mods { + terraforged { + source sourceSets.main + } + } + } + server { + workingDirectory project.file("run/server") + property "forge.logging.markers", "SCAN,REGISTRIES,REGISTRYDUMP" + property "forge.logging.console.level", "debug" + jvmArgs "-Xmx8G", "-Xms6G", "-Ddev" + mods { + terraforged { + source sourceSets.main + } + } + } + } +} + +task collectClasses(type: Copy) { + configurations.collectMany { it.allDependencies }.findAll{ it instanceof ProjectDependency }.each { + ProjectDependency project = (ProjectDependency) it + from("$project.dependencyProject.buildDir/classes/java/main") + } + into("build/classes/java/main") +} + +task collectResources(type: Copy) { + configurations.collectMany { it.allDependencies }.findAll{ it instanceof ProjectDependency }.each { + ProjectDependency project = (ProjectDependency) it + from("$project.dependencyProject.buildDir/resources/main") + } + into("build/resources/main") +} + +processResources { + dependsOn(collectResources) + + filesMatching("**/mods.toml") { + expand( + "version": version, + "mc_version": mc_version + ) + } +} + +classes { + dependsOn(collectClasses) +} + +publish { + dependsOn("reobfJar") +} + +static def getBuildNumber() { + def buildNumber = System.getenv("BUILD_NUMBER") + if (buildNumber == null) { + return "" + } + return "-${buildNumber}" +} \ No newline at end of file diff --git a/TerraForgedMod/gradlew b/TerraForgedMod/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/TerraForgedMod/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/TerraForgedMod/gradlew.bat b/TerraForgedMod/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/TerraForgedMod/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/TerraForgedMod/psd/biomes.psd b/TerraForgedMod/psd/biomes.psd new file mode 100644 index 0000000..eedc297 Binary files /dev/null and b/TerraForgedMod/psd/biomes.psd differ diff --git a/TerraForgedMod/psd/icon.png b/TerraForgedMod/psd/icon.png new file mode 100644 index 0000000..ecedcf8 Binary files /dev/null and b/TerraForgedMod/psd/icon.png differ diff --git a/TerraForgedMod/psd/terraforged.png b/TerraForgedMod/psd/terraforged.png new file mode 100644 index 0000000..0d649c9 Binary files /dev/null and b/TerraForgedMod/psd/terraforged.png differ diff --git a/TerraForgedMod/psd/terraforged.psd b/TerraForgedMod/psd/terraforged.psd new file mode 100644 index 0000000..8034e6d Binary files /dev/null and b/TerraForgedMod/psd/terraforged.psd differ diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/Log.java b/TerraForgedMod/src/main/java/com/terraforged/mod/Log.java new file mode 100644 index 0000000..dd5af8d --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/Log.java @@ -0,0 +1,46 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Log { + + private static final Logger logger = LogManager.getLogger("TerraForged"); + + public static void info(String message, Object... args) { + logger.info(message, args); + } + + public static void debug(String message, Object... args) { + logger.debug(message, args); + } + + public static void err(String message, Object... args) { + logger.error(message, args); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java b/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java new file mode 100644 index 0000000..eb81041 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java @@ -0,0 +1,81 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod; + +import com.terraforged.api.material.MaterialTags; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.feature.FeatureManager; +import com.terraforged.mod.data.DataGen; +import com.terraforged.mod.feature.tree.SaplingManager; +import com.terraforged.mod.util.Environment; +import net.minecraft.world.gen.feature.Feature; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; +import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; + +/** + * Author + */ +@Mod("terraforged") +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) +public class TerraForgedMod { + + @SubscribeEvent + public static void setup(FMLCommonSetupEvent event) { + Log.info("Common setup"); + MinecraftForge.EVENT_BUS.addListener(TerraForgedMod::onShutdown); + MaterialTags.init(); + TerraWorld.init(); + SaplingManager.init(); + } + + @SubscribeEvent + public static void complete(FMLLoadCompleteEvent event) { + if (Environment.isDev()) { + DataGen.dumpData(); + } + } + + @SubscribeEvent + public static void server(FMLDedicatedServerSetupEvent event) { + Log.info("Setting dedicated server"); + TerraWorld.setDedicatedServer(); + } + + @SubscribeEvent + public static void registerFeatures(RegistryEvent.Register> event) { + FeatureManager.registerTemplates(event); + } + + private static void onShutdown(FMLServerStoppingEvent event) { + ThreadPool.shutdownCurrent(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/TerraWorld.java b/TerraForgedMod/src/main/java/com/terraforged/mod/TerraWorld.java new file mode 100644 index 0000000..0394335 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/TerraWorld.java @@ -0,0 +1,157 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod; + +import com.google.gson.Gson; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.ChunkGeneratorFactory; +import com.terraforged.mod.chunk.TerraChunkGenerator; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.chunk.TerraGenSettings; +import com.terraforged.mod.chunk.test.TestChunkGenerator; +import com.terraforged.mod.gui.SettingsScreen; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.CreateWorldScreen; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; +import net.minecraft.world.WorldType; +import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.OverworldGenSettings; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; +import java.util.HashSet; +import java.util.Set; + +public class TerraWorld extends WorldType { + + public static final String SETTINGS_FILE_NAME = "terraforged-generator.json"; + + private static final Set types = new HashSet<>(); + public static final TerraWorld TERRA = new TerraWorld("terraforged", TerraChunkGenerator::new); + public static final TerraWorld TEST = new TerraWorld("terratest", TestChunkGenerator::new); + + private static boolean dedicated = false; + + private final ChunkGeneratorFactory factory; + + public TerraWorld(String name, ChunkGeneratorFactory factory) { + super(name); + this.factory = factory; + setCustomOptions(true); + TerraWorld.types.add(this); + } + + @Override + public double getHorizon(World world) { + return 0; + } + + @Override + public float getCloudHeight() { + return 260.0F; + } + + @Override + public ChunkGenerator createChunkGenerator(World world) { + if (world.getDimension().getType() != DimensionType.OVERWORLD) { + return world.getDimension().createChunkGenerator(); + } + + Log.debug("Creating {} generator", world.getDimension().getType()); + + TerraSettings settings = getSettings(world); + settings.generator.seed = world.getSeed(); + + Terrains terrains = Terrains.create(settings); + + OverworldGenSettings genSettings = new TerraGenSettings(settings.structures); + + OverworldBiomeProviderSettings biomeSettings = new OverworldBiomeProviderSettings(world.getWorldInfo()); + biomeSettings.setGeneratorSettings(genSettings); + world.getWorldInfo().setGeneratorOptions(NBTHelper.serializeCompact(settings)); + + TerraContext context = new TerraContext(world, terrains, settings); + BiomeProvider biomeProvider = new BiomeProvider(context); + + return getGeneratorFactory().create(context, biomeProvider, genSettings); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void onCustomizeButton(Minecraft mc, CreateWorldScreen gui) { + mc.displayGuiScreen(new SettingsScreen(gui)); + } + + public ChunkGeneratorFactory getGeneratorFactory() { + return factory; + } + + private static TerraSettings getSettings(IWorld world) { + if (dedicated) { + try (Reader reader = new BufferedReader(new FileReader(new File("config", SETTINGS_FILE_NAME)))) { + Log.info("Loading generator settings from json"); + return new Gson().fromJson(reader, TerraSettings.class); + } catch (Throwable ignored) { + return getSettings(world.getWorldInfo().getGeneratorOptions()); + } + } + return getSettings(world.getWorldInfo().getGeneratorOptions()); + } + + private static TerraSettings getSettings(CompoundNBT root) { + TerraSettings settings = new TerraSettings(); + if (!root.isEmpty()) { + NBTHelper.deserialize(root, settings); + } + return settings; + } + + public static void init() { + Log.info("Registered world type(s)"); + } + + public static void setDedicatedServer() { + dedicated = true; + } + + public static boolean isTerraWorld(IWorld world) { + if (world instanceof World) { + return types.contains(((World) world).getWorldType()); + } + return false; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ColdSteppe.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ColdSteppe.java new file mode 100644 index 0000000..a164a0c --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ColdSteppe.java @@ -0,0 +1,93 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class ColdSteppe extends BiomeVariant { + + public ColdSteppe() { + super((new Biome.Builder()).surfaceBuilder(SurfaceBuilder.GIANT_TREE_TAIGA, SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(RainType.SNOW).category(Biome.Category.TAIGA).depth(0.2F).scale(0.25F).temperature(0.2F).downfall(0.1F).waterColor(4159204).waterFogColor(329011).parent((String) null)); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); +// DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addMonsterRooms(this); + DefaultBiomeFeatures.addTaigaLargeFerns(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addSedimentDisks(this); +// DefaultBiomeFeatures.addTaigaConifers(this); +// DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addVeryDenseGrass(this); +// DefaultBiomeFeatures.addMushrooms(this); +// DefaultBiomeFeatures.addReedsAndPumpkins(this); +// DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addBerryBushes(this); + DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + + setRegistryName("terraforged", "cold_steppe"); + } + + @Override + public boolean doesSnowGenerate(IWorldReader worldIn, BlockPos pos) { + return false; + } + + @Override + public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos pos) { + return false; + } + + @Override + public Biome getBase() { + return Biomes.TAIGA; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ModBiomes.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ModBiomes.java new file mode 100644 index 0000000..70bcc26 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ModBiomes.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +import java.util.ArrayList; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) +public class ModBiomes { + + private static final ArrayList biomes = new ArrayList<>(); + + public static final Biome COLD_STEPPE = register(new ColdSteppe()); + public static final Biome SAVANNA_SCRUB = register(new SavannaScrub()); + public static final Biome SHATTERED_SAVANNA_SCRUB = register(new ShatteredSavannaScrub()); + public static final Biome SNOWY_TAIGA_SCRUB = register(new SnowyTaigaScrub()); + public static final Biome STEPPE = register(new Steppe()); + public static final Biome TAIGA_SCRUB = register(new TaigaScrub()); + public static final Biome WARM_BEACH = register(new WarmBeach()); + + private static Biome register(BiomeVariant biome) { + biomes.add(biome); + return biome; + } + + @SubscribeEvent + public static void register(RegistryEvent.Register event) { + biomes.forEach(event.getRegistry()::register); + biomes.clear(); + biomes.trimToSize(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/SavannaScrub.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/SavannaScrub.java new file mode 100644 index 0000000..854d14d --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/SavannaScrub.java @@ -0,0 +1,111 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.block.BlockState; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.surfacebuilders.DefaultSurfaceBuilder; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilderConfig; + +import java.util.Random; + +public class SavannaScrub extends BiomeVariant { + + public SavannaScrub() { + super((new Biome.Builder()).surfaceBuilder(new Builder(), SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(Biome.RainType.NONE).category(Biome.Category.SAVANNA).depth(0.125F).scale(0.05F).temperature(1.2F).downfall(0.0F).waterColor(4159204).waterFogColor(329011).parent((String) null)); + this.setRegistryName("terraforged", "savanna_scrub"); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); +// DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addMonsterRooms(this); + DefaultBiomeFeatures.addTallGrass(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addSedimentDisks(this); +// DefaultBiomeFeatures.addSavannaTrees(this); + DefaultBiomeFeatures.addExtraDefaultFlowers(this); + + // func_222339_L - add grasses - add this a few times since there are no trees + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addVeryDenseGrass(this); + + DefaultBiomeFeatures.addMushrooms(this); + DefaultBiomeFeatures.addReedsAndPumpkins(this); +// DefaultBiomeFeatures.addSprings(this); +// DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.HORSE, 1, 2, 6)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.DONKEY, 1, 1, 1)); + this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome getBase() { + return Biomes.SAVANNA; + } + + private static class Builder extends DefaultSurfaceBuilder { + + private Builder() { + super(SurfaceBuilderConfig::deserialize); + } + + @Override + public void buildSurface(Random random, IChunk chunkIn, Biome biomeIn, int x, int z, int startHeight, double noise, BlockState defaultBlock, BlockState defaultFluid, int seaLevel, long seed, SurfaceBuilderConfig config) { + super.buildSurface(random, chunkIn, biomeIn, x, z, startHeight, noise, defaultBlock, defaultFluid, seaLevel, seed, config); + BlockPos.Mutable pos = new BlockPos.Mutable(); + if (random.nextInt(5) > 0) { + int dx = x & 15; + int dz = z & 15; + int y = chunkIn.getTopBlockY(Heightmap.Type.MOTION_BLOCKING, dx, dz); + if (y > seaLevel) { + pos.setPos(dx, y, dz); +// chunkIn.setBlockState(pos, Blocks.SAND.getDefaultState(), false); + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ShatteredSavannaScrub.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ShatteredSavannaScrub.java new file mode 100644 index 0000000..d39ca20 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/ShatteredSavannaScrub.java @@ -0,0 +1,114 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.block.BlockState; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.surfacebuilders.DefaultSurfaceBuilder; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilderConfig; + +import java.util.Random; + +public class ShatteredSavannaScrub extends BiomeVariant { + public ShatteredSavannaScrub() { + super((new Biome.Builder()).surfaceBuilder(new Builder(), SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(Biome.RainType.NONE).category(Biome.Category.SAVANNA).depth(0.3625F).scale(1.225F).temperature(1.1F).downfall(0.0F).waterColor(4159204).waterFogColor(329011).parent("terraforged:savanna_scrub")); + this.setRegistryName("terraforged", "shattered_savanna_scrub"); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); +// DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addMonsterRooms(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addSedimentDisks(this); +// DefaultBiomeFeatures.addShatteredSavannaTrees(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + + // func_222314_K - addGrasses - add this a few times since there are no trees + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addVeryDenseGrass(this); + + DefaultBiomeFeatures.addMushrooms(this); + DefaultBiomeFeatures.addReedsAndPumpkins(this); +// DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.HORSE, 1, 2, 6)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.DONKEY, 1, 1, 1)); + this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public boolean isMutation() { + return true; + } + + @Override + public Biome getBase() { + return Biomes.SHATTERED_SAVANNA; + } + + private static class Builder extends DefaultSurfaceBuilder { + + private Builder() { + super(SurfaceBuilderConfig::deserialize); + } + + @Override + public void buildSurface(Random random, IChunk chunkIn, Biome biomeIn, int x, int z, int startHeight, double noise, BlockState defaultBlock, BlockState defaultFluid, int seaLevel, long seed, SurfaceBuilderConfig config) { + SurfaceBuilder.SHATTERED_SAVANNA.buildSurface(random, chunkIn, biomeIn, x, z, startHeight, noise, defaultBlock, defaultFluid, seaLevel, seed, config); + BlockPos.Mutable pos = new BlockPos.Mutable(); + if (random.nextInt(5) > 0) { + int dx = x & 15; + int dz = z & 15; + int y = chunkIn.getTopBlockY(Heightmap.Type.MOTION_BLOCKING, dx, dz); + if (y > seaLevel) { + pos.setPos(dx, y, dz); +// chunkIn.setBlockState(pos, Blocks.SAND.getDefaultState(), false); + } + } + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/SnowyTaigaScrub.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/SnowyTaigaScrub.java new file mode 100644 index 0000000..7f23b7a --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/SnowyTaigaScrub.java @@ -0,0 +1,79 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class SnowyTaigaScrub extends BiomeVariant { + public SnowyTaigaScrub() { + super((new Builder()).surfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(RainType.SNOW).category(Category.TAIGA).depth(0.2F).scale(0.2F).temperature(-0.5F).downfall(0.4F).waterColor(4020182).waterFogColor(329011).parent((String) null)); + this.setRegistryName("terraforged", "snowy_taiga_scrub"); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); +// DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addMonsterRooms(this); + DefaultBiomeFeatures.addTaigaLargeFerns(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addSedimentDisks(this); +// DefaultBiomeFeatures.addTaigaConifers(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addTaigaGrassAndMushrooms(this); + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addMushrooms(this); + DefaultBiomeFeatures.addReedsAndPumpkins(this); +// DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addSparseBerryBushes(this); + DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityClassification.AMBIENT, new SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome getBase() { + return Biomes.SNOWY_TAIGA; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/Steppe.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/Steppe.java new file mode 100644 index 0000000..a6bbc55 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/Steppe.java @@ -0,0 +1,93 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class Steppe extends BiomeVariant { + + protected Steppe() { + super((new Biome.Builder()).surfaceBuilder(SurfaceBuilder.GIANT_TREE_TAIGA, SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(RainType.SNOW).category(Category.SAVANNA).depth(0.2F).scale(0.2F).temperature(0.7F).downfall(0.1F).waterColor(4159204).waterFogColor(329011).parent((String) null)); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); +// DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addMonsterRooms(this); +// DefaultBiomeFeatures.addTaigaRocks(this); +// DefaultBiomeFeatures.addTaigaLargeFerns(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addSedimentDisks(this); + // extra grasses as no trees/ferns + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addVeryDenseGrass(this); +// DefaultBiomeFeatures.func_222285_H(this); +// DefaultBiomeFeatures.addDefaultFlowers(this); +// DefaultBiomeFeatures.addMushrooms(this); +// DefaultBiomeFeatures.addReedsAndPumpkins(this); +// DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 25, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + + setRegistryName("terraforged", "steppe"); + } + + @Override + public boolean doesSnowGenerate(IWorldReader worldIn, BlockPos pos) { + return false; + } + + @Override + public boolean doesWaterFreeze(IWorldReader worldIn, BlockPos pos) { + return false; + } + + @Override + public Biome getBase() { + return Biomes.SAVANNA; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/TaigaScrub.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/TaigaScrub.java new file mode 100644 index 0000000..b735217 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/TaigaScrub.java @@ -0,0 +1,83 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class TaigaScrub extends BiomeVariant { + public TaigaScrub() { + super((new Builder()).surfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.GRASS_DIRT_GRAVEL_CONFIG).precipitation(RainType.RAIN).category(Category.TAIGA).depth(0.2F).scale(0.2F).temperature(0.25F).downfall(0.8F).waterColor(4159204).waterFogColor(329011).parent((String) null)); + this.setRegistryName("terraforged", "taiga_scrub"); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); +// DefaultBiomeFeatures.addLakes(this); + DefaultBiomeFeatures.addMonsterRooms(this); + DefaultBiomeFeatures.addTaigaLargeFerns(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addSedimentDisks(this); +// DefaultBiomeFeatures.addTaigaConifers(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addVeryDenseGrass(this); + + // extra grass since there are no trees + DefaultBiomeFeatures.addGrass(this); + DefaultBiomeFeatures.addGrass(this); + + DefaultBiomeFeatures.addReedsAndPumpkins(this); +// DefaultBiomeFeatures.addSprings(this); + DefaultBiomeFeatures.addBerryBushes(this); + DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.SHEEP, 12, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.PIG, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.CHICKEN, 10, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.COW, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.WOLF, 8, 4, 4)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.RABBIT, 4, 2, 3)); + this.addSpawn(EntityClassification.CREATURE, new SpawnListEntry(EntityType.FOX, 8, 2, 4)); + this.addSpawn(EntityClassification.AMBIENT, new SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + } + + @Override + public Biome getBase() { + return Biomes.TAIGA; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/WarmBeach.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/WarmBeach.java new file mode 100644 index 0000000..3aa0ebb --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/WarmBeach.java @@ -0,0 +1,78 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome; + +import com.terraforged.api.biome.BiomeVariant; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.biome.DefaultBiomeFeatures; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.structure.BuriedTreasureConfig; +import net.minecraft.world.gen.feature.structure.MineshaftConfig; +import net.minecraft.world.gen.feature.structure.MineshaftStructure; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class WarmBeach extends BiomeVariant { + + public WarmBeach() { + super((new Biome.Builder()).surfaceBuilder(SurfaceBuilder.DEFAULT, SurfaceBuilder.SAND_CONFIG).precipitation(Biome.RainType.RAIN).category(Category.BEACH).depth(-0.5F).scale(0.1F).temperature(1.5F).downfall(0.5F).waterColor(4445678).waterFogColor(270131).parent((String)null)); + this.addStructure(Feature.MINESHAFT.func_225566_b_(new MineshaftConfig(0.004D, MineshaftStructure.Type.NORMAL))); + this.addStructure(Feature.BURIED_TREASURE.func_225566_b_(new BuriedTreasureConfig(0.01F))); + DefaultBiomeFeatures.addCarvers(this); + DefaultBiomeFeatures.addStructures(this); + DefaultBiomeFeatures.addMonsterRooms(this); + DefaultBiomeFeatures.addStoneVariants(this); + DefaultBiomeFeatures.addOres(this); + DefaultBiomeFeatures.addDefaultFlowers(this); + DefaultBiomeFeatures.addSparseGrass(this); + DefaultBiomeFeatures.addMushrooms(this); + DefaultBiomeFeatures.addReedsAndPumpkins(this); + DefaultBiomeFeatures.addFreezeTopLayer(this); + this.addSpawn(EntityClassification.CREATURE, new Biome.SpawnListEntry(EntityType.TURTLE, 5, 2, 5)); + this.addSpawn(EntityClassification.AMBIENT, new Biome.SpawnListEntry(EntityType.BAT, 10, 8, 8)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SPIDER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE, 95, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_VILLAGER, 5, 1, 1)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SKELETON, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.CREEPER, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.SLIME, 100, 4, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 1, 4)); + this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.WITCH, 5, 1, 1)); + setRegistryName("terraforged", "warm_beach"); + } + + @Override + public Biome.TempCategory getTempCategory() { + return TempCategory.WARM; + } + + @Override + public Biome getBase() { + return Biomes.WARM_OCEAN; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/AbstractBiomeMap.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/AbstractBiomeMap.java new file mode 100644 index 0000000..3ebd34a --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/AbstractBiomeMap.java @@ -0,0 +1,198 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.ModBiomes; +import com.terraforged.mod.biome.provider.BiomeHelper; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public abstract class AbstractBiomeMap implements BiomeMap { + + private final Biome[][] beach; + private final Biome[][] river; + private final Biome[][] ocean; + private final Biome[][] deepOcean; + + protected AbstractBiomeMap(BiomeMapBuilder builder) { + river = builder.rivers(); + beach = builder.beaches(); + ocean = builder.oceans(); + deepOcean = builder.deepOceans(); + } + + @Override + public Biome getBeach(float temperature, float moisture, float shape) { + return get(beach, getCategory(temperature), shape, defaultBeach(temperature)); + } + + @Override + public Biome getRiver(float temperature, float moisture, float shape) { + return get(river, getCategory(temperature), shape, defaultRiver(temperature)); + } + + @Override + public Biome getOcean(float temperature, float moisture, float shape) { + return get(ocean, getCategory(temperature), shape, defaultOcean(temperature)); + } + + @Override + public Biome getDeepOcean(float temperature, float moisture, float shape) { + return get(deepOcean, getCategory(temperature), shape, defaultDeepOcean(temperature)); + } + + @Override + public Set getOceanBiomes(Biome.TempCategory temp) { + return Sets.newHashSet(ocean[temp.ordinal() - 1]); + } + + @Override + public Set getDeepOceanBiomes(Biome.TempCategory temp) { + return Sets.newHashSet(deepOcean[temp.ordinal() - 1]); + } + + @Override + public Set getRivers(Biome.TempCategory temp) { + return Sets.newHashSet(river[temp.ordinal() - 1]); + } + + @Override + public JsonObject toJson() { + JsonObject root = new JsonObject(); + root.add("rivers", collect(river)); + root.add("beaches", collect(river)); + root.add("oceans", collect(ocean)); + root.add("deepOceans", collect(deepOcean)); + return root; + } + + private JsonObject collect(Biome[][] biomes) { + JsonObject root = new JsonObject(); + for (Biome.TempCategory temp : Biome.TempCategory.values()) { + if (temp == Biome.TempCategory.OCEAN) { + continue; + } + JsonArray array = new JsonArray(); + Biome[] group = biomes[temp.ordinal() - 1]; + if (group != null) { + Set set = new HashSet<>(); + Collections.addAll(set, group); + set.stream().map(BiomeHelper::getId).sorted().forEach(array::add); + } + root.add(temp.name(), array); + } + return root; + } + + + protected Biome.TempCategory getCategory(float value) { + if (value < 0.25) { + return Biome.TempCategory.COLD; + } + if (value > 0.75) { + return Biome.TempCategory.WARM; + } + return Biome.TempCategory.MEDIUM; + } + + protected Biome defaultBeach(float temperature) { + if (temperature < 0.25) { + return Biomes.SNOWY_BEACH; + } + if (temperature > 0.75) { + return ModBiomes.WARM_BEACH; + } + return Biomes.BEACH; + } + + protected Biome defaultRiver(float temperature) { + if (temperature < 0.15) { + return Biomes.FROZEN_RIVER; + } + return Biomes.RIVER; + } + + protected Biome defaultOcean(float temperature) { + if (temperature < 0.3) { + return Biomes.FROZEN_OCEAN; + } + if (temperature > 0.7) { + return Biomes.WARM_OCEAN; + } + return Biomes.OCEAN; + } + + protected Biome defaultDeepOcean(float temperature) { + if (temperature < 0.3) { + return Biomes.DEEP_FROZEN_OCEAN; + } + if (temperature > 0.7) { + return Biomes.DEEP_WARM_OCEAN; + } + return Biomes.DEEP_OCEAN; + } + + protected Biome defaultBiome(float temperature, float moisture) { + if (temperature < 0.3) { + return ModBiomes.TAIGA_SCRUB; + } + if (temperature > 0.7) { + return ModBiomes.SAVANNA_SCRUB; + } + return Biomes.PLAINS; + } + + protected Biome get(Biome[][] group, Biome.TempCategory category, float shape, Biome def) { + return get(group, category.ordinal() - 1, shape, def); + } + + protected Biome get(Biome[][] group, BiomeType type, float shape, Biome def) { + return get(group, type.ordinal(), shape, def); + } + + protected Biome get(Biome[][] group, int ordinal, float shape, Biome def) { + if (ordinal >= group.length) { + return def; + } + + Biome[] biomes = group[ordinal]; + if (biomes == null || biomes.length == 0) { + return def; + } + + int index = NoiseUtil.round((biomes.length - 1) * shape); + return biomes[index]; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BasicBiomeMap.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BasicBiomeMap.java new file mode 100644 index 0000000..49b0a72 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BasicBiomeMap.java @@ -0,0 +1,82 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.common.collect.Sets; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.provider.BiomeHelper; +import net.minecraft.world.biome.Biome; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class BasicBiomeMap extends AbstractBiomeMap { + + private final Biome[][] biomeTypes; + + public BasicBiomeMap(BiomeMapBuilder builder) { + super(builder); + biomeTypes = builder.biomeList(); + } + + @Override + public List getAllBiomes(BiomeType type) { + if (type.ordinal() >= biomeTypes.length) { + return Collections.emptyList(); + } + return Arrays.asList(biomeTypes[type.ordinal()]); + } + + @Override + public Set getBiomes(BiomeType type) { + if (type.ordinal() >= biomeTypes.length) { + return Collections.emptySet(); + } + return Sets.newHashSet(biomeTypes[type.ordinal()]); + } + + @Override + public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { + return get(biomeTypes, type, shape, defaultBiome(temperature, moisture)); + } + + @Override + public JsonObject toJson() { + JsonObject groups = new JsonObject(); + for (BiomeType type : BiomeType.values()) { + JsonArray group = new JsonArray(); + getBiomes(type).stream().map(BiomeHelper::getId).sorted().forEach(group::add); + groups.add(type.name(), group); + } + JsonObject root = super.toJson(); + root.add("biomes", groups); + return root; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeGroup.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeGroup.java new file mode 100644 index 0000000..98fd7cc --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeGroup.java @@ -0,0 +1,38 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.terraforged.core.util.grid.FixedGrid; +import net.minecraft.world.biome.Biome; + +public class BiomeGroup { + + public final FixedGrid biomes; + + public BiomeGroup(FixedGrid biomes) { + this.biomes = biomes; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java new file mode 100644 index 0000000..db2ae58 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java @@ -0,0 +1,71 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.gson.JsonElement; +import com.terraforged.core.world.biome.BiomeType; +import net.minecraft.world.biome.Biome; + +import java.util.List; +import java.util.Set; + +public interface BiomeMap { + + Biome getBeach(float temperature, float moisture, float shape); + + Biome getRiver(float temperature, float moisture, float shape); + + Biome getOcean(float temperature, float moisture, float shape); + + Biome getDeepOcean(float temperature, float moisture, float shape); + + Biome getBiome(BiomeType type, float temperature, float moisture, float shape); + + List getAllBiomes(BiomeType type); + + Set getBiomes(BiomeType type); + + Set getRivers(Biome.TempCategory temp); + + Set getOceanBiomes(Biome.TempCategory temp); + + Set getDeepOceanBiomes(Biome.TempCategory temp); + + JsonElement toJson(); + + interface Builder { + + Builder addBeach(Biome biome, int count); + + Builder addRiver(Biome biome, int count); + + Builder addOcean(Biome biome, int count); + + Builder addBiome(BiomeType type, Biome biome, int count); + + BiomeMap build(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeMapBuilder.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeMapBuilder.java new file mode 100644 index 0000000..281e9b5 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomeMapBuilder.java @@ -0,0 +1,176 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.terraforged.core.util.grid.FixedGrid; +import com.terraforged.core.world.biome.BiomeData; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.provider.BiomeHelper; +import com.terraforged.mod.util.ListUtils; +import net.minecraft.world.biome.Biome; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +public class BiomeMapBuilder implements BiomeMap.Builder { + + private final Map> rivers = new HashMap<>(); + private final Map> beaches = new HashMap<>(); + private final Map> oceans = new HashMap<>(); + private final Map> deepOceans = new HashMap<>(); + private final Map> map = new EnumMap<>(BiomeType.class); + private final Map dataMap = new HashMap<>(); + + private final int gridSize; + private final Function constructor; + + BiomeMapBuilder(Function constructor, int gridSize, List biomes) { + this.constructor = constructor; + this.gridSize = gridSize; + + for (BiomeData data : biomes) { + dataMap.put((Biome) data.reference, data); + } + } + + @Override + public BiomeMapBuilder addOcean(Biome biome, int count) { + Biome.TempCategory category = BiomeHelper.getTempCategory(biome); + if (biome.getDepth() < -1) { + add(deepOceans.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + } else { + add(oceans.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + } + return this; + } + + @Override + public BiomeMap.Builder addBeach(Biome biome, int count) { + Biome.TempCategory category = BiomeHelper.getTempCategory(biome); + add(beaches.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMapBuilder addRiver(Biome biome, int count) { + Biome.TempCategory category = BiomeHelper.getTempCategory(biome); + add(rivers.computeIfAbsent(category, c -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMapBuilder addBiome(BiomeType type, Biome biome, int count) { + add(map.computeIfAbsent(type, t -> new ArrayList<>()), biome, count); + return this; + } + + @Override + public BiomeMap build() { + return constructor.apply(this); + } + + Biome[][] rivers() { + return collectTemps(rivers); + } + + Biome[][] beaches() { + return collectTemps(beaches); + } + + Biome[][] oceans() { + return collectTemps(oceans); + } + + Biome[][] deepOceans() { + return collectTemps(deepOceans); + } + + Biome[][] biomeList() { + return collectTypes(map); + } + + BiomeGroup[] biomeGroups() { + BiomeGroup[] biomes = new BiomeGroup[BiomeType.values().length]; + + Function moisture = b -> dataMap.get(b).rainfall; + Function temperature = b -> dataMap.get(b).temperature; + for (BiomeType type : BiomeType.values()) { + List list = map.getOrDefault(type, Collections.emptyList()); + if (list.isEmpty()) { + continue; + } + FixedGrid grid = FixedGrid.generate(gridSize, list, moisture, temperature); + biomes[type.ordinal()] = new BiomeGroup(grid); + } + + return biomes; + } + + private void add(List list, Biome biome, int count) { + for (int i = 0; i < count; i++) { + list.add(biome); + } + } + + private Biome[][] collectTemps(Map> map) { + Biome[][] biomes = new Biome[3][]; + for (Biome.TempCategory category : Biome.TempCategory.values()) { + if (category == Biome.TempCategory.OCEAN) { + continue; + } + List list = map.getOrDefault(category, Collections.emptyList()); + list = ListUtils.minimize(list); + list.sort(Comparator.comparing(BiomeHelper::getId)); + biomes[category.ordinal() - 1] = list.toArray(new Biome[0]); + } + return biomes; + } + + private Biome[][] collectTypes(Map> map) { + Biome[][] biomes = new Biome[BiomeType.values().length][]; + for (BiomeType type : BiomeType.values()) { + List list = map.getOrDefault(type, Collections.emptyList()); + list = ListUtils.minimize(list); + list.sort(Comparator.comparing(BiomeHelper::getId)); + biomes[type.ordinal()] = list.toArray(new Biome[0]); + } + return biomes; + } + + public static BiomeMap.Builder basic(List biomes) { + return new BiomeMapBuilder(BasicBiomeMap::new, 0, biomes); + } + + public static BiomeMap.Builder grid(int size, List biomes) { + return new BiomeMapBuilder(GridBiomeMap::new, size, biomes); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomePredicate.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomePredicate.java new file mode 100644 index 0000000..8b58fcd --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/BiomePredicate.java @@ -0,0 +1,101 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.terraforged.core.world.biome.BiomeData; +import com.terraforged.mod.biome.provider.BiomeHelper; +import net.minecraft.world.biome.Biome; + +import java.util.function.BiPredicate; + +public interface BiomePredicate { + + boolean test(BiomeData data, Biome biome); + + default boolean test(BiomeData data) { + return test(data, (Biome) data.reference); + } + + default BiomePredicate and(BiomePredicate other) { + return (d, b) -> this.test(d, b) && other.test(d, b); + } + + default BiomePredicate not(BiomePredicate other) { + return (d, b) -> this.test(d, b) && !other.test(d, b); + } + + default BiomePredicate or(BiomePredicate other) { + return (d, b) -> this.test(d, b) || other.test(d, b); + } + + static BiomePredicate name(String... name) { + return (d, b) -> anyMatch(BiomeHelper.getId(b), name, String::contains); + } + + static BiomePredicate type(Biome.Category... categories) { + return (d, b) -> anyMatch(b.getCategory(), categories, (c1, c2) -> c1 == c2); + } + + static BiomePredicate rain(double min, double max) { + return (d, b) -> d.rainfall >= min && d.rainfall <= max; + } + + static BiomePredicate rainType(Biome.RainType... rainTypes) { + return (d, b) -> anyMatch(b.getPrecipitation(), rainTypes, (c1, c2) -> c1 == c2); + } + + static BiomePredicate temp(double min, double max) { + return (d, b) -> d.temperature >= min && d.temperature <= max; + } + + static BiomePredicate depth(double min, double max) { + return (d, b) -> b.getDepth() >= min && b.getDepth() <= max; + } + + static boolean anyMatch(T value, T[] test, BiPredicate tester) { + for (T t : test) { + if (tester.test(value, t)) { + return true; + } + } + return false; + } + + BiomePredicate COAST = type(Biome.Category.BEACH); + BiomePredicate WETLAND = type(Biome.Category.SWAMP); + BiomePredicate DESERT = type(Biome.Category.DESERT).or(temp(0.9, 2).and(rain(-1, 0.2))); + BiomePredicate SAVANNA = type(Biome.Category.SAVANNA).or(temp(0.8, 2).and(rain(-1, 0.4))); + BiomePredicate MESA = type(Biome.Category.MESA); + BiomePredicate STEPPE = name("steppe").and(temp(0.3, 1)); + BiomePredicate COLD_STEPPE = name("steppe").and(temp(-1, 0.3)); + BiomePredicate GRASSLAND = type(Biome.Category.PLAINS); + BiomePredicate TEMPERATE_FOREST = type(Biome.Category.FOREST).and(rain(-1, 0.81)); + BiomePredicate TEMPERATE_RAINFOREST = type(Biome.Category.FOREST).and(rain(0.8, 2)); + BiomePredicate TROPICAL_RAINFOREST = type(Biome.Category.JUNGLE); + BiomePredicate TAIGA = type(Biome.Category.TAIGA).or(temp(0.19, 0.35)).not(rainType(Biome.RainType.SNOW)); + BiomePredicate TUNDRA = type(Biome.Category.ICY).or(temp(-1, 0.21).and(rainType(Biome.RainType.SNOW))); + BiomePredicate MOUNTAIN = type(Biome.Category.EXTREME_HILLS).or(name("mountain")); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/GridBiomeMap.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/GridBiomeMap.java new file mode 100644 index 0000000..eb0a02f --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/map/GridBiomeMap.java @@ -0,0 +1,127 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.map; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.util.grid.FixedList; +import com.terraforged.core.util.grid.MappedList; +import com.terraforged.core.world.biome.BiomeType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class GridBiomeMap extends AbstractBiomeMap { + + private final BiomeGroup[] biomeTypes; + + GridBiomeMap(BiomeMapBuilder builder) { + super(builder); + biomeTypes = builder.biomeGroups(); + } + + @Override + public Biome getBiome(BiomeType type, float temperature, float moisture, float shape) { + BiomeGroup group = biomeTypes[type.ordinal()]; + if (group == null) { + return Biomes.NETHER; + } + return group.biomes.get(moisture, temperature, shape); + } + + @Override + public List getAllBiomes(BiomeType type) { + BiomeGroup group = biomeTypes[type.ordinal()]; + if (group == null) { + return Collections.emptyList(); + } + List biomes = new LinkedList<>(); + for (MappedList> row : group.biomes) { + for (FixedList cell : row) { + for (Biome biome : cell) { + biomes.add(biome); + } + } + } + return biomes; + } + + @Override + public Set getBiomes(BiomeType type) { + BiomeGroup group = biomeTypes[type.ordinal()]; + if (group == null) { + return Collections.emptySet(); + } + Set biomes = new HashSet<>(); + for (MappedList> row : group.biomes) { + for (FixedList cell : row) { + for (Biome biome : cell) { + biomes.add(biome); + } + } + } + return biomes; + } + + @Override + public JsonObject toJson() { + JsonObject root = new JsonObject(); + for (BiomeType type : BiomeType.values()) { + BiomeGroup group = biomeTypes[type.ordinal()]; + JsonObject grid = new JsonObject(); + if (group != null) { + int rowCount = 0; + float maxRow = group.biomes.size() - 1; + for (MappedList> row : group.biomes) { + int colCount = 0; + float maxCol = row.size() - 1; + + JsonObject rowJson = new JsonObject(); + for (FixedList cell : row) { + JsonArray colJson = new JsonArray(); + for (Biome biome : cell.uniqueValues()) { + colJson.add(biome.getRegistryName() + ""); + } + float colId = colCount / maxCol; + rowJson.add("" + colId, colJson); + colCount++; + } + + float rowId = rowCount / maxRow; + grid.add("" + rowId, rowJson); + rowCount++; + } + } + root.add(type.name(), grid); + } + return root; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/AbstractMaxHeightModifier.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/AbstractMaxHeightModifier.java new file mode 100644 index 0000000..8915c6d --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/AbstractMaxHeightModifier.java @@ -0,0 +1,67 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.world.biome.Biome; + +public abstract class AbstractMaxHeightModifier extends AbstractOffsetModifier { + + private final float minHeight; + private final float maxHeight; + private final float range; + private final Module variance; + + public AbstractMaxHeightModifier(Seed seed, Climate climate, int scale, int octaves, float variance, float minHeight, float maxHeight) { + super(climate); + this.minHeight = minHeight; + this.maxHeight = maxHeight; + this.range = maxHeight - minHeight; + this.variance = Source.perlin(seed.next(), scale, octaves).scale(variance); + } + + @Override + protected final Biome modify(Biome in, Cell cell, int x, int z, float ox, float oz) { + float var = variance.getValue(x, z); + float value = cell.value + var; + if (value < minHeight) { + return in; + } + if (value > maxHeight) { + return getModifiedBiome(in, cell, x, z, ox, oz); + } + float alpha = (value - minHeight) / range; + cell.biomeEdge *= alpha; + return in; + } + + protected abstract Biome getModifiedBiome(Biome in, Cell cell, int x, int z, float ox, float oz); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/AbstractOffsetModifier.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/AbstractOffsetModifier.java new file mode 100644 index 0000000..0f9031a --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/AbstractOffsetModifier.java @@ -0,0 +1,50 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.world.biome.Biome; + +public abstract class AbstractOffsetModifier implements BiomeModifier { + + private final Climate climate; + + public AbstractOffsetModifier(Climate climate) { + this.climate = climate; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + float dx = climate.getOffsetX(x, z, 50); + float dz = climate.getOffsetX(x, z, 50); + return modify(in, cell, x, z, x + dx, z + dz); + } + + protected abstract Biome modify(Biome in, Cell cell, int x, int z, float ox, float oz); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/BeachModifier.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/BeachModifier.java new file mode 100644 index 0000000..31abce2 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/BeachModifier.java @@ -0,0 +1,62 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.map.BiomeMap; +import net.minecraft.world.biome.Biome; + +public class BeachModifier implements BiomeModifier { + + private final Terrains terrain; + private final BiomeMap biomeMap; + + public BeachModifier(BiomeMap biomeMap, Terrains terrain) { + this.terrain = terrain; + this.biomeMap = biomeMap; + } + + @Override + public int priority() { + return 0; + } + + @Override + public boolean test(Biome biome) { + return true; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + if (cell.tag == terrain.beach) { + return biomeMap.getBeach(cell.temperature, cell.moisture, cell.biome); + } + return in; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/BiomeModifierManager.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/BiomeModifierManager.java new file mode 100644 index 0000000..86a0300 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/BiomeModifierManager.java @@ -0,0 +1,95 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.api.biome.modifier.ModifierManager; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.provider.DesertBiomes; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.biome.Biome; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class BiomeModifierManager implements BiomeModifier, ModifierManager { + + private final DesertBiomes desertBiomes; + private final List biomeModifiers; + + public BiomeModifierManager(TerraContext context, BiomeMap biomes) { + desertBiomes = new DesertBiomes(context.materials, biomes.getAllBiomes(BiomeType.DESERT)); + List modifiers = new ArrayList<>(); + modifiers.add(new BeachModifier(biomes, context.terrain)); + modifiers.add(new DesertColorModifier(desertBiomes)); + modifiers.add(new SandBiomeModifier( + context.seed, + context.factory.getClimate(), + context.levels + )); + modifiers.add(new SwampModifier( + context.seed, + context.factory.getClimate(), + context.levels + )); + Collections.sort(modifiers); + this.biomeModifiers = modifiers; + } + + @Override + public void register(BiomeModifier modifier) { + biomeModifiers.add(modifier); + Collections.sort(biomeModifiers); + } + + public DesertBiomes getDesertBiomes() { + return desertBiomes; + } + + @Override + public int priority() { + return -1; + } + + @Override + public boolean test(Biome biome) { + return true; + } + + @Override + public Biome modify(Biome biome, Cell cell, int x, int z) { + for (BiomeModifier modifier : biomeModifiers) { + if (modifier.test(biome)) { + biome = modifier.modify(biome, cell, x, z); + } + } + return biome; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/DesertColorModifier.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/DesertColorModifier.java new file mode 100644 index 0000000..d941f23 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/DesertColorModifier.java @@ -0,0 +1,63 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.api.biome.modifier.BiomeModifier; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.DesertBiomes; +import net.minecraft.world.biome.Biome; + +public class DesertColorModifier implements BiomeModifier { + + private final DesertBiomes biomes; + + public DesertColorModifier(DesertBiomes biomes) { + this.biomes = biomes; + } + + @Override + public int priority() { + return 0; + } + + @Override + public boolean test(Biome biome) { + return biome.getCategory() == Biome.Category.DESERT; + } + + @Override + public Biome modify(Biome in, Cell cell, int x, int z) { + if (biomes.isRedDesert(in)) { + if (cell.continent <= 0.5F) { + return biomes.getWhiteDesert(cell.biome); + } + } else if (cell.continent > 0.5F) { + return biomes.getRedDesert(cell.biome); + } + return in; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/SandBiomeModifier.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/SandBiomeModifier.java new file mode 100644 index 0000000..bd5279b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/SandBiomeModifier.java @@ -0,0 +1,67 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.material.MaterialHelper; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Set; +import java.util.stream.Collectors; + +// prevents deserts forming at high levels +public class SandBiomeModifier extends AbstractMaxHeightModifier { + + private final Set biomes; + + public SandBiomeModifier(Seed seed, Climate climate, Levels levels) { + super(seed, climate, 50, 2, levels.scale(8), levels.ground(5), levels.ground(25)); + this.biomes = ForgeRegistries.BIOMES.getValues().stream() + .filter(biome -> MaterialHelper.isSand(biome.getSurfaceBuilderConfig().getTop().getBlock())) + .collect(Collectors.toSet()); + } + + @Override + public int priority() { + return 1; + } + + @Override + public boolean test(Biome biome) { + return biome.getCategory() == Biome.Category.DESERT || biomes.contains(biome); + } + + @Override + protected Biome getModifiedBiome(Biome in, Cell cell, int x, int z, float ox, float oz) { + return Biomes.BADLANDS; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/SwampModifier.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/SwampModifier.java new file mode 100644 index 0000000..2cd031b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/modifier/SwampModifier.java @@ -0,0 +1,57 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.modifier; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.climate.Climate; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +// prevents swamps forming at high levels +public class SwampModifier extends AbstractMaxHeightModifier { + + public SwampModifier(Seed seed, Climate climate, Levels levels) { + super(seed, climate, 60, 1, levels.scale(10), levels.ground(4), levels.ground(12)); + } + + @Override + protected Biome getModifiedBiome(Biome in, Cell cell, int x, int z, float ox, float oz) { + return Biomes.PLAINS; + } + + @Override + public int priority() { + return 0; + } + + @Override + public boolean test(Biome biome) { + return biome.getCategory() == Biome.Category.SWAMP; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/AbstractBiomeProvider.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/AbstractBiomeProvider.java new file mode 100644 index 0000000..75bd5c3 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/AbstractBiomeProvider.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.google.common.collect.ImmutableSet; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.util.List; +import java.util.Random; +import java.util.Set; + +public abstract class AbstractBiomeProvider extends net.minecraft.world.biome.provider.BiomeProvider { + + protected static final Set defaultBiomes = ImmutableSet.of(Biomes.OCEAN, Biomes.PLAINS, Biomes.DESERT, Biomes.MOUNTAINS, Biomes.FOREST, Biomes.TAIGA, Biomes.SWAMP, Biomes.RIVER, Biomes.FROZEN_OCEAN, Biomes.FROZEN_RIVER, Biomes.SNOWY_TUNDRA, Biomes.SNOWY_MOUNTAINS, Biomes.MUSHROOM_FIELDS, Biomes.MUSHROOM_FIELD_SHORE, Biomes.BEACH, Biomes.DESERT_HILLS, Biomes.WOODED_HILLS, Biomes.TAIGA_HILLS, Biomes.MOUNTAIN_EDGE, Biomes.JUNGLE, Biomes.JUNGLE_HILLS, Biomes.JUNGLE_EDGE, Biomes.DEEP_OCEAN, Biomes.STONE_SHORE, Biomes.SNOWY_BEACH, Biomes.BIRCH_FOREST, Biomes.BIRCH_FOREST_HILLS, Biomes.DARK_FOREST, Biomes.SNOWY_TAIGA, Biomes.SNOWY_TAIGA_HILLS, Biomes.GIANT_TREE_TAIGA, Biomes.GIANT_TREE_TAIGA_HILLS, Biomes.WOODED_MOUNTAINS, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.BADLANDS, Biomes.WOODED_BADLANDS_PLATEAU, Biomes.BADLANDS_PLATEAU, Biomes.WARM_OCEAN, Biomes.LUKEWARM_OCEAN, Biomes.COLD_OCEAN, Biomes.DEEP_WARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN, Biomes.DEEP_COLD_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.SUNFLOWER_PLAINS, Biomes.DESERT_LAKES, Biomes.GRAVELLY_MOUNTAINS, Biomes.FLOWER_FOREST, Biomes.TAIGA_MOUNTAINS, Biomes.SWAMP_HILLS, Biomes.ICE_SPIKES, Biomes.MODIFIED_JUNGLE, Biomes.MODIFIED_JUNGLE_EDGE, Biomes.TALL_BIRCH_FOREST, Biomes.TALL_BIRCH_HILLS, Biomes.DARK_FOREST_HILLS, Biomes.SNOWY_TAIGA_MOUNTAINS, Biomes.GIANT_SPRUCE_TAIGA, Biomes.GIANT_SPRUCE_TAIGA_HILLS, Biomes.MODIFIED_GRAVELLY_MOUNTAINS, Biomes.SHATTERED_SAVANNA, Biomes.SHATTERED_SAVANNA_PLATEAU, Biomes.ERODED_BADLANDS, Biomes.MODIFIED_WOODED_BADLANDS_PLATEAU, Biomes.MODIFIED_BADLANDS_PLATEAU); + + public AbstractBiomeProvider() { + super(defaultBiomes); + } + + @Override + public final Biome getNoiseBiome(int x, int y, int z) { + return getBiome(x, y, z); + } + + @Override + public final Set func_225530_a_(int x, int y, int z, int size) { + return getBiomesInSquare(x, y, z, size); + } + + @Override + public final BlockPos func_225531_a_(int centerX, int centerY, int centerZ, int range, List biomes, Random random) { + return findBiomePosition(centerX, centerY, centerZ, range, biomes, random); + } + + public abstract Biome getBiome(int x, int y, int z); + + public abstract Set getBiomesInSquare(int x, int y, int z, int size); + + public abstract BlockPos findBiomePosition(int centerX, int centerY, int centerZ, int range, List biomes, Random random); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/BiomeHelper.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/BiomeHelper.java new file mode 100644 index 0000000..75fbe47 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/BiomeHelper.java @@ -0,0 +1,243 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.google.common.collect.Sets; +import com.terraforged.core.settings.BiomeSettings; +import com.terraforged.core.world.biome.BiomeData; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.ModBiomes; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.map.BiomeMapBuilder; +import com.terraforged.mod.biome.map.BiomePredicate; +import me.dags.noise.util.Vec2f; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.structure.OceanRuinConfig; +import net.minecraft.world.gen.feature.structure.OceanRuinStructure; +import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class BiomeHelper { + + private static final Set IGNORE_BIOMES = Sets.newHashSet( + Biomes.THE_END, + Biomes.END_BARRENS, + Biomes.END_HIGHLANDS, + Biomes.END_MIDLANDS, + Biomes.SMALL_END_ISLANDS, + Biomes.NETHER, + Biomes.THE_VOID, + Biomes.JUNGLE_EDGE, + Biomes.MODIFIED_JUNGLE_EDGE, + Biomes.MOUNTAIN_EDGE, + Biomes.STONE_SHORE + ); + + private static final Map PREDICATES = new HashMap() {{ + put(BiomeType.TROPICAL_RAINFOREST, BiomePredicate.TROPICAL_RAINFOREST); + put(BiomeType.SAVANNA, BiomePredicate.SAVANNA.or(BiomePredicate.MESA).not(BiomePredicate.DESERT).not(BiomePredicate.STEPPE).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.DESERT, BiomePredicate.DESERT.or(BiomePredicate.MESA).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.TEMPERATE_RAINFOREST, BiomePredicate.TEMPERATE_RAINFOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TEMPERATE_FOREST, BiomePredicate.TEMPERATE_FOREST.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN).not(BiomePredicate.WETLAND)); + put(BiomeType.GRASSLAND, BiomePredicate.GRASSLAND.or(BiomePredicate.WETLAND).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.COLD_STEPPE, BiomePredicate.COLD_STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.STEPPE, BiomePredicate.STEPPE.not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TAIGA, BiomePredicate.TAIGA.not(BiomePredicate.TUNDRA).not(BiomePredicate.COLD_STEPPE).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.TUNDRA, BiomePredicate.TUNDRA.not(BiomePredicate.TAIGA).not(BiomePredicate.COAST).not(BiomePredicate.MOUNTAIN)); + put(BiomeType.ALPINE, BiomePredicate.MOUNTAIN); + }}; + + public static BiomeMap.Builder getBuilder(List biomes) { + return BiomeMapBuilder.basic(biomes); + } + + public static BiomeMap getDefaultBiomeMap() { + List biomes = getAllBiomeData(); + BiomeMap.Builder builder = getBuilder(biomes); + for (BiomeData data : biomes) { + int weight = 10; + Biome biome = (Biome) data.reference; + + if (biome.isMutation() && getId(biome).contains("hills")) { + continue; + } + + if (biome.getCategory() == Biome.Category.FOREST) { + weight = 5; + } + + if (biome.getCategory() == Biome.Category.MUSHROOM) { + weight = 1; + } + + // don't use BiomeDictionary with transient biomes + if (ForgeRegistries.BIOMES.containsKey(biome.getRegistryName())) { + if (BiomeDictionary.getTypes(biome).contains(BiomeDictionary.Type.RARE)) { + weight = 1; + } + } + + if (biome.getCategory() == Biome.Category.OCEAN) { + builder.addOcean(biome, weight); + } else if (biome.getCategory() == Biome.Category.RIVER) { + builder.addRiver(biome, weight); + } else if (biome.getCategory() == Biome.Category.BEACH || biome == Biomes.STONE_SHORE) { + builder.addBeach(biome, weight); + } else { + Collection types = getTypes(data, biome); + for (BiomeType type : types) { + builder.addBiome(type, biome, weight); + } + } + } + + builder.addBiome(BiomeType.TEMPERATE_RAINFOREST, Biomes.PLAINS, 10); + builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.FLOWER_FOREST, 3); + builder.addBiome(BiomeType.TEMPERATE_FOREST, Biomes.PLAINS, 10); + builder.addBiome(BiomeType.TUNDRA, ModBiomes.SNOWY_TAIGA_SCRUB, 5); + builder.addBiome(BiomeType.TAIGA, ModBiomes.TAIGA_SCRUB, 5); + + return builder.build(); + } + + public static BiomeMap getBiomeMap(BiomeSettings settings) { + List biomes = getAllBiomeData(); + BiomeMap.Builder builder = getBuilder(biomes); + Map biomeMap = biomes.stream().collect(Collectors.toMap(d -> d.name, d -> d)); + Map groupMap = settings.asMap(); + for (Map.Entry e : groupMap.entrySet()) { + for (BiomeSettings.BiomeWeight biomeWeight : e.getValue().biomes) { + BiomeData data = biomeMap.get(biomeWeight.id); + if (data == null) { + continue; + } + builder.addBiome(e.getKey(), (Biome) data.reference, biomeWeight.weight); + } + } + for (BiomeData data : biomes) { + Biome biome = (Biome) data.reference; + if (biome.getCategory() == Biome.Category.OCEAN) { + builder.addOcean(biome, 10); + } else if (biome.getCategory() == Biome.Category.RIVER) { + builder.addRiver(biome, 10); + } + } + return builder.build(); + } + + public static Biome.TempCategory getTempCategory(Biome biome) { + // vanilla ocean biome properties are not at all helpful for determining temperature + if (biome.getCategory() == Biome.Category.OCEAN) { + // warm & luke_warm oceans get OceanRuinStructure.Type.WARM + OceanRuinConfig config = biome.getStructureConfig(Feature.OCEAN_RUIN); + if (config != null) { + if (config.field_204031_a == OceanRuinStructure.Type.WARM) { + return Biome.TempCategory.WARM; + } + } + + // if the id contains the world cold or frozen, assume it's cold + if (getId(biome).contains("cold") || getId(biome).contains("frozen")) { + return Biome.TempCategory.COLD; + } + + // the rest we categorize as medium + return Biome.TempCategory.MEDIUM; + } + // hopefully biomes otherwise have a sensible category + return biome.getTempCategory(); + } + + public static String getId(Biome biome) { + ResourceLocation name = biome.getRegistryName(); + if (name == null) { + return "unknown"; + } + return name.toString(); + } + + public static Collection getTypes(BiomeData data, Biome biome) { + Set types = new HashSet<>(); + for (Map.Entry entry : PREDICATES.entrySet()) { + if (entry.getValue().test(data, biome)) { + types.add(entry.getKey()); + } + } + return types; + } + + public static List getAllBiomeData() { + Collection biomes = TerraBiomeRegistry.getInstance().getAll(BiomeHelper::filter); + Vec2f tempRange = getRange(biomes, Biome::getDefaultTemperature); + Vec2f moistRange = getRange(biomes, Biome::getDownfall); + List list = new LinkedList<>(); + for (Biome biome : biomes) { + String name = getId(biome); + float moisture = (biome.getDownfall() - moistRange.x) / (moistRange.y - moistRange.x); + float temperature = (biome.getDefaultTemperature() - tempRange.x) / (tempRange.y - tempRange.x); + int color = biome.getSurfaceBuilderConfig().getTop().getMaterial().getColor().colorValue; + list.add(new BiomeData(name, biome, color, moisture, temperature)); + } + return list; + } + + private static boolean filter(Biome biome) { + if (biome.getCategory() == Biome.Category.NONE) { + return true; + } + if (biome.getCategory() == Biome.Category.THEEND) { + return true; + } + if (biome.getCategory() == Biome.Category.NETHER) { + return true; + } + return IGNORE_BIOMES.contains(biome); + } + + private static Vec2f getRange(Collection biomes, Function getter) { + float min = Float.MAX_VALUE; + float max = Float.MIN_VALUE; + for (Biome biome : biomes) { + float value = getter.apply(biome); + min = Math.min(min, value); + max = Math.max(max, value); + } + return new Vec2f(min, max); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/BiomeProvider.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/BiomeProvider.java new file mode 100644 index 0000000..f7372af --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/BiomeProvider.java @@ -0,0 +1,165 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.google.common.collect.Sets; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.chunk.ChunkReader; +import com.terraforged.core.util.concurrent.ObjectPool; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.modifier.BiomeModifierManager; +import com.terraforged.mod.chunk.TerraContainer; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.util.setup.SetupHooks; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.feature.structure.Structure; + +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +public class BiomeProvider extends AbstractBiomeProvider { + + private final BiomeMap biomeMap; + private final TerraContext context; + private final BiomeModifierManager modifierManager; + + public BiomeProvider(TerraContext context) { + this.context = context; + this.biomeMap = BiomeHelper.getDefaultBiomeMap(); + this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy()); + } + + public BiomeModifierManager getModifierManager() { + return modifierManager; + } + + public TerraContainer createBiomeContainer(ChunkReader chunkReader) { + TerraContainer.Builder builder = TerraContainer.builder(); + chunkReader.iterate((cell, dx, dz) -> { + Biome biome = getBiome(cell, chunkReader.getBlockX() + dx, chunkReader.getBlockZ() + dz); + builder.fill(dx, dz, biome); + }); + return builder.build(chunkReader); + } + + @Override + public Biome getBiome(int x, int y, int z) { + try (ObjectPool.Item> item = Cell.pooled()) { + context.heightmap.apply(item.getValue(), x, z); + return getBiome(item.getValue(), x, z); + } + } + + @Override + public Set getBiomesInSquare(int centerX, int centerY, int centerZ, int sideLength) { + int minX = centerX - (sideLength >> 2); + int minZ = centerZ - (sideLength >> 2); + int maxX = centerX + (sideLength >> 2); + int maxZ = centerZ + (sideLength >> 2); + Set biomes = Sets.newHashSet(); + context.heightmap.visit(minX, minZ, maxX, maxZ, (cell, x, z) -> { + Biome biome = getBiome(cell, minX + x, minZ + z); + biomes.add(biome); + }); + return biomes; + } + + @Override + public BlockPos findBiomePosition(int centerX, int centerY, int centerZ, int range, List biomes, Random random) { + int minX = centerX - (range >> 2); + int minZ = centerZ - (range >> 2); + int maxX = centerX + (range >> 2); + int maxZ = centerZ + (range >> 2); + Set matchBiomes = new HashSet<>(biomes); + SearchContext search = new SearchContext(); + context.heightmap.visit(minX, minZ, maxX, maxZ, (cell, x, z) -> { + Biome biome = getBiome(cell, minX + x, minZ + z); + if (matchBiomes.contains(biome)) { + if (search.first || random.nextInt(search.count + 1) == 0) { + search.first = false; + search.pos.setPos(minX + x, 0, minZ + z); + } + ++search.count; + } + }); + return search.pos; + } + + @Override + public boolean hasStructure(Structure structureIn) { + return this.hasStructureCache.computeIfAbsent(structureIn, (p_205006_1_) -> { + for (Biome biome : defaultBiomes) { + if (biome.hasStructure(p_205006_1_)) { + return true; + } + } + return false; + }); + } + + @Override + public Set getSurfaceBlocks() { + if (this.topBlocksCache.isEmpty()) { + for (Biome biome : defaultBiomes) { + this.topBlocksCache.add(biome.getSurfaceBuilderConfig().getTop()); + } + } + return this.topBlocksCache; + } + + public Biome getBiome(Cell cell, int x, int z) { + if (cell.value <= context.levels.water) { + if (cell.tag == context.terrain.river || cell.tag == context.terrain.riverBanks) { + return modifyBiome(biomeMap.getRiver(cell.temperature, cell.moisture, cell.biome), cell, x, z); + } else if (cell.tag == context.terrain.ocean) { + return biomeMap.getOcean(cell.temperature, cell.moisture, cell.biome); + } else if (cell.tag == context.terrain.deepOcean) { + return biomeMap.getDeepOcean(cell.temperature, cell.moisture, cell.biome); + } + } + return modifyBiome(getBiome(cell), cell, x, z); + } + + public Biome getBiome(Cell cell) { + return biomeMap.getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome); + } + + public Biome modifyBiome(Biome biome, Cell cell, int x, int z) { + return modifierManager.modify(biome, cell, x, z); + } + + private static class SearchContext { + + private int count = 0; + private boolean first = true; + private final BlockPos.Mutable pos = new BlockPos.Mutable(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/DesertBiomes.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/DesertBiomes.java new file mode 100644 index 0000000..18941d9 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/DesertBiomes.java @@ -0,0 +1,117 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.api.material.layer.LayerMaterial; +import com.terraforged.core.util.concurrent.ObjectPool; +import com.terraforged.mod.material.Materials; +import com.terraforged.mod.util.DummyBlockReader; +import com.terraforged.mod.util.ListUtils; +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.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class DesertBiomes { + + private final Set reds; + private final Set whites; + private final List redSand; + private final List whiteSand; + private final LayerManager layerManager; + + private final int maxRedIndex; + private final int maxWhiteIndex; + + public DesertBiomes(Materials materials, List deserts) { + List white = new LinkedList<>(); + List red = new LinkedList<>(); + try (ObjectPool.Item reader = DummyBlockReader.pooled()) { + for (Biome biome : deserts) { + BlockState top = biome.getSurfaceBuilderConfig().getTop(); + MaterialColor color = top.getMaterialColor(reader.getValue().set(top), BlockPos.ZERO); + int whiteDist2 = distance2(color, MaterialColor.SAND); + int redDist2 = distance2(color, MaterialColor.ADOBE); + if (whiteDist2 < redDist2) { + white.add(biome); + } else { + red.add(biome); + } + } + } + this.layerManager = materials.getLayerManager(); + this.whiteSand = new ArrayList<>(white); + this.redSand = new ArrayList<>(red); + this.whites = new HashSet<>(white); + this.reds = new HashSet<>(red); + this.whiteSand.sort(Comparator.comparing(BiomeHelper::getId)); + this.redSand.sort(Comparator.comparing(BiomeHelper::getId)); + this.maxRedIndex = red.size() - 1; + this.maxWhiteIndex = white.size() - 1; + } + + public boolean isRedDesert(Biome biome) { + return reds.contains(biome); + } + + public boolean isWhiteDesert(Biome biome) { + return whites.contains(biome); + } + + public Biome getRedDesert(float shape) { + return ListUtils.get(redSand, maxRedIndex, shape, Biomes.MODIFIED_BADLANDS_PLATEAU); + } + + public Biome getWhiteDesert(float shape) { + return ListUtils.get(whiteSand, maxWhiteIndex, shape, Biomes.DESERT); + } + + public LayerMaterial getSandLayers(Biome biome) { + Block top = biome.getSurfaceBuilderConfig().getTop().getBlock(); + return layerManager.getMaterial(Blocks.SAND); + } + + private static int distance2(MaterialColor mc1, MaterialColor mc2) { + Color c1 = new Color(mc1.colorValue); + Color c2 = new Color(mc2.colorValue); + int dr = c1.getRed() - c2.getRed(); + int dg = c1.getGreen() - c2.getGreen(); + int db = c1.getBlue() - c2.getBlue(); + return (dr * dr) + (dg * dg) + (db * db); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeManager.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeManager.java new file mode 100644 index 0000000..20c39c9 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeManager.java @@ -0,0 +1,54 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeManager; +import net.minecraft.world.biome.ColumnFuzzedBiomeMagnifier; +import net.minecraft.world.biome.provider.BiomeProvider; + +public class TerraBiomeManager extends BiomeManager { + + private final long seed; + private final IBiomeReader provider; + + public TerraBiomeManager(IBiomeReader reader, long seed) { + super(reader, seed, ColumnFuzzedBiomeMagnifier.INSTANCE); + this.provider = reader; + this.seed = seed; + } + + @Override + public BiomeManager func_226835_a_(BiomeProvider provider) { + return new TerraBiomeManager(provider, seed); + } + + @Override + public Biome func_226836_a_(BlockPos pos) { + return provider.getNoiseBiome(pos.getX(), pos.getY(), pos.getZ()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeRegistry.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeRegistry.java new file mode 100644 index 0000000..68219be --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeRegistry.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.provider; + +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; + +public class TerraBiomeRegistry { + + private static final TerraBiomeRegistry instance = new TerraBiomeRegistry(); + + public Optional getBiome(ResourceLocation name) { + if (ForgeRegistries.BIOMES.containsKey(name)) { + return Optional.ofNullable(ForgeRegistries.BIOMES.getValue(name)); + } + return Optional.empty(); + } + + public Collection getAll(Predicate filter) { + List combined = new LinkedList<>(ForgeRegistries.BIOMES.getValues()); + combined.removeIf(filter); + return combined; + } + + public static TerraBiomeRegistry getInstance() { + return instance; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/biome/tag/BiomeTagManager.java b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/tag/BiomeTagManager.java new file mode 100644 index 0000000..26e5ac8 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/biome/tag/BiomeTagManager.java @@ -0,0 +1,72 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.biome.tag; + +import com.terraforged.api.biome.BiomeTags; +import com.terraforged.mod.Log; +import net.minecraft.profiler.IProfiler; +import net.minecraft.resources.IFutureReloadListener; +import net.minecraft.resources.IResourceManager; +import net.minecraft.tags.TagCollection; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) +public class BiomeTagManager implements IFutureReloadListener { + + private static final boolean RETAIN_ORDER = false; + + private final TagCollection collection = new TagCollection<>( + Registry.BIOME::getValue, + "tags/biomes", + BiomeTagManager.RETAIN_ORDER, + "biomes" + ); + + @Override + public CompletableFuture reload(IFutureReloadListener.IStage stage, IResourceManager manager, IProfiler preparationsProfiler, IProfiler reloadProfiler, Executor backgroundExecutor, Executor gameExecutor) { + Log.debug("Reloading biome tag collection"); + return collection.reload(manager, gameExecutor) + .thenCompose(stage::markCompleteAwaitingOthers) + .thenAccept(collection::registerAll) + .thenRun(() -> { + BiomeTags.setCollection(collection); + Log.debug("Biome tag reload complete"); + }); + } + + @SubscribeEvent + public static void init(FMLServerAboutToStartEvent event) { + Log.debug("Registering tag reload listener"); + event.getServer().getResourceManager().addReloadListener(new BiomeTagManager()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ChunkGeneratorFactory.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ChunkGeneratorFactory.java new file mode 100644 index 0000000..9b4d1f6 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ChunkGeneratorFactory.java @@ -0,0 +1,35 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.mod.biome.provider.BiomeProvider; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.OverworldGenSettings; + +public interface ChunkGeneratorFactory> { + + T create(TerraContext context, BiomeProvider biomeProvider, OverworldGenSettings settings); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java new file mode 100644 index 0000000..2888d05 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java @@ -0,0 +1,150 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.mod.util.annotation.Name; +import com.terraforged.mod.util.annotation.Ref; +import net.minecraft.entity.EntityClassification; +import net.minecraft.util.SharedSeedRandom; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorld; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.provider.BiomeProvider; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.GenerationSettings; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.INoiseGenerator; +import net.minecraft.world.gen.NoiseChunkGenerator; +import net.minecraft.world.gen.OverworldChunkGenerator; +import net.minecraft.world.gen.PerlinNoiseGenerator; +import net.minecraft.world.gen.WorldGenRegion; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.server.ServerWorld; +import net.minecraft.world.spawner.CatSpawner; +import net.minecraft.world.spawner.PatrolSpawner; +import net.minecraft.world.spawner.PhantomSpawner; +import net.minecraft.world.spawner.WorldEntitySpawner; + +import java.util.List; + +@Ref({OverworldChunkGenerator.class, NoiseChunkGenerator.class, ChunkGenerator.class}) +public abstract class ObfHelperChunkGenerator extends ChunkGenerator { + + private final CatSpawner catSpawner = new CatSpawner(); + private final PatrolSpawner patrolSpawner = new PatrolSpawner(); + private final PhantomSpawner phantomSpawner = new PhantomSpawner(); + private final INoiseGenerator surfaceNoise; + + public ObfHelperChunkGenerator(IWorld world, BiomeProvider biomeProvider, T settings) { + super(world, biomeProvider, settings); + SharedSeedRandom random = new SharedSeedRandom(world.getSeed()); + this.surfaceNoise = new PerlinNoiseGenerator(random, 3, 0); + } + + @Override + public final void generateStructureStarts(IWorld world, IChunk chunk) { + try { + super.generateStructureStarts(world, chunk); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + @Override + public final void makeBase(IWorld world, IChunk chunk) { + generateBase(world, chunk); + } + + @Override + public final void func_225551_a_(WorldGenRegion world, IChunk chunk) { + generateSurface(world, chunk); + } + + @Override + public final List getPossibleCreatures(EntityClassification type, BlockPos pos) { + if (Feature.SWAMP_HUT.func_202383_b(this.world, pos)) { + if (type == EntityClassification.MONSTER) { + return Feature.SWAMP_HUT.getSpawnList(); + } + + if (type == EntityClassification.CREATURE) { + return Feature.SWAMP_HUT.getCreatureSpawnList(); + } + } else if (type == EntityClassification.MONSTER) { + if (Feature.PILLAGER_OUTPOST.isPositionInStructure(this.world, pos)) { + return Feature.PILLAGER_OUTPOST.getSpawnList(); + } + + if (Feature.OCEAN_MONUMENT.isPositionInStructure(this.world, pos)) { + return Feature.OCEAN_MONUMENT.getSpawnList(); + } + } + return super.getPossibleCreatures(type, pos); + } + + @Override + public final void spawnMobs(ServerWorld worldIn, boolean spawnHostileMobs, boolean spawnPeacefulMobs) { + phantomSpawner.tick(worldIn, spawnHostileMobs, spawnPeacefulMobs); + patrolSpawner.tick(worldIn, spawnHostileMobs, spawnPeacefulMobs); + catSpawner.tick(worldIn, spawnHostileMobs, spawnPeacefulMobs); + } + + @Override + public final void spawnMobs(WorldGenRegion region) { + int chunkX = region.getMainChunkX(); + int chunkZ = region.getMainChunkZ(); + Biome biome = region.getChunk(chunkX, chunkZ).getBiomes().getNoiseBiome(0, 0, 0); + SharedSeedRandom sharedseedrandom = new SharedSeedRandom(); + sharedseedrandom.setDecorationSeed(region.getSeed(), chunkX << 4, chunkZ << 4); + WorldEntitySpawner.performWorldGenSpawning(region, biome, chunkX, chunkZ, sharedseedrandom); + } + + @Override + @Name("getSurfaceLevel") + public final int func_222529_a(int x, int z, Heightmap.Type type) { + int level = getTopBlockY(x, z, type) + 1; + if (type == Heightmap.Type.OCEAN_FLOOR || type == Heightmap.Type.OCEAN_FLOOR_WG) { + return level; + } + return Math.max(getGroundHeight(), level); + } + + public final double getSurfaceNoise(int x, int z) { + double scale = 0.0625D; + double noiseX = x * scale; + double noiseZ = z * scale; + double unusedValue1 = scale; + double unusedValue2 = (x & 15) * scale; + return surfaceNoise.noiseAt(noiseX, noiseZ, unusedValue1, unusedValue2); + } + + public abstract int getTopBlockY(int x, int z, Heightmap.Type type); + + public abstract void generateBase(IWorld world, IChunk chunk); + + public abstract void generateSurface(WorldGenRegion world, IChunk chunk); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java new file mode 100644 index 0000000..76d04e9 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java @@ -0,0 +1,366 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.chunk.surface.ChunkSurfaceBuffer; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.chunk.surface.SurfaceManager; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.RegionCache; +import com.terraforged.core.region.RegionGenerator; +import com.terraforged.core.region.Size; +import com.terraforged.core.region.chunk.ChunkReader; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.feature.FeatureManager; +import com.terraforged.feature.matcher.dynamic.DynamicMatcher; +import com.terraforged.feature.matcher.feature.FeatureMatcher; +import com.terraforged.feature.modifier.FeatureModifierLoader; +import com.terraforged.feature.modifier.FeatureModifiers; +import com.terraforged.feature.predicate.DeepWater; +import com.terraforged.feature.predicate.FeaturePredicate; +import com.terraforged.feature.predicate.MinHeight; +import com.terraforged.feature.template.type.FeatureTypes; +import com.terraforged.mod.Log; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.biome.provider.TerraBiomeManager; +import com.terraforged.mod.chunk.fix.ChunkCarverFix; +import com.terraforged.mod.chunk.fix.RegionFix; +import com.terraforged.mod.decorator.ChunkPopulator; +import com.terraforged.mod.decorator.base.BedrockDecorator; +import com.terraforged.mod.decorator.base.CoastDecorator; +import com.terraforged.mod.decorator.base.ErosionDecorator; +import com.terraforged.mod.decorator.base.GeologyDecorator; +import com.terraforged.mod.decorator.feature.LayerDecorator; +import com.terraforged.mod.decorator.feature.SnowEroder; +import com.terraforged.mod.decorator.surface.FrozenOcean; +import com.terraforged.mod.feature.Matchers; +import com.terraforged.mod.feature.TerrainHelper; +import com.terraforged.mod.feature.predicate.TreeLine; +import com.terraforged.mod.material.Materials; +import com.terraforged.mod.material.geology.GeoManager; +import com.terraforged.mod.util.setup.SetupHooks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.IWorld; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeContainer; +import net.minecraft.world.biome.BiomeManager; +import net.minecraft.world.biome.Biomes; +import net.minecraft.world.chunk.ChunkPrimer; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.GenerationSettings; +import net.minecraft.world.gen.GenerationStage; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.WorldGenRegion; +import net.minecraft.world.gen.feature.AbstractTreeFeature; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.template.TemplateManager; + +import java.util.ArrayList; +import java.util.List; + +public class TerraChunkGenerator extends ObfHelperChunkGenerator { + + private final TerraContext context; + private final BiomeProvider biomeProvider; + private final TerrainHelper terrainHelper; + + private final BiomeManager biomeManager; + private final GeoManager geologyManager; + private final FeatureManager featureManager; + private final SurfaceManager surfaceManager; + private final List baseDecorators; + private final List postProcessors; + + private final RegionCache regionCache; + + public TerraChunkGenerator(TerraContext context, BiomeProvider biomeProvider, GenerationSettings settings) { + super(context.world, biomeProvider, settings); + this.context = context; + this.biomeProvider = biomeProvider; + this.surfaceManager = SetupHooks.setup(createSurfaceManager(), context.copy()); + this.geologyManager = SetupHooks.setup(createGeologyManager(context), context.copy()); + this.baseDecorators = createBaseDecorators(context); + this.postProcessors = createFeatureDecorators(context); + this.terrainHelper = new TerrainHelper((int) world.getSeed(), 0.8F); + this.biomeManager = new TerraBiomeManager(biomeProvider, context.world.getSeed()); + this.featureManager = createFeatureManager(context); + this.regionCache = createRegionCache(context); + SetupHooks.setup(getLayerManager(), context.copy()); + SetupHooks.setup(baseDecorators, postProcessors, context.copy()); + } + + @Override + public void generateStructures(BiomeManager unused, IChunk chunk, ChunkGenerator generator, TemplateManager templates) { + super.generateStructures(biomeManager, chunk, this, templates); + } + + @Override + public final void generateBiomes(IChunk chunk) { + ChunkPos pos = chunk.getPos(); + ChunkReader view = getChunkReader(pos.x, pos.z); + BiomeContainer container = getBiomeProvider().createBiomeContainer(view); + ((ChunkPrimer) chunk).func_225548_a_(container); + } + + @Override + public final void generateBase(IWorld world, IChunk chunk) { + DecoratorContext context = new DecoratorContext(chunk, getContext().levels, getContext().terrain, getContext().factory.getClimate()); + TerraContainer container = getBiomeContainer(chunk); + container.getChunkReader().iterate((cell, dx, dz) -> { + int px = context.blockX + dx; + int pz = context.blockZ + dz; + int py = (int) (cell.value * getMaxHeight()); + context.cell = cell; + context.biome = container.getBiome(dx, dz); + ChunkPopulator.INSTANCE.decorate(chunk, context, px, py, pz); + }); + + terrainHelper.flatten(world, chunk, context.blockX, context.blockZ); + } + + @Override + public final void generateSurface(WorldGenRegion world, IChunk chunk) { + ChunkSurfaceBuffer buffer = new ChunkSurfaceBuffer(chunk); + SurfaceContext context = getContext().surface(buffer, getSettings()); + TerraContainer container = getBiomeContainer(chunk); + container.getChunkReader().iterate((cell, dx, dz) -> { + int px = context.blockX + dx; + int pz = context.blockZ + dz; + int top = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, dx, dz) + 1; + + buffer.setSurfaceLevel(top); + + context.cell = cell; + context.biome = container.getBiome(dx, dz); + context.noise = getSurfaceNoise(px, pz) * 15D; + + getSurfaceManager().getSurface(context).buildSurface(px, pz, top, context); + + int py = (int) (cell.value * getMaxHeight()); + for (ColumnDecorator processor : getBaseDecorators()) { + processor.decorate(buffer, context, px, py, pz); + } + }); + } + + @Override + public final void func_225550_a_(BiomeManager biomeManager, IChunk chunk, GenerationStage.Carving carving) { + // World carvers have hardcoded 'carvable' blocks which can be problematic with modded blocks + // AirCarverFix shims the actual blockstates to an equivalent carvable type + super.func_225550_a_(this.biomeManager, new ChunkCarverFix(chunk, context.materials), carving); + } + + @Override + public void decorate(WorldGenRegion region) { + int chunkX = region.getMainChunkX(); + int chunkZ = region.getMainChunkZ(); + IChunk chunk = region.getChunk(chunkX, chunkZ); + TerraContainer container = getBiomeContainer(chunk); + Biome biome = container.getFeatureBiome(); + DecoratorContext context = getContext().decorator(chunk); + + // overrides WorldGenRegion's getSeaLevel() to provide the actual sea level + IWorld regionFix = new RegionFix(region, container, this, biomeManager); + BlockPos pos = new BlockPos(context.blockX, 0, context.blockZ); + + // place biome features + featureManager.decorate(this, regionFix, chunk, biome, pos); + + // run post processors + container.getChunkReader().iterate((cell, dx, dz) -> { + int px = context.blockX + dx; + int pz = context.blockZ + dz; + int py = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, dx, dz); + context.cell = cell; + context.biome = container.getBiome(dx, dz); + for (ColumnDecorator decorator : getPostProcessors()) { + decorator.decorate(chunk, context, px, py, pz); + } + }); + + ((ChunkPrimer) chunk).func_225548_a_(container.bakeBiomes()); + } + + @Override + public int getTopBlockY(int x, int z, Heightmap.Type type) { + int chunkX = Size.blockToChunk(x); + int chunkZ = Size.blockToChunk(z); + ChunkReader chunk = getChunkReader(chunkX, chunkZ); + Cell cell = chunk.getCell(x, z); + return (int) (cell.value * getMaxHeight()); + } + + @Override + public BiomeProvider getBiomeProvider() { + return biomeProvider; + } + + @Override + public final int getMaxHeight() { + return getContext().levels.worldHeight; + } + + @Override + public final int getSeaLevel() { + return getContext().levels.waterLevel; + } + + @Override + public final int getGroundHeight() { + return getContext().levels.groundLevel; + } + + public final TerraContext getContext() { + return context; + } + + public final Materials getMaterials() { + return context.materials; + } + + public final GeoManager getGeologyManager() { + return geologyManager; + } + + public final LayerManager getLayerManager() { + return context.materials.getLayerManager(); + } + + public final SurfaceManager getSurfaceManager() { + return surfaceManager; + } + + public final List getBaseDecorators() { + return baseDecorators; + } + + public final List getPostProcessors() { + return postProcessors; + } + + protected TerraContainer getBiomeContainer(IChunk chunk) { + if (chunk.getBiomes() instanceof TerraContainer) { + return (TerraContainer) chunk.getBiomes(); + } + + ChunkReader view = getChunkReader(chunk.getPos().x, chunk.getPos().z); + TerraContainer container = getBiomeProvider().createBiomeContainer(view); + if (chunk instanceof ChunkPrimer) { + ((ChunkPrimer) chunk).func_225548_a_(container); + } + + return container; + } + + protected FeatureManager createFeatureManager(TerraContext context) { + FeatureModifiers modifiers; + if (context.terraSettings.features.customBiomeFeatures) { + Log.info(" - Custom biome features enabled"); + modifiers = FeatureModifierLoader.load(); + } else { + modifiers = new FeatureModifiers(); + } + + // block ugly features + modifiers.getPredicates().add(Matchers.STONE_BLOBS, FeaturePredicate.DENY); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.DISK), FeaturePredicate.DENY); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.LAKE), FeaturePredicate.DENY); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.SPRING_FEATURE), FeaturePredicate.DENY); + + // limit to deep oceans + modifiers.getPredicates().add(FeatureMatcher.of(Feature.SHIPWRECK), DeepWater.INSTANCE); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.OCEAN_RUIN), DeepWater.INSTANCE); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.OCEAN_MONUMENT), DeepWater.INSTANCE); + + // prevent mineshafts above ground + modifiers.getPredicates().add(FeatureMatcher.of(Feature.MINESHAFT), MinHeight.HEIGHT80); + + // prevent trees/bamboo growing too high up + TreeLine treeLine = new TreeLine(context); + modifiers.getPredicates().add(FeatureTypes.TREE.matcher(), treeLine); + modifiers.getPredicates().add(FeatureMatcher.of(Feature.BAMBOO), treeLine); + modifiers.getDynamic().add(DynamicMatcher.feature(AbstractTreeFeature.class), treeLine); + + return FeatureManager.create(context.world, SetupHooks.setup(modifiers, context.copy())); + } + + protected GeoManager createGeologyManager(TerraContext context) { + return new GeoManager(context); + } + + protected SurfaceManager createSurfaceManager() { + SurfaceManager manager = new SurfaceManager(); + manager.replace(Biomes.FROZEN_OCEAN, new FrozenOcean(context, 20, 15)); + manager.replace(Biomes.DEEP_FROZEN_OCEAN, new FrozenOcean(context, 30, 30)); + return manager; + } + + protected List createBaseDecorators(TerraContext context) { + List processors = new ArrayList<>(); + if (context.terraSettings.features.strataDecorator) { + Log.info(" - Geology decorator enabled"); + processors.add(new GeologyDecorator(geologyManager)); + } + if (context.terraSettings.features.erosionDecorator) { + Log.info(" - Erosion decorator enabled"); + processors.add(new ErosionDecorator(context)); + } + processors.add(new CoastDecorator(context)); + processors.add(new BedrockDecorator()); + return processors; + } + + protected List createFeatureDecorators(TerraContext context) { + List processors = new ArrayList<>(); + if (context.terraSettings.features.naturalSnowDecorator) { + Log.info(" - Natural snow decorator enabled"); + processors.add(new SnowEroder(context)); + } + if (context.terraSettings.features.smoothLayerDecorator) { + Log.info(" - Smooth layer decorator enabled"); + processors.add(new LayerDecorator(context.materials.getLayerManager())); + } + return processors; + } + + protected RegionCache createRegionCache(TerraContext context) { + return RegionGenerator.builder() + .pool(ThreadPool.getFixed()) + .factory(context.factory) + .size(3, 2) + .build() + .toCache(); + } + + public ChunkReader getChunkReader(int chunkX, int chunkZ) { + return regionCache.getChunk(chunkX, chunkZ); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraContainer.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraContainer.java new file mode 100644 index 0000000..37751f9 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraContainer.java @@ -0,0 +1,131 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.api.biome.BiomeVariant; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.chunk.ChunkReader; +import com.terraforged.core.util.PosIterator; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.util.Environment; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeContainer; + +public class TerraContainer extends BiomeContainer { + + private static final int ZOOM_HORIZ = (int) Math.round(Math.log(16.0D) / Math.log(2.0D)) - 2; + private static final int ZOOM_VERT = (int) Math.round(Math.log(256.0D) / Math.log(2.0D)) - 2; + public static final int SIZE = 1 << ZOOM_HORIZ + ZOOM_HORIZ + ZOOM_VERT; + public static final int MASK_HORIZ = (1 << ZOOM_HORIZ) - 1; + public static final int MASK_VERT = (1 << ZOOM_VERT) - 1; + + private final Biome[] biomes; + private final Biome[] surface; + private final ChunkReader chunkReader; + + public TerraContainer(Builder builder, ChunkReader chunkReader) { + super(builder.biomes); + this.chunkReader = chunkReader; + this.biomes = builder.biomes; + this.surface = builder.surfaceBiomeCache; + } + + public Biome getBiome(int x, int z) { + return surface[indexOf(x, z)]; + } + + @Override + public Biome getNoiseBiome(int x, int y, int z) { + return super.getNoiseBiome(x, y, z); + } + + public Biome getFeatureBiome() { + PosIterator iterator = PosIterator.area(0, 0, 16, 16); + while (iterator.next()) { + Cell cell = chunkReader.getCell(iterator.x(), iterator.z()); + if (cell.biomeType.isExtreme()) { + return getBiome(iterator.x(), iterator.z()); + } + } + return getBiome(8, 8); + } + + public BiomeContainer bakeBiomes() { + if (Environment.isDev()) { + for (int i = 0; i < biomes.length; i++) { + Biome biome = biomes[i]; + if (biome instanceof BiomeVariant) { + biomes[i] = ((BiomeVariant) biome).getBase(); + } + } + } + return new BiomeContainer(biomes); + } + + public ChunkReader getChunkReader() { + return chunkReader; + } + + private static int indexOf(int x, int z) { + x &= 15; + z &= 15; + return (z << 4) + x; + } + + private static int indexOf(int x, int y, int z) { + int bx = x & MASK_HORIZ; + int by = MathHelper.clamp(y, 0, MASK_VERT); + int bz = z & MASK_HORIZ; + return by << ZOOM_HORIZ + ZOOM_HORIZ | bz << ZOOM_HORIZ | bx; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final Biome[] biomes = new Biome[SIZE]; + private final Biome[] surfaceBiomeCache = new Biome[256]; + + public void set(int x, int y, int z, Biome biome) { + biomes[indexOf(x, y, z)] = biome; + + surfaceBiomeCache[indexOf(x, z)] = biome; + } + + public void fill(int x, int z, Biome biome) { + for (int y = 0; y < 64; y++) { + set(x, y, z, biome); + } + } + + public TerraContainer build(ChunkReader chunkReader) { + return new TerraContainer(this, chunkReader); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraContext.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraContext.java new file mode 100644 index 0000000..1e5c41b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraContext.java @@ -0,0 +1,68 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.WorldGeneratorFactory; +import com.terraforged.core.world.heightmap.Heightmap; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.material.Materials; +import com.terraforged.mod.settings.TerraSettings; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.world.IWorld; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.GenerationSettings; + +public class TerraContext extends GeneratorContext { + + public final IWorld world; + public final Heightmap heightmap; + public final Materials materials; + public final WorldGeneratorFactory factory; + public final TerraSettings terraSettings; + + public TerraContext(IWorld world, Terrains terrain, TerraSettings settings) { + super(terrain, settings, TerraTerrainProvider::new); + this.world = world; + this.materials = new Materials(); + this.terraSettings = settings; + this.factory = new WorldGeneratorFactory(this); + this.heightmap = factory.getHeightmap(); + ItemStack stack = new ItemStack(Items.COBBLESTONE); + stack.getMaxStackSize(); + } + + public DecoratorContext decorator(IChunk chunk) { + return new DecoratorContext(chunk, levels, terrain, factory.getClimate()); + } + + public SurfaceContext surface(IChunk chunk, GenerationSettings settings) { + return new SurfaceContext(chunk, levels, terrain, factory.getClimate(), settings, world.getSeed()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraGenSettings.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraGenSettings.java new file mode 100644 index 0000000..6782bc5 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraGenSettings.java @@ -0,0 +1,41 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.mod.settings.StructureSettings; +import net.minecraft.world.gen.OverworldGenSettings; + +public class TerraGenSettings extends OverworldGenSettings { + + public TerraGenSettings(StructureSettings settings) { + super.villageDistance *= settings.villageDistance; + super.mansionDistance *= settings.mansionDistance; + super.strongholdDistance *= settings.strongholdDistance; + super.biomeFeatureDistance *= settings.biomeStructureDistance; + super.oceanMonumentSpacing *= settings.oceanMonumentSpacing; + super.oceanMonumentSeparation *= settings.oceanMonumentSeparation; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraTerrainProvider.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraTerrainProvider.java new file mode 100644 index 0000000..a6365df --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraTerrainProvider.java @@ -0,0 +1,45 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk; + +import com.terraforged.core.cell.Populator; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.heightmap.RegionConfig; +import com.terraforged.core.world.terrain.provider.StandardTerrainProvider; +import com.terraforged.mod.util.setup.SetupHooks; + +public class TerraTerrainProvider extends StandardTerrainProvider { + + public TerraTerrainProvider(GeneratorContext context, RegionConfig config, Populator defaultPopulator) { + super(context, config, defaultPopulator); + } + + @Override + public void init() { + super.init(); + SetupHooks.setup(this, getContext().copy()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/fix/ChunkCarverFix.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/fix/ChunkCarverFix.java new file mode 100644 index 0000000..dc12300 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/fix/ChunkCarverFix.java @@ -0,0 +1,74 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.fix; + +import com.terraforged.api.chunk.ChunkDelegate; +import com.terraforged.api.material.state.States; +import com.terraforged.mod.material.MaterialHelper; +import com.terraforged.mod.material.Materials; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.IChunk; + +public class ChunkCarverFix implements ChunkDelegate { + + private final IChunk delegate; + private final Materials materials; + + public ChunkCarverFix(IChunk chunk, Materials materials) { + this.delegate = chunk; + this.materials = materials; + } + + @Override + public IChunk getDelegate() { + return delegate; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + BlockState state = getDelegate().getBlockState(pos); + if (MaterialHelper.isAir(state.getBlock())) { + return state; + } + if (MaterialHelper.isGrass(state.getBlock())) { + return States.GRASS_BLOCK.get(); + } + if (materials.isStone(state.getBlock())) { + return States.STONE.get(); + } + if (materials.isEarth(state.getBlock())) { + return States.DIRT.get(); + } + if (materials.isClay(state.getBlock())) { + return States.DIRT.get(); + } + if (materials.isSediment(state.getBlock())) { + return States.SAND.get(); + } + return state; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/fix/RegionFix.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/fix/RegionFix.java new file mode 100644 index 0000000..9ba2e19 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/fix/RegionFix.java @@ -0,0 +1,109 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.fix; + +import com.terraforged.feature.util.WorldDelegate; +import com.terraforged.mod.chunk.TerraContainer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.BiomeContainer; +import net.minecraft.world.biome.BiomeManager; +import net.minecraft.world.chunk.ChunkStatus; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.WorldGenRegion; + +public class RegionFix extends WorldDelegate { + + private final WorldGenRegion region; + private final TerraContainer container; + private final BiomeManager biomeManager; + private final ChunkGenerator generator; + + public RegionFix(WorldGenRegion region, TerraContainer container, ChunkGenerator generator, BiomeManager biomeManager) { + super(region); + this.region = region; + this.container = container; + this.generator = generator; + this.biomeManager = biomeManager; + } + + @Override + public int getSeaLevel() { + return generator.getSeaLevel(); + } + + @Override + public int getMaxHeight() { + return generator.getMaxHeight(); + } + + @Override + public BiomeManager func_225523_d_() { + return biomeManager; + } + + @Override + public Biome getNoiseBiome(int x, int y, int z) { + return getBiome(x, y, z); + } + + @Override + public Biome getNoiseBiomeRaw(int x, int y, int z) { + return getBiome(x, y, z); + } + + @Override + public Biome getBiome(BlockPos pos) { + return getBiome(pos.getX(), pos.getY(), pos.getZ()); + } + + private Biome getBiome(int x, int y, int z) { + int chunkX = x >> 4; + int chunkZ = z >> 4; + if (chunkX == region.getMainChunkX() && chunkZ == region.getMainChunkZ()) { + return container.getBiome(x, z); + } + + TerraContainer container = getBiomes(chunkX, chunkZ); + if (container == null) { + return generator.getBiomeProvider().getNoiseBiome(x, y, z); + } + + return container.getBiome(x, z); + } + + private TerraContainer getBiomes(int chunkX, int chunkZ) { + IChunk chunk = getChunk(chunkX, chunkZ, ChunkStatus.BIOMES, false); + if (chunk != null) { + BiomeContainer container = chunk.getBiomes(); + if (container instanceof TerraContainer) { + return (TerraContainer) container; + } + } + return null; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/Test.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/Test.java new file mode 100644 index 0000000..9e2e018 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/Test.java @@ -0,0 +1,44 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.test; + +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.Biomes; + +public class Test { + + public static boolean fixedBiome = true; + + public static Terrain getTerrainType(Terrains terrains) { + return terrains.steppe; + } + + public static Biome getBiome() { + return Biomes.DESERT; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/TestBiomeProvider.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/TestBiomeProvider.java new file mode 100644 index 0000000..c56de43 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/TestBiomeProvider.java @@ -0,0 +1,48 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.test; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.ModBiomes; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.biome.Biome; + +public class TestBiomeProvider extends BiomeProvider { + + public TestBiomeProvider(TerraContext chunkContext) { + super(chunkContext); + } + + @Override + public Biome getBiome(Cell cell, int x, int z) { + if (cell.biome < 0.5F) { + return ModBiomes.TAIGA_SCRUB; + } + return Test.getBiome(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/TestChunkGenerator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/TestChunkGenerator.java new file mode 100644 index 0000000..f33a581 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/test/TestChunkGenerator.java @@ -0,0 +1,87 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.chunk.test; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.cell.Populator; +import com.terraforged.core.region.RegionCache; +import com.terraforged.core.region.RegionGenerator; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.WorldGeneratorFactory; +import com.terraforged.core.world.heightmap.WorldHeightmap; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.TerraChunkGenerator; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.gen.GenerationSettings; + +public class TestChunkGenerator extends TerraChunkGenerator { + + private final BiomeProvider biomeProvider; + + public TestChunkGenerator(TerraContext context, BiomeProvider biomeProvider, GenerationSettings settings) { + super(context, biomeProvider, settings); + this.biomeProvider = new TestBiomeProvider(context); + } + + @Override + protected RegionCache createRegionCache(TerraContext context) { + return RegionGenerator.builder() + .factory(new WorldGeneratorFactory(context, new TestHeightMap(context))) + .pool(ThreadPool.getFixed()) + .size(3, 2) + .build() + .toCache(true); + } + + @Override + public BiomeProvider getBiomeProvider() { + return biomeProvider; + } + + private static class TestHeightMap extends WorldHeightmap { + + private final Populator populator; + + public TestHeightMap(GeneratorContext context) { + super(context); + this.populator = getPopulator(Test.getTerrainType(context.terrain)); + } + + @Override + public void apply(Cell cell, float x, float y) { + super.apply(cell, x, y); + + populator.apply(cell, x, y); + } + + @Override + public void tag(Cell cell, float x, float y) { + populator.tag(cell, x, y); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/TerraCommand.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/TerraCommand.java new file mode 100644 index 0000000..3065f29 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/TerraCommand.java @@ -0,0 +1,256 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.WorldGenerator; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.Log; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.chunk.TerraChunkGenerator; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.command.arg.BiomeArgType; +import com.terraforged.mod.command.arg.TerrainArgType; +import com.terraforged.mod.command.task.FindBiomeTask; +import com.terraforged.mod.command.task.FindBothTask; +import com.terraforged.mod.command.task.FindTask; +import com.terraforged.mod.command.task.FindTerrainTask; +import com.terraforged.mod.data.DataGen; +import me.dags.noise.util.Vec2i; +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextComponentUtils; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.util.text.event.ClickEvent; +import net.minecraft.util.text.event.HoverEvent; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.server.FMLServerStartingEvent; + +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) +public class TerraCommand { + + @SubscribeEvent + public static void start(FMLServerStartingEvent event) { + Log.info("Registering find command!"); + register(event.getCommandDispatcher()); + } + + public static void register(CommandDispatcher dispatcher) { + dispatcher.register(command()); + } + + private static LiteralArgumentBuilder command() { + return Commands.literal("terra") + .requires(source -> source.hasPermissionLevel(2)) + .then(Commands.literal("query") + .executes(TerraCommand::query)) + .then(Commands.literal("data") + .then(Commands.literal("dump") + .executes(TerraCommand::dump))) + .then(Commands.literal("locate") + .then(Commands.argument("biome", BiomeArgType.biome()) + .executes(TerraCommand::findBiome) + .then(Commands.argument("terrain", TerrainArgType.terrain()) + .executes(TerraCommand::findTerrainAndBiome))) + .then(Commands.argument("terrain", TerrainArgType.terrain()) + .executes(TerraCommand::findTerrain) + .then(Commands.argument("biome", BiomeArgType.biome()) + .executes(TerraCommand::findTerrainAndBiome)))); + } + + private static int query(CommandContext context) throws CommandSyntaxException { + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + BlockPos pos = context.getSource().asPlayer().getPosition(); + WorldGenerator worldGenerator = terraContext.factory.get(); + BiomeProvider biomeProvider = getBiomeProvider(context); + Cell cell = new Cell<>(); + worldGenerator.getHeightmap().apply(cell, pos.getX(), pos.getZ()); + Biome biome = biomeProvider.getBiome(cell, pos.getX(), pos.getZ()); + context.getSource().sendFeedback( + new StringTextComponent("Terrain=" + cell.tag.getName() + ", Biome=" + biome.getRegistryName()), + false + ); + + return Command.SINGLE_SUCCESS; + } + + private static int dump(CommandContext context) throws CommandSyntaxException { + context.getSource().sendFeedback( + new StringTextComponent("Exporting data"), + true + ); + DataGen.dumpData(); + return Command.SINGLE_SUCCESS; + } + + private static int findTerrain(CommandContext context) throws CommandSyntaxException { + // get the generator's context + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + Terrain terrain = TerrainArgType.getTerrain(context, "terrain"); + Terrain target = getTerrainInstance(terrain, terraContext.terrain); + BlockPos pos = context.getSource().asPlayer().getPosition(); + UUID playerID = context.getSource().asPlayer().getUniqueID(); + MinecraftServer server = context.getSource().getServer(); + WorldGenerator worldGenerator = terraContext.factory.get(); + FindTask task = new FindTerrainTask(pos, target, worldGenerator); + doSearch(server, playerID, task); + context.getSource().sendFeedback(new StringTextComponent("Searching..."), false); + + return Command.SINGLE_SUCCESS; + } + + private static int findBiome(CommandContext context) throws CommandSyntaxException { + // get the generator's context + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + Biome biome = BiomeArgType.getBiome(context, "biome"); + BlockPos pos = context.getSource().asPlayer().getPosition(); + UUID playerID = context.getSource().asPlayer().getUniqueID(); + MinecraftServer server = context.getSource().getServer(); + WorldGenerator worldGenerator = terraContext.factory.get(); + BiomeProvider biomeProvider = getBiomeProvider(context); + FindTask task = new FindBiomeTask(pos, biome, worldGenerator, biomeProvider); + doSearch(server, playerID, task); + context.getSource().sendFeedback(new StringTextComponent("Searching..."), false); + + return Command.SINGLE_SUCCESS; + } + + private static int findTerrainAndBiome(CommandContext context) throws CommandSyntaxException { + // get the generator's context + TerraContext terraContext = getContext(context).orElseThrow(() -> createException( + "Invalid world type", + "This command can only be run in a TerraForged world!" + )); + + Terrain terrain = TerrainArgType.getTerrain(context, "terrain"); + Terrain target = getTerrainInstance(terrain, terraContext.terrain); + Biome biome = BiomeArgType.getBiome(context, "biome"); + BlockPos pos = context.getSource().asPlayer().getPosition(); + UUID playerID = context.getSource().asPlayer().getUniqueID(); + MinecraftServer server = context.getSource().getServer(); + WorldGenerator worldGenerator = terraContext.factory.get(); + BiomeProvider biomeProvider = getBiomeProvider(context); + FindTask task = new FindBothTask(pos, target, biome, worldGenerator, biomeProvider); + doSearch(server, playerID, task); + context.getSource().sendFeedback(new StringTextComponent("Searching..."), false); + + return Command.SINGLE_SUCCESS; + } + + private static void doSearch(MinecraftServer server, UUID userId, FindTask task) { + CompletableFuture.supplyAsync(task).thenAccept(pos -> server.deferTask(() -> { + PlayerEntity player = server.getPlayerList().getPlayerByUUID(userId); + if (player == null) { + return; + } + + if (pos.x == 0 && pos.y == 0) { + player.sendMessage(new StringTextComponent("Location not found :[")); + return; + } + + ITextComponent result = new StringTextComponent("Nearest match: ") + .appendSibling(createTeleportMessage(pos)); + + player.sendMessage(result); + })); + } + + private static Optional getContext(CommandContext context) throws CommandSyntaxException { + MinecraftServer server = context.getSource().getServer(); + DimensionType dimension = context.getSource().asPlayer().dimension; + ChunkGenerator generator = server.getWorld(dimension).getChunkProvider().getChunkGenerator(); + if (generator instanceof TerraChunkGenerator) { + TerraChunkGenerator gen = (TerraChunkGenerator) generator; + return Optional.of(gen.getContext()); + } + return Optional.empty(); + } + + // the terrain parsed from the command will not be the same instance as used in the + // world generator, so find the matching instance by name + private static Terrain getTerrainInstance(Terrain find, Terrains terrains) { + for (Terrain t : terrains.index) { + if (t.getName().equals(find.getName())) { + return t; + } + } + return find; + } + + private static BiomeProvider getBiomeProvider(CommandContext context) { + return (BiomeProvider) context.getSource().getWorld().getChunkProvider().getChunkGenerator().getBiomeProvider(); + } + + private static CommandSyntaxException createException(String type, String message, Object... args) { + return new CommandSyntaxException( + new SimpleCommandExceptionType(new StringTextComponent(type)), + new StringTextComponent(String.format(message, args)) + ); + } + + private static ITextComponent createTeleportMessage(Vec2i pos) { + return TextComponentUtils.wrapInSquareBrackets(new TranslationTextComponent( + "chat.coordinates", pos.x, "~", pos.y + )).applyTextStyle((style) -> style.setColor(TextFormatting.GREEN) + .setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tp @s " + pos.x + " ~ " + pos.y)) + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslationTextComponent("chat.coordinates.tooltip"))) + ); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/arg/BiomeArgType.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/arg/BiomeArgType.java new file mode 100644 index 0000000..10a3b54 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/arg/BiomeArgType.java @@ -0,0 +1,72 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.arg; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.command.ISuggestionProvider; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.world.biome.Biome; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.concurrent.CompletableFuture; + +public class BiomeArgType implements ArgumentType { + + @Override + public Biome parse(StringReader reader) throws CommandSyntaxException { + ResourceLocation resourcelocation = ResourceLocation.read(reader); + return Registry.BIOME.getValue(resourcelocation) + .orElseThrow(() -> createException("Invalid biome", "%s is not a valid biome", resourcelocation)); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder suggestions) { + return ISuggestionProvider.func_212476_a(ForgeRegistries.BIOMES.getValues().stream().map(Biome::getRegistryName), suggestions); + } + + private static CommandSyntaxException createException(String type, String message, Object... args) { + return new CommandSyntaxException( + new SimpleCommandExceptionType(new StringTextComponent(type)), + new StringTextComponent(String.format(message, args)) + ); + } + + public static ArgumentType biome() { + return new BiomeArgType(); + } + + public static Biome getBiome(CommandContext context, String name) { + return context.getArgument(name, Biome.class); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/arg/TerrainArgType.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/arg/TerrainArgType.java new file mode 100644 index 0000000..77a4c50 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/arg/TerrainArgType.java @@ -0,0 +1,117 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.arg; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import com.terraforged.core.settings.Settings; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import net.minecraft.command.ISuggestionProvider; +import net.minecraft.util.text.StringTextComponent; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +public class TerrainArgType implements ArgumentType { + + private final List terrains = getTerrains(); + + @Override + public Terrain parse(StringReader reader) throws CommandSyntaxException { + int cursor = reader.getCursor(); + String name = reader.readString(); + for (Terrain terrain : terrains) { + if (terrain.getName().equalsIgnoreCase(name)) { + return terrain; + } + } + reader.setCursor(cursor); + throw createException("Invalid terrain", "%s is not a valid terrain type", name); + } + + @Override + public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder suggestions) { + return ISuggestionProvider.suggest(terrains.stream().map(Terrain::getName).collect(Collectors.toList()), suggestions); + } + + public static ArgumentType terrain() { + return new TerrainArgType(); + } + + public static Terrain getTerrain(CommandContext context, String name) { + return context.getArgument(name, Terrain.class); + } + + private static CommandSyntaxException createException(String type, String message, Object... args) { + return new CommandSyntaxException( + new SimpleCommandExceptionType(new StringTextComponent(type)), + new StringTextComponent(String.format(message, args)) + ); + } + + private static List getTerrains() { + Terrains terrains = Terrains.create(new Settings()); + List result = new ArrayList<>(); + + for (int i = 0; i < terrains.index.size(); i++) { + Terrain terrain = terrains.index.get(i); + result.add(terrain); + if (dontMix(terrain, terrains)) { + continue; + } + for (int j = i + 1; j < terrains.index.size(); j++) { + Terrain other = terrains.index.get(j); + if (dontMix(other, terrains)) { + continue; + } + Terrain mix = new Terrain(terrain.getName() + "-" + other.getName(), -1); + result.add(mix); + } + } + + return result; + } + + private static boolean dontMix(Terrain terrain, Terrains terrains) { + return terrain == terrains.ocean + || terrain == terrains.deepOcean + || terrain == terrains.river + || terrain == terrains.riverBanks + || terrain == terrains.beach + || terrain == terrains.coast + || terrain == terrains.volcano + || terrain == terrains.volcanoPipe + || terrain == terrains.lake; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindBiomeTask.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindBiomeTask.java new file mode 100644 index 0000000..88ed423 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindBiomeTask.java @@ -0,0 +1,80 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.task; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.WorldGenerator; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.BiomeProvider; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; + +public class FindBiomeTask extends FindTask { + + private final Biome biome; + private final WorldGenerator generator; + private final BiomeProvider biomeProvider; + private final Cell cell = new Cell<>(); + + public FindBiomeTask(BlockPos center, Biome biome, WorldGenerator generator, BiomeProvider biomeProvider) { + this(center, biome, generator, biomeProvider, 100); + } + + public FindBiomeTask(BlockPos center, Biome biome, WorldGenerator generator, BiomeProvider biomeProvider, int minRadius) { + super(center, minRadius); + this.biome = biome; + this.generator = generator; + this.biomeProvider = biomeProvider; + } + + @Override + protected int transformCoord(int coord) { + return coord * 8; + } + + @Override + protected boolean search(int x, int z) { + generator.getHeightmap().apply(cell, x, z); + + if (biome.getCategory() != Biome.Category.BEACH && biome.getCategory() != Biome.Category.OCEAN) { + if (cell.continentEdge > 0.4 && cell.continentEdge < 0.5) { + return false; + } + } + + return biomeProvider.getBiome(cell, x, z) == biome; + } + + protected boolean test(Cell cell, int x, int z) { + if (biome.getCategory() != Biome.Category.BEACH && biome.getCategory() != Biome.Category.OCEAN) { + if (cell.continentEdge > 0.4 && cell.continentEdge < 0.5) { + return false; + } + } + + return biomeProvider.getBiome(cell, x, z) == biome; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindBothTask.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindBothTask.java new file mode 100644 index 0000000..fda554b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindBothTask.java @@ -0,0 +1,57 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.task; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.WorldGenerator; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.biome.provider.BiomeProvider; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; + +public class FindBothTask extends FindBiomeTask { + + private final Terrain type; + private final WorldGenerator generator; + private final Cell cell = new Cell<>(); + + public FindBothTask(BlockPos center, Terrain terrain, Biome biome, WorldGenerator generator, BiomeProvider biomeProvider) { + super(center, biome, generator, biomeProvider, 300); + this.type = terrain; + this.generator = generator; + } + + @Override + protected boolean search(int x, int z) { + generator.getHeightmap().apply(cell, x, z); + return test(cell, x , z) && super.test(cell, x, z); + } + + @Override + protected boolean test(Cell cell, int x, int z) { + return cell.continentEdge > 0.5 && cell.regionEdge > 0.8F && cell.tag == type; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindTask.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindTask.java new file mode 100644 index 0000000..4ffa070 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindTask.java @@ -0,0 +1,109 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.task; + +import me.dags.noise.util.Vec2i; +import net.minecraft.util.math.BlockPos; + +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; + +public abstract class FindTask implements Supplier { + + private static final int RADIUS = 5000; + + private final BlockPos center; + private final int minRadius; + + private final long timeout; + + protected FindTask(BlockPos center, int minRadius) { + this.center = center; + this.minRadius = minRadius; + this.timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(20); + } + + @Override + public Vec2i get() { + try { + int x = 0; + int y = 0; + int dx = 0; + int dy = -1; + int radius = RADIUS; + int size = radius + 1 + radius; + int max = size * size; + + int minSize = minRadius + 1 + minRadius; + int min = minSize * minSize; + + for (int i = 0; i < max; i++) { + if (i % 100 == 0) { + if (System.currentTimeMillis() > timeout) { + break; + } + } + + if ((-radius <= x) && (x <= radius) && (-radius <= y) && (y <= radius)) { + int distX = transformCoord(x); + int distY = transformCoord(y); + int dist2 = distX * distX + distY * distY; + if (dist2 > min) { + int posX = center.getX() + distX; + int posZ = center.getZ() + distY; + if (search(posX, posZ)) { + return new Vec2i(posX, posZ); + } + } + } + + if ((x == y) || ((x < 0) && (x == -y)) || ((x > 0) && (x == 1 - y))) { + size = dx; + dx = -dy; + dy = size; + } + + x += dx; + y += dy; + } + return new Vec2i(0, 0); + } catch (Throwable t) { + t.printStackTrace(); + return new Vec2i(0, 0); + } + } + + protected abstract int transformCoord(int coord); + + /** + * Performs the search at the given x,z coordinates and returns true if a result is found + * + * @param x the x block coordinate + * @param z the z block coordinate + * @return the search result + */ + protected abstract boolean search(int x, int z); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindTerrainTask.java b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindTerrainTask.java new file mode 100644 index 0000000..33316ca --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/command/task/FindTerrainTask.java @@ -0,0 +1,59 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.command.task; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.WorldGenerator; +import com.terraforged.core.world.terrain.Terrain; +import net.minecraft.util.math.BlockPos; + +public class FindTerrainTask extends FindTask { + + private final Terrain type; + private final WorldGenerator generator; + private final Cell cell = new Cell<>(); + + public FindTerrainTask(BlockPos center, Terrain type, WorldGenerator generator) { + super(center, 300); + this.type = type; + this.generator = generator; + } + + @Override + protected int transformCoord(int coord) { + return coord * 64; + } + + @Override + protected boolean search(int x, int z) { + generator.getHeightmap().apply(cell, x, z); + return test(cell); + } + + protected boolean test(Cell cell) { + return cell.continentEdge > 0.5 && cell.regionEdge > 0.8F && cell.tag == type; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/data/DataGen.java b/TerraForgedMod/src/main/java/com/terraforged/mod/data/DataGen.java new file mode 100644 index 0000000..881b3f3 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/data/DataGen.java @@ -0,0 +1,72 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import net.minecraft.util.ResourceLocation; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; + +public class DataGen { + + public static void dumpData() { + File dataDir = new File("data"); + WorldGenBiomes.genBiomeMap(dataDir); + WorldGenBlocks.genBlockTags(dataDir); + WorldGenFeatures.genBiomeFeatures(dataDir); + } + + protected static void write(File file, IOConsumer consumer) { + if (file.getParentFile().exists() || file.getParentFile().mkdirs()) { + try (Writer writer = new BufferedWriter(new FileWriter(file))) { + consumer.accept(writer); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + protected static void write(JsonElement json, Writer writer) { + new GsonBuilder().setPrettyPrinting().create().toJson(json, writer); + } + + protected static String getJsonPath(String type, ResourceLocation location) { + if (location == null) { + return "unknown"; + } + return location.getNamespace() + "/" + type + "/" + location.getPath() + ".json"; + } + + public interface IOConsumer { + + void accept(Writer writer) throws IOException; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenBiomes.java b/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenBiomes.java new file mode 100644 index 0000000..d618592 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenBiomes.java @@ -0,0 +1,71 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.core.world.biome.BiomeType; +import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.provider.BiomeHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.biome.Biome; + +import java.io.File; +import java.util.Set; + +public class WorldGenBiomes extends DataGen { + + public static void genBiomeMap(File dataDir) { + BiomeMap map = BiomeHelper.getDefaultBiomeMap(); + for (BiomeType type : BiomeType.values()) { + genBiomes(dataDir, type, map); + } + } + + private static void genBiomes(File dir, BiomeType type, BiomeMap map) { + String path = getJsonPath("tags/biomes", getName(type)); + + write(new File(dir, path), writer -> { + Set biomes = map.getBiomes(type); + JsonObject root = new JsonObject(); + JsonArray values = new JsonArray(); + + root.addProperty("replaceable", false); + root.add("values", values); + + biomes.stream() + .map(b -> b.getRegistryName() + "") + .sorted() + .forEach(values::add); + + write(root, writer); + }); + } + + private static ResourceLocation getName(BiomeType type) { + return new ResourceLocation("terraforged", type.name().toLowerCase()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenBlocks.java b/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenBlocks.java new file mode 100644 index 0000000..e101bc4 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenBlocks.java @@ -0,0 +1,63 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.terraforged.mod.material.Materials; +import net.minecraft.block.Block; +import net.minecraft.util.ResourceLocation; + +import java.io.File; +import java.util.Collection; + +public class WorldGenBlocks extends DataGen { + + public static void genBlockTags(File dataDir) { + if (dataDir.exists() || dataDir.mkdirs()) { + Materials materials = new Materials(); + printMaterials(dataDir, "stone", materials.getStone()); + printMaterials(dataDir, "dirt", materials.getDirt()); + printMaterials(dataDir, "clay", materials.getClay()); + printMaterials(dataDir, "sediment",materials.getSediment()); + printMaterials(dataDir, "ore", materials.getOre()); + } + } + + private static void printMaterials(File dir, String name, Collection blocks) { + String path = getJsonPath("tags/blocks", new ResourceLocation("terraforged", name)); + write(new File(dir, path), writer -> { + JsonObject root = new JsonObject(); + JsonArray values = new JsonArray(); + root.addProperty("replace", false); + root.add("values", values); + for (Block block : blocks) { + values.add("" + block.getRegistryName()); + } + write(root, writer); + }); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenFeatures.java b/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenFeatures.java new file mode 100644 index 0000000..cbe327b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/data/WorldGenFeatures.java @@ -0,0 +1,68 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.data; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.JsonOps; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.GenerationStage; +import net.minecraft.world.gen.feature.ConfiguredFeature; +import net.minecraftforge.registries.ForgeRegistries; + +import java.io.File; + +public class WorldGenFeatures extends DataGen { + + public static void genBiomeFeatures(File dataDir) { + if (dataDir.exists() || dataDir.mkdirs()) { + for (Biome biome : ForgeRegistries.BIOMES) { + genBiomeFeatures(dataDir, biome); + } + } + } + + private static void genBiomeFeatures(File dir, Biome biome) { + write(new File(dir, getJsonPath("features", biome.getRegistryName())), writer -> { + JsonObject root = new JsonObject(); + for (GenerationStage.Decoration type : GenerationStage.Decoration.values()) { + JsonArray features = new JsonArray(); + for (ConfiguredFeature feature : biome.getFeatures(type)) { + try { + Dynamic dynamic = feature.serialize(JsonOps.INSTANCE); + features.add(dynamic.getValue()); + } catch (NullPointerException e) { + new NullPointerException("Badly written feature: " + feature.feature.getRegistryName()).printStackTrace(); + } + } + root.add(type.getName(), features); + } + write(root, writer); + }); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/ChunkPopulator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/ChunkPopulator.java new file mode 100644 index 0000000..87e826f --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/ChunkPopulator.java @@ -0,0 +1,49 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import net.minecraft.world.chunk.IChunk; + +public class ChunkPopulator implements ColumnDecorator { + + public static final ChunkPopulator INSTANCE = new ChunkPopulator(); + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.tag == context.terrains.volcanoPipe && context.cell.riverMask > 0.25F) { + int lavaStart = Math.max(context.levels.waterY + 10, y - 30); + int lavaEnd = Math.max(5, context.levels.waterY - 10); + fillDown(context, chunk, x, z, lavaStart, lavaEnd, States.LAVA.get()); + y = lavaEnd; + } else if (y < context.levels.waterLevel) { + fillDown(context, chunk, x, z, context.levels.waterY, y, States.WATER.get()); + } + fillDown(context, chunk, x, z, y, 0, States.STONE.get()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/BedrockDecorator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/BedrockDecorator.java new file mode 100644 index 0000000..b5e03cf --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/BedrockDecorator.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import net.minecraft.world.chunk.IChunk; + +import java.util.Random; + +public class BedrockDecorator implements ColumnDecorator { + + private final Random random = new Random(); + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + fillDown(context, chunk, x, z, 1 + random.nextInt(4), -1, States.BEDROCK.get()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/CoastDecorator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/CoastDecorator.java new file mode 100644 index 0000000..686d4b8 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/CoastDecorator.java @@ -0,0 +1,76 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.util.VariablePredicate; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.IChunk; + +public class CoastDecorator implements ColumnDecorator { + + private final Terrains terrains; + private final BlockState sand; + private final BlockState gravel; + private final VariablePredicate height; + + public CoastDecorator(TerraContext context) { + int min = context.levels.waterLevel - 5; + int max = context.levels.waterLevel + 16; + sand = States.SAND.get(); + gravel = States.GRAVEL.get(); + terrains = context.terrain; + height = VariablePredicate.height( + context.seed, + context.levels, + min, + max, + 75, + 1 + ); + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.tag != terrains.beach) { + return; + } + + if (!height.test(context.cell, x, z)) { + return; + } + + if (context.cell.temperature < 0.3F) { + setState(chunk, x, y, z, gravel, false); + } else { + setState(chunk, x, y, z, sand, false); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/ErosionDecorator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/ErosionDecorator.java new file mode 100644 index 0000000..cd59f52 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/ErosionDecorator.java @@ -0,0 +1,193 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.material.Materials; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.material.Material; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.surfacebuilders.ISurfaceBuilderConfig; + +public class ErosionDecorator implements ColumnDecorator { + + private static final int ROCK_VAR = 30; + private static final int ROCK_MIN = 140; + + private static final int DIRT_VAR = 40; + private static final int DIRT_MIN = 95; + + public static final float ROCK_STEEPNESS = 0.65F; + private static final float DIRT_STEEPNESS = 0.475F; + private static final float SCREE_STEEPNESS = 0.4F; + + public static final float HEIGHT_MODIFIER = 6F / 255F; + public static final float SLOPE_MODIFIER = 3F / 255F; + + private static final float SEDIMENT_MODIFIER = 256; + private static final float SEDIMENT_NOISE = 3F / 255F; + private static final float SCREE_VALUE = 0.55F; + + private final int seed1; + private final int seed2; + private final int seed3; + private final float minY; + private final Terrains terrain; + private final Materials materials; + + public ErosionDecorator(TerraContext context) { + this.terrain = context.terrain; + this.seed1 = context.seed.next(); + this.seed2 = context.seed.next(); + this.seed3 = context.seed.next(); + this.minY = context.levels.ground(4); + this.materials = context.materials; + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.value < minY || context.cell.tag == terrain.river || context.cell.tag == terrain.riverBanks) { + return; + } + + if (context.cell.tag == terrain.volcanoPipe) { + return; + } + + int topY = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, x, z); + if (topY - 1 > y) { + y = topY; + } + + ISurfaceBuilderConfig config = context.biome.getSurfaceBuilderConfig(); + BlockState top = config.getTop(); + BlockState middle = config.getUnder(); + + if (materials.isErodible(top.getBlock())) { + BlockState material = getMaterial(x, z, context, top, middle); + if (material != top) { + if (materials.isStone(material.getBlock())) { + erodeRock(context, chunk, x, y, z); + return; + } else { + fillDown(context, chunk, x, z, y, y - 4, material); + } + } + placeScree(chunk, context, x, y, z); + } + } + + protected void erodeRock(DecoratorContext context, IChunk chunk, int dx, int y, int dz) { + int depth = 32; + BlockState material = Blocks.GRAVEL.getDefaultState(); + // find the uppermost layer of rock & record it's depth + for (int dy = 3; dy < 32; dy++) { + context.pos.setY(y - dy); + BlockState state = chunk.getBlockState(context.pos); + if (materials.isStone(state.getBlock())) { + material = state; + depth = dy + 1; + break; + } + } + + // fill downwards to the first rock layer + for (int dy = 0; dy < depth; dy++) { + context.pos.setY(y - dy); + chunk.setBlockState(context.pos, material, false); + } + } + + protected void placeScree(IChunk chunk, DecoratorContext context, int x, int y, int z) { + float steepness = context.cell.steepness + context.climate.getRand().getValue(x, z, seed2) * SLOPE_MODIFIER; + if (steepness < SCREE_STEEPNESS) { + return; + } + + float sediment = context.cell.sediment * SEDIMENT_MODIFIER; + float noise = context.climate.getRand().getValue(x, z, seed3) * SEDIMENT_NOISE; + if (sediment + noise > SCREE_VALUE) { + fillDown(context, chunk, x, z, y, y - 2, States.GRAVEL.get()); + } + } + + public boolean erodeRock(float x, float z, float steepness, float height) { + return steepness > ROCK_STEEPNESS || height > ColumnDecorator.getNoise(x, z, seed1, ROCK_VAR, ROCK_MIN); + } + + public boolean erodeDirt(float x, float z, float steepness, float height) { + return steepness > DIRT_STEEPNESS && height > ColumnDecorator.getNoise(x, z, seed2, DIRT_VAR, DIRT_MIN); + } + + private BlockState getMaterial(float x, float z, DecoratorContext context, BlockState top, BlockState middle) { + float height = context.cell.value + context.climate.getRand().getValue(x, z, seed1) * HEIGHT_MODIFIER; + float steepness = context.cell.steepness + context.climate.getRand().getValue(x, z, seed2) * SLOPE_MODIFIER; + + if (steepness > ROCK_STEEPNESS || height > ColumnDecorator.getNoise(x, z, seed1, ROCK_VAR, ROCK_MIN)) { + return rock(middle); + } + + if (steepness > DIRT_STEEPNESS && height > ColumnDecorator.getNoise(x, z, seed2, DIRT_VAR, DIRT_MIN)) { + return ground(top); + } + + return top; + } + + private static BlockState rock(BlockState state) { + if (state.getMaterial() == Material.ROCK) { + return state; + } + return States.STONE.get(); + } + + private static BlockState ground(BlockState state) { + if (state.getMaterial() == Material.ORGANIC) { + return States.DIRT.get(); + } + if (state.getMaterial() == Material.ROCK) { + return States.GRAVEL.get(); + } + if (state.getMaterial() == Material.EARTH) { + return state; + } + if (state.getMaterial() == Material.SAND) { + if (state.getBlock() == Blocks.SAND) { + return States.SANDSTONE.get(); + } + if (state.getBlock() == Blocks.RED_SAND) { + return States.RED_SANDSTONE.get(); + } + } + return States.COARSE_DIRT.get(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/GeologyDecorator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/GeologyDecorator.java new file mode 100644 index 0000000..af2af9c --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/GeologyDecorator.java @@ -0,0 +1,56 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.chunk.surface.ChunkSurfaceBuffer; +import com.terraforged.mod.material.geology.GeoManager; +import net.minecraft.world.chunk.IChunk; + +public class GeologyDecorator implements ColumnDecorator { + + private final GeoManager geology; + + public GeologyDecorator(GeoManager geology) { + this.geology = geology; + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int dy, int z) { + + } + + @Override + public void decorate(ChunkSurfaceBuffer buffer, DecoratorContext context, int x, int y, int z) { + int top = buffer.getSurfaceBottom(); + geology.getGeology(context.biome).getStrata(x, z).downwards(x, top, z, (py, state) -> { + context.pos.setPos(x, py, z); + buffer.getDelegate().setBlockState(context.pos, state, false); + return true; + }); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/RiverDecorator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/RiverDecorator.java new file mode 100644 index 0000000..62b5946 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/base/RiverDecorator.java @@ -0,0 +1,84 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.base; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.mod.chunk.TerraContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.block.BlockState; +import net.minecraft.world.chunk.IChunk; + +public class RiverDecorator implements ColumnDecorator { + + private final Levels levels; + private final Terrain river; + private final Terrain riverBank; + + private final BlockState dirt; + private final BlockState sand; + private final BlockState gravel; + + private final Module noise1; + + public RiverDecorator(TerraContext context) { + Seed seed = context.seed.nextSeed(); + this.levels = context.levels; + this.river = context.terrain.river; + this.riverBank = context.terrain.riverBanks; + this.dirt = States.DIRT.get(); + this.sand = States.SAND.get(); + this.gravel = States.GRAVEL.get(); + this.noise1 = Source.perlin(seed.next(), 50, 1); + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + if (context.cell.tag == river) { + chunk.setBlockState(context.pos.setPos(x, y, z), dirt, false); + return; + } + if (context.cell.tag == riverBank) { + float value = noise1.getValue(x, z) * 5; + if (y + value >= levels.waterY) { + if (context.cell.steepness > 0.5) { + chunk.setBlockState(context.pos.setPos(x, y, z), gravel, false); + } else if (context.cell.steepness < 0.3) { + chunk.setBlockState(context.pos.setPos(x, y, z), sand, false); + } else { + chunk.setBlockState(context.pos.setPos(x, y, z), dirt, false); + } + } else { + chunk.setBlockState(context.pos.setPos(x, y, z), dirt, false); + } + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/feature/LayerDecorator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/feature/LayerDecorator.java new file mode 100644 index 0000000..5467be8 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/feature/LayerDecorator.java @@ -0,0 +1,87 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.feature; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.api.material.layer.LayerMaterial; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.mod.material.MaterialHelper; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.IChunk; + +public class LayerDecorator implements ColumnDecorator { + + private final LayerManager layerManager; + + public LayerDecorator(LayerManager layerManager) { + this.layerManager = layerManager; + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + context.pos.setPos(x, y + 1, z); + + // if block is already a layer-type then simply set the layer property + BlockState state = chunk.getBlockState(context.pos); + LayerMaterial material = layerManager.getMaterial(state.getBlock()); + if (material != null) { + setLayer(chunk, context.pos, material, context.cell, context.levels, 0F); + return; + } + + if (MaterialHelper.isAir(state.getBlock())) { + return; + } + + // block is non-solid (grass/flower etc) + if (!state.getMaterial().blocksMovement()) { + // block below is solid + if (chunk.getBlockState(context.pos.setPos(x, y, z)).getMaterial().blocksMovement()) { + // block above is air + if (MaterialHelper.isAir(chunk.getBlockState(context.pos.setPos(x, y + 2, z)).getBlock())) { +// setLayer(chunk, pos.setPos(x, y + 1, z), context.cell, context.levels, 0.25F); + } + } + } + } + + private void setLayer(IChunk chunk, BlockPos pos, LayerMaterial material, Cell cell, Levels levels, float min) { + float height = cell.value * levels.worldHeight; + float depth = material.getDepth(height); + if (depth > min) { + int level = material.getLevel(depth); + BlockState layer = material.getState(level); + if (MaterialHelper.isAir(layer.getBlock())) { + return; + } + chunk.setBlockState(pos, layer, false); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/feature/SnowEroder.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/feature/SnowEroder.java new file mode 100644 index 0000000..2e3f125 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/feature/SnowEroder.java @@ -0,0 +1,93 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.feature; + +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorContext; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.decorator.base.ErosionDecorator; +import me.dags.noise.source.Rand; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; + +import java.util.function.Predicate; + +public class SnowEroder extends ErosionDecorator { + + private static final float SNOW_ROCK_STEEPNESS = 0.45F; + private static final float SNOW_ROCK_HEIGHT = 95F / 255F; + + private final int seed1; + private final int seed2; + private final int seed3; + private final Rand rand; + + public SnowEroder(TerraContext context) { + super(context); + this.seed1 = context.seed.next(); + this.seed2 = context.seed.next(); + this.seed3 = context.seed.next(); + this.rand = context.factory.getHeightmap().getClimate().getRand(); + } + + @Override + public void decorate(IChunk chunk, DecoratorContext context, int x, int y, int z) { + int surface = chunk.getTopBlockY(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, x, z); + if (y - surface > 0) { + if (y - surface > 4) { + return; + } + y = surface; + } + + if (context.biome.getTemperature(context.pos.setPos(x, y, z)) <= 0.25) { + float var = -ColumnDecorator.getNoise(x, z, seed1, 16, 0); + float hNoise = rand.getValue(x, z, seed2) * HEIGHT_MODIFIER; + float sNoise = rand.getValue(x, z, seed3) * SLOPE_MODIFIER; + float vModifier = context.cell.tag == context.terrains.volcano ? 0.15F : 0F; + float height = context.cell.value + var + hNoise + vModifier; + float steepness = context.cell.steepness + var + sNoise + vModifier; + if (snowErosion(x, z, steepness, height)) { + Predicate predicate = Heightmap.Type.MOTION_BLOCKING.getHeightLimitPredicate(); + for (int dy = 2; dy > 0; dy--) { + context.pos.setY(y + dy); + BlockState state = chunk.getBlockState(context.pos); + if (!predicate.test(state) || state.getBlock() == Blocks.SNOW) { + chunk.setBlockState(context.pos, Blocks.AIR.getDefaultState(), false); + } + } + } + } + } + + private boolean snowErosion(float x, float z, float steepness, float height) { + return steepness > ROCK_STEEPNESS + || (steepness > SNOW_ROCK_STEEPNESS && height > SNOW_ROCK_HEIGHT) + || super.erodeDirt(x, z, steepness, height); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/surface/DesertDunes.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/surface/DesertDunes.java new file mode 100644 index 0000000..7089486 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/surface/DesertDunes.java @@ -0,0 +1,98 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.surface; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.material.layer.LayerMaterial; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.biome.provider.BiomeProvider; +import com.terraforged.mod.biome.provider.DesertBiomes; +import com.terraforged.mod.chunk.TerraContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.func.CellFunc; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; + +public class DesertDunes implements Surface { + + private final int maxHeight; + private final Levels levels; + private final Module module; + private final Terrains terrains; + private final DesertBiomes deserts; + private final BlockPos.Mutable pos = new BlockPos.Mutable(); + + public DesertDunes(TerraContext context, int maxHeight, DesertBiomes deserts) { + Module dunes = Source.cell(context.seed.next(), 80, CellFunc.DISTANCE) + .warp(context.seed.next(), 70, 1, 70); + this.terrains = context.terrain; + this.levels = context.levels; + this.maxHeight = maxHeight; + this.deserts = deserts; + this.module = dunes; + } + + @Override + public void buildSurface(int x, int z, int surface, SurfaceContext ctx) { + float value = module.getValue(x, z) * getMask(ctx.cell); + float baseHeight = ctx.cell.value * levels.worldHeight; + float duneHeight = baseHeight + value * maxHeight; + int duneBase = (int) baseHeight; + int duneTop = (int) duneHeight; + if (duneTop < levels.waterLevel || duneTop <= baseHeight) { + return; + } + + LayerMaterial material = deserts.getSandLayers(ctx.biome); + if (material == null) { + return; + } + + fill(x, z, duneBase, duneTop, ctx, ctx.chunk, material.getFull()); + + float depth = material.getDepth(duneHeight); + int levels = material.getLevel(depth); + BlockState top = material.getState(levels); + ctx.chunk.setBlockState(pos.setPos(x, duneTop, z), top, false); + } + + public static Surface create(TerraContext context, BiomeProvider provider) { + return create(context, provider.getModifierManager().getDesertBiomes()); + } + + public static Surface create(TerraContext context, DesertBiomes desertBiomes) { + return new DesertDunes(context, 25, desertBiomes); + } + + private static float getMask(Cell cell) { + return cell.biomeMask(0F, 0.75F) * cell.mask(0.4F, 0.5F, 0F, 0.8F); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/surface/FrozenOcean.java b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/surface/FrozenOcean.java new file mode 100644 index 0000000..f20c5fa --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/decorator/surface/FrozenOcean.java @@ -0,0 +1,115 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.decorator.surface; + +import com.terraforged.api.chunk.surface.Surface; +import com.terraforged.api.chunk.surface.SurfaceContext; +import com.terraforged.api.material.state.States; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.mod.chunk.TerraContext; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; + +public class FrozenOcean implements Surface { + + private final Module up; + private final Module down; + private final Module fadeUp; + private final Module bergTop; + private final Module seaFloor; + private final Levels levels; + + public FrozenOcean(TerraContext context, int height, int depth) { + Levels levels = context.levels; + Module shape = Source.perlin(context.seed.next(), 65, 3) + .warp(context.seed.next(), 15, 1, 10) + .cache(); + Module mask = shape.threshold(0.6).cache(); + Module fadeDown = shape.clamp(0.6, 0.725).map(0, 1); + + this.levels = levels; + + this.fadeUp = shape.clamp(0.6, 0.65).map(0, 1); + + this.up = Source.ridge(context.seed.next(), 50, 3) + .mult(mask) + .mult(fadeUp) + .scale(levels.scale(height)); + + this.down = Source.ridge(context.seed.next(), 60, 3) + .mult(mask) + .mult(fadeDown) + .scale(levels.scale(depth)); + + this.bergTop = Source.perlin(context.seed.next(), 25, 2) + .scale(levels.scale(3)) + .bias(levels.scale(2)); + + this.seaFloor = Source.perlin(context.seed.next(), 50, 1) + .scale(levels.scale(3)) + .bias(levels.scale(1)); + } + + @Override + public void buildSurface(int x, int z, int height, SurfaceContext ctx) { + int center = levels.waterLevel - 5; + int top = center + (int) (up.getValue(x, z) * levels.worldHeight); + int topDepth = (int) (bergTop.getValue(x, z) * levels.worldHeight); + int bottom = center - (int) (down.getValue(x, z) * levels.worldHeight); + + // set iceberg materials + BlockPos.Mutable pos = new BlockPos.Mutable(x, height, z); + for (int dy = top; dy > bottom; dy--) { + pos.setY(dy); + BlockState state = getMaterial(x, dy, z, top, topDepth); + ctx.chunk.setBlockState(pos, state, false); + } + + // set ocean floor to gravel + int floorBed = (int) (ctx.cell.value * ctx.levels.worldHeight); + int floorDepth = (int) (seaFloor.getValue(x, z) * levels.worldHeight); + for (int dy = 0; dy < floorDepth; dy++) { + pos.setY(floorBed - dy); + ctx.chunk.setBlockState(pos, SurfaceBuilder.GRAVEL, false); + } + } + + private BlockState getMaterial(int x, int y, int z, int top, int topDepth) { + if (y >= top - topDepth && fadeUp.getValue(x, z) == 1) { + return States.SNOW_BLOCK.get(); + } + return States.PACKED_ICE.get(); + } + + private static float getMask(Cell cell) { + return NoiseUtil.map(cell.biomeTypeMask * cell.riverMask, 0F, 0.3F, 0.3F); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/Matchers.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/Matchers.java new file mode 100644 index 0000000..bcd94e8 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/Matchers.java @@ -0,0 +1,39 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature; + +import com.terraforged.feature.matcher.feature.FeatureMatcher; + +public class Matchers { + + public static final FeatureMatcher STONE_BLOBS = FeatureMatcher.builder() + .or("minecraft:ore").and("minecraft:dirt") + .or("minecraft:ore").and("minecraft:gravel") + .or("minecraft:ore").and("minecraft:granite") + .or("minecraft:ore").and("minecraft:diorite") + .or("minecraft:ore").and("minecraft:andesite") + .build(); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/TerrainHelper.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/TerrainHelper.java new file mode 100644 index 0000000..184b466 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/TerrainHelper.java @@ -0,0 +1,178 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature; + +import it.unimi.dsi.fastutil.longs.LongIterator; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectList; +import me.dags.noise.Module; +import me.dags.noise.Source; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.world.IWorld; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.jigsaw.JigsawPattern; +import net.minecraft.world.gen.feature.structure.AbstractVillagePiece; +import net.minecraft.world.gen.feature.structure.Structure; +import net.minecraft.world.gen.feature.structure.StructurePiece; +import net.minecraft.world.gen.feature.structure.StructureStart; + +public class TerrainHelper { + + private final Module noise; + private final float radius; + + public TerrainHelper(int seed, float radius) { + this.noise = Source.perlin(++seed, 8, 1).alpha(0.75); + this.radius = radius; + } + + public void flatten(IWorld world, IChunk chunk, int chunkStartX, int chunkStartZ) { + ObjectList pieces = new ObjectArrayList<>(10); + collectPieces(world, chunk, pieces); + buildBases(chunk, pieces, chunkStartX, chunkStartZ); + } + + // see NoiseChunkGenerator + private void collectPieces(IWorld world, IChunk chunk, ObjectList pieces) { + ChunkPos pos = chunk.getPos(); + for (Structure structure : Feature.ILLAGER_STRUCTURES) { + String name = structure.getStructureName(); + LongIterator structureIds = chunk.getStructureReferences(name).iterator(); + + while (structureIds.hasNext()) { + long id = structureIds.nextLong(); + ChunkPos structurePos = new ChunkPos(id); + IChunk neighbourChunk = world.getChunk(structurePos.asBlockPos()); + StructureStart structurestart = neighbourChunk.getStructureStart(name); + if (structurestart != null && structurestart.isValid()) { + for (StructurePiece structurepiece : structurestart.getComponents()) { + if (structurepiece.func_214810_a(pos, 12) && structurepiece instanceof AbstractVillagePiece) { + AbstractVillagePiece piece = (AbstractVillagePiece) structurepiece; + JigsawPattern.PlacementBehaviour placement = piece.getJigsawPiece().getPlacementBehaviour(); + if (placement == JigsawPattern.PlacementBehaviour.RIGID) { + pieces.add(piece); + } + } + } + } + } + } + } + + // try to fill in type air beneath village pieces with the biomes default filler block + private void buildBases(IChunk chunk, ObjectList pieces, int chunkStartX, int chunkStartZ) { + BlockPos.Mutable pos = new BlockPos.Mutable(); + MutableBoundingBox chunkBounds = new MutableBoundingBox(chunkStartX, chunkStartZ, chunkStartX + 15, chunkStartZ + 15); + for (AbstractVillagePiece piece : pieces) { + MutableBoundingBox pieceBounds = piece.getBoundingBox(); + + int length = Math.min(pieceBounds.maxX - pieceBounds.minX, pieceBounds.maxZ - pieceBounds.minZ); + int borderRadius = Math.max(5, NoiseUtil.round(length * radius)); + MutableBoundingBox expanded = expand(pieceBounds, borderRadius); + + if (!expanded.intersectsWith(chunkBounds)) { + continue; + } + + // intersecting area between the generator bounds and the village piece bounds + int startX = Math.max(chunkStartX, expanded.minX); + int startZ = Math.max(chunkStartZ, expanded.minZ); + int endX = Math.min(chunkStartX + 15, expanded.maxX); + int endZ = Math.min(chunkStartZ + 15, expanded.maxZ); + + // iterate the intersecting area + for (int z = startZ; z <= endZ; z++) { + for (int x = startX; x <= endX; x++) { + // local generator coords + int dx = x & 15; + int dz = z & 15; + + // the paste position of the village piece + BlockPos position = piece.getPos(); + + int offset = piece.getGroundLevelDelta(); + int level = position.getY() + (offset - 1); + int surface = chunk.getTopBlockY(Heightmap.Type.OCEAN_FLOOR_WG, dx, dz) - 1; + int height = level - surface; + if (height <= 0) { + continue; + } + + float radius2 = Math.max(1, borderRadius * borderRadius * noise.getValue(x, z)); + float alpha = getAlpha(pieceBounds, radius2, x, z); + if (alpha == 0F) { + continue; + } + + if (alpha < 1F) { + alpha = alpha * alpha; + height = NoiseUtil.round(alpha * height); + } + + BlockState state = Blocks.STONE.getDefaultState(); + for (int dy = surface + height; dy >= surface; dy--) { + pos.setPos(dx, dy, dz); + if (chunk.getBlockState(pos).isSolid()) { + break; + } + chunk.setBlockState(pos.setPos(dx, dy, dz), state, false); + } + } + } + } + } + + private static MutableBoundingBox expand(MutableBoundingBox box, int radius) { + return new MutableBoundingBox( + box.minX - radius, + box.minY, + box.minZ - radius, + box.maxX + radius, + box.maxY, + box.maxZ + radius + ); + } + + private static float getAlpha(MutableBoundingBox box, float radius2, int x, int y) { + int dx = x < box.minX ? box.minX - x : x > box.maxX ? x - box.maxX : 0; + int dy = y < box.minZ ? box.minZ - y : y > box.maxZ ? y - box.maxZ : 0; + int d2 = dx * dx + dy * dy; + if (d2 == 0) { + return 1F; + } + if (d2 > radius2) { + return 0F; + } + return 1 - (d2 / radius2); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/predicate/TreeLine.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/predicate/TreeLine.java new file mode 100644 index 0000000..fd9f6d6 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/predicate/TreeLine.java @@ -0,0 +1,57 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.predicate; + +import com.terraforged.core.world.climate.Climate; +import com.terraforged.feature.predicate.FeaturePredicate; +import com.terraforged.mod.chunk.TerraContext; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.gen.Heightmap; + +public class TreeLine implements FeaturePredicate { + + private final int worldHeight; + private final Climate climate; + + public TreeLine(TerraContext context) { + this.worldHeight = context.levels.worldHeight; + this.climate = context.heightmap.getClimate(); + } + + @Override + public boolean test(IChunk chunk, Biome biome) { + int x = chunk.getPos().getXStart() + 8; + int z = chunk.getPos().getZStart() + 8; + int treeline = getTreeline(x, z); + int y = chunk.getTopBlockY(Heightmap.Type.WORLD_SURFACE_WG, 8, 8); + return y < treeline; + } + + private int getTreeline(int x, int z) { + return (int) (climate.getTreeLine(x, z) * worldHeight); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingConfig.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingConfig.java new file mode 100644 index 0000000..70b4333 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingConfig.java @@ -0,0 +1,122 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.google.gson.reflect.TypeToken; +import com.mojang.datafixers.types.DynamicOps; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class SaplingConfig { + + private static final TypeToken> TOKEN = new TypeToken>() { + }; + + private final Map normal; + private final Map giant; + + public SaplingConfig() { + normal = new HashMap<>(); + giant = new HashMap<>(); + } + + public SaplingConfig(T config, DynamicOps ops) { + this.normal = getSection("normal", config, ops); + this.giant = getSection("giant", config, ops); + } + + public SaplingConfig addNormal(ResourceLocation name, int weight) { + normal.put(name, weight); + return this; + } + + public SaplingConfig addNormal(String name, int weight) { + normal.put(new ResourceLocation(name), weight); + return this; + } + + public SaplingConfig addGiant(ResourceLocation name, int weight) { + giant.put(name, weight); + return this; + } + + public SaplingConfig addGiant(String name, int weight) { + giant.put(new ResourceLocation(name), weight); + return this; + } + + private Map getSection(String key, T config, DynamicOps ops) { + return ops.get(config, key).flatMap(ops::getMapValues).map(map -> { + Map backing = new HashMap<>(); + + for (Map.Entry entry : map.entrySet()) { + String name = ops.getStringValue(entry.getKey()).orElse(""); + int weight = ops.getNumberValue(entry.getValue()).orElse(0).intValue(); + if (name.isEmpty() || weight == 0) { + continue; + } + + ResourceLocation loc = new ResourceLocation(name); + backing.put(loc, weight); + } + + return backing; + }).orElse(Collections.emptyMap()); + } + + public List> getNormal() { + return build(normal); + } + + public List> getGiant() { + return build(giant); + } + + @SuppressWarnings("unchecked") + public static List> build(Map map) { + List> list = new LinkedList<>(); + for (Map.Entry entry : map.entrySet()) { + Feature feature = ForgeRegistries.FEATURES.getValue(entry.getKey()); + if (feature == null) { + continue; + } + + if (TOKEN.getRawType().isAssignableFrom(feature.getClass())) { + Feature noConfFeature = (Feature) feature; + list.add(noConfFeature); + } + } + return list; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingFeature.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingFeature.java new file mode 100644 index 0000000..b8204ff --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingFeature.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class SaplingFeature { + + private final List> normal; + private final List> giant; + + public SaplingFeature(SaplingConfig config) { + this.normal = new ArrayList<>(config.getNormal()); + this.giant = new ArrayList<>(config.getGiant()); + } + + public Feature nextNormal(Random random) { + if (normal.isEmpty()) { + return null; + } + return normal.get(random.nextInt(normal.size())); + } + + public Feature nextGiant(Random random) { + if (giant.isEmpty()) { + return null; + } + return giant.get(random.nextInt(giant.size())); + } + + public int getNormalCount() { + return normal.size(); + } + + public int getGiantCount() { + return giant.size(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingListener.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingListener.java new file mode 100644 index 0000000..18e2e24 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingListener.java @@ -0,0 +1,141 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.terraforged.mod.TerraWorld; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.SaplingBlock; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; +import net.minecraft.world.WorldType; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraftforge.event.world.SaplingGrowTreeEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) +public class SaplingListener { + + private static final BlockPos[] NONE = {BlockPos.ZERO}; + + private static final Vec3i[][] DIRECTIONS = { + {new Vec3i(0, 0, 1), new Vec3i(1, 0, 1), new Vec3i(1, 0, 0)}, + {new Vec3i(1, 0, 0), new Vec3i(1, 0, -1), new Vec3i(0, 0, -1)}, + {new Vec3i(0, 0, -1), new Vec3i(-1, 0, -1), new Vec3i(-1, 0, 0)}, + {new Vec3i(-1, 0, 0), new Vec3i(-1, 0, 1), new Vec3i(0, 0, 1)}, + }; + + @SubscribeEvent + public static void onTreeGrow(SaplingGrowTreeEvent event) { + if (!TerraWorld.isTerraWorld(event.getWorld())) { + return; + } + + IWorld world = event.getWorld(); + BlockPos pos = event.getPos(); + Block block = world.getBlockState(pos).getBlock(); + if (block instanceof SaplingBlock) { + // get the sapling feature for the given block type + SaplingFeature tree = SaplingManager.getSapling(block.getRegistryName()); + + // tree is null if the sapling type hasn't been configured + if (tree == null) { + return; + } + + // check for a 2x2 arrangement of sapling blocks around the position + Vec3i[] directions = getNeighbourDirections(world, block, pos); + + // length is 1 if a full 2x2 arrangement could not be found + if (directions.length == 1) { + placeNormal(tree, event, directions); + } else { + placeGiant(tree, event, block, directions); + } + } + } + + private static void placeNormal(SaplingFeature tree, SaplingGrowTreeEvent event, Vec3i[] directions) { + SaplingPlacer.placeTree(tree.nextNormal(event.getRand()), event, directions); + } + + private static void placeGiant(SaplingFeature tree, SaplingGrowTreeEvent event, Block type, Vec3i[] directions) { + Feature feature = tree.nextGiant(event.getRand()); + + // if no giant tree exists for this sapling type try and place a normal one instead + if (feature == null) { + placeNormal(tree, event, directions); + return; + } + + // do not continue if unable to place the tree + if (!SaplingPlacer.placeTree(feature, event, directions)) { + return; + } + + // iterate through the contributing saplings and remove any that were not destroyed during tree creation + BlockPos pos = event.getPos(); + for (Vec3i dir : directions) { + BlockPos blockPos = pos.add(dir); + BlockState state = event.getWorld().getBlockState(blockPos); + if (state.getBlock() == type) { + event.getWorld().removeBlock(blockPos, false); + } + } + } + + private static Vec3i[] getNeighbourDirections(IWorld world, Block block, BlockPos pos) { + for (Vec3i[] dirs : DIRECTIONS) { + boolean match = true; + for (Vec3i dir : dirs) { + BlockState state = world.getBlockState(pos.add(dir)); + if (state.getBlock() != block) { + match = false; + break; + } + } + if (match) { + return dirs; + } + } + return NONE; + } + + private static boolean isTerraWorld(IWorld world) { + if (world instanceof World) { + return isTerraWorld(((World) world).getWorldType()); + } + return false; + } + + private static boolean isTerraWorld(WorldType type) { + return type.getName().equals("terraforged"); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingManager.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingManager.java new file mode 100644 index 0000000..9335703 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingManager.java @@ -0,0 +1,90 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.mojang.datafixers.types.DynamicOps; +import com.terraforged.mod.Log; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.util.ResourceLocation; + +import java.util.HashMap; +import java.util.Map; + +public class SaplingManager { + + private static final Map saplings = new HashMap<>(); + + public static SaplingFeature getSapling(ResourceLocation name) { + return saplings.get(name); + } + + public static void register(Block block, SaplingConfig config) { + register(block.getRegistryName(), config); + } + + public static void register(ResourceLocation location, T config, DynamicOps ops) { + register(location, new SaplingConfig(config, ops)); + } + + public static void register(ResourceLocation location, SaplingConfig config) { + saplings.put(location, new SaplingFeature(config)); + } + + public static void init() { + register(Blocks.OAK_SAPLING, new SaplingConfig() + .addNormal("terraforged:oak_small", 4) + .addNormal("terraforged:oak_forest", 3) + .addNormal("terraforged:oak_large", 2) + .addGiant("terraforged:oak_huge", 1)); + + register(Blocks.BIRCH_SAPLING, new SaplingConfig() + .addNormal("terraforged:birch_small", 4) + .addNormal("terraforged:birch_forest", 3) + .addNormal("terraforged:birch_large", 1)); + + register(Blocks.JUNGLE_SAPLING, new SaplingConfig() + .addNormal("terraforged:jungle_small", 4) + .addGiant("terraforged:jungle_large", 1)); + + register( + Blocks.SPRUCE_SAPLING, + new SaplingConfig() + .addNormal("terraforged:spruce_small", 4) + .addNormal("terraforged:spruce_large", 1) + .addGiant("terraforged:redwood_huge", 1)); + + register(Blocks.DARK_OAK_SAPLING, new SaplingConfig() + .addNormal("terraforged:dark_oak_small", 4) + .addNormal("terraforged:dark_oak_large", 1)); + + register(Blocks.ACACIA_SAPLING, new SaplingConfig() + .addNormal("terraforged:acacia_small", 2) + .addNormal("terraforged:acacia_large", 1)); + + Log.info("Registered saplings"); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingPlacer.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingPlacer.java new file mode 100644 index 0000000..788a12c --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/SaplingPlacer.java @@ -0,0 +1,151 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.terraforged.feature.template.decorator.DecoratedFeature; +import com.terraforged.feature.template.decorator.DecoratorWorld; +import com.terraforged.feature.template.feature.TemplateFeature; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IWorld; +import net.minecraft.world.gen.ChunkGenerator; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.server.ServerChunkProvider; +import net.minecraftforge.event.world.SaplingGrowTreeEvent; +import net.minecraftforge.eventbus.api.Event; + +public class SaplingPlacer { + + public static boolean placeTree(Feature feature, SaplingGrowTreeEvent event, Vec3i[] dirs) { + if (feature == null) { + return false; + } + + event.setResult(Event.Result.DENY); + + if (feature instanceof DecoratedFeature) { + return placeDecorated((DecoratedFeature) feature, event, dirs); + } + + return placeNormal(feature, event, dirs); + } + + private static boolean placeDecorated(DecoratedFeature feature, SaplingGrowTreeEvent event, Vec3i[] dirs) { + if (!(event.getWorld().getChunkProvider() instanceof ServerChunkProvider)) { + return false; + } + + TreeBuffer buffer = new TreeBuffer(event.getWorld(), event.getPos()); + W world = feature.wrap(buffer); + + ChunkGenerator generator = ((ServerChunkProvider) event.getWorld().getChunkProvider()).getChunkGenerator(); + feature.placeFeature(world, generator, event.getRand(), event.getPos(), NoFeatureConfig.NO_FEATURE_CONFIG); + + // check that the tree can grow here + if (overheadIsSolid(event.getWorld(), event.getPos(), buffer.getTopY())) { + return false; + } + + BlockPos translation = buffer.getBaseMin().add(getMin(dirs)); + + // apply buffer to world with translation + applyBuffer(buffer, event.getWorld(), translation); + + // translate the decoration positions and apply in the world + world.setDelegate(event.getWorld()); + world.translate(translation); + feature.decorate(world, event.getRand()); + return true; + } + + private static boolean placeNormal(Feature feature, SaplingGrowTreeEvent event, Vec3i[] dirs) { + // apply the feature to a buffer + TreeBuffer buffer = new TreeBuffer(event.getWorld(), event.getPos()); + buffer.placeFeature(feature, event.getPos(), event.getRand()); + + // check that the tree can grow here + if (overheadIsSolid(event.getWorld(), event.getPos(), buffer.getTopY())) { + return false; + } + + // get the min position in the 2x2 grid + BlockPos translation = buffer.getBaseMin().add(getMin(dirs)); + + // copy the feature from the buffer to the world while translating each block + applyBuffer(buffer, event.getWorld(), translation); + return true; + } + + private static void applyBuffer(TreeBuffer buffer, IWorld world, BlockPos translation) { + try (BlockPos.PooledMutable pos = BlockPos.PooledMutable.retain()) { + for (TemplateFeature.BlockInfo block : buffer.getChanges()) { + int x = block.getPos().getX() + translation.getX(); + int y = block.getPos().getY(); + int z = block.getPos().getZ() + translation.getZ(); + + pos.setPos(x, y, z); + + if (pos.getY() > 90) { + BlockState current = world.getBlockState(pos); + if (current.isSolid()) { + continue; + } + } + + world.setBlockState(pos, block.getState(), 2); + } + } + } + + private static boolean overheadIsSolid(IWorld world, BlockPos pos, int topY) { + try (BlockPos.PooledMutable blockPos = BlockPos.PooledMutable.retain()) { + for (int y = pos.getY(); y <= topY; y++) { + blockPos.setPos(pos.getX(), y, pos.getZ()); + BlockState state = world.getBlockState(pos); + if (state.isSolid()) { + return true; + } + } + return false; + } + } + + private static Vec3i getMin(Vec3i[] dirs) { + Vec3i min = Vec3i.NULL_VECTOR; + for (Vec3i dir : dirs) { + if (dir.getX() < min.getX() && dir.getZ() <= min.getZ()) { + min = dir; + continue; + } + if (dir.getZ() < min.getZ() && dir.getX() <= min.getX()) { + min = dir; + } + } + return min; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/TreeBuffer.java b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/TreeBuffer.java new file mode 100644 index 0000000..8488612 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/feature/tree/TreeBuffer.java @@ -0,0 +1,123 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.feature.tree; + +import com.terraforged.feature.template.feature.TemplateFeature; +import com.terraforged.feature.util.WorldDelegate; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IWorld; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.IFeatureConfig; +import net.minecraft.world.gen.feature.NoFeatureConfig; +import net.minecraft.world.server.ServerChunkProvider; + +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +public class TreeBuffer extends WorldDelegate { + + private int topY = 0; + private final BlockPos pos; + private final MutableVec3i baseMin = new MutableVec3i(0); + private final MutableVec3i baseMax = new MutableVec3i(0); + private final List changes = new LinkedList<>(); + + public TreeBuffer(IWorld delegate, BlockPos pos) { + super(delegate); + this.pos = pos; + } + + public int getTopY() { + return topY; + } + + public BlockPos getBaseMin() { + return new BlockPos(-baseMin.x, baseMin.y, -baseMin.z); + } + + public BlockPos getBaseMax() { + return new BlockPos(baseMax.x, baseMax.y, baseMax.z); + } + + public Iterable getChanges() { + return changes; + } + + @Override + public boolean setBlockState(BlockPos pos, BlockState state, int i) { + if (state.isSolid()) { + recordPos(pos); + } + changes.add(new TemplateFeature.BlockInfo(pos, state)); + return true; + } + + public void placeFeature(Feature feature, BlockPos pos, Random random) { + placeFeature(feature, pos, random, NoFeatureConfig.NO_FEATURE_CONFIG); + } + + public void placeFeature(Feature feature, BlockPos pos, Random random, T config) { + if (getChunkProvider() instanceof ServerChunkProvider) { + ServerChunkProvider chunkProvider = (ServerChunkProvider) getChunkProvider(); + feature.place(this, chunkProvider.getChunkGenerator(), random, pos, config); + } + } + + private void recordPos(BlockPos pos) { + if (pos.getY() > topY) { + topY = pos.getY(); + baseMax.max(pos.subtract(this.pos)); + } else if (pos.getY() == this.pos.getY()) { + baseMin.min(pos.subtract(this.pos)); + } + } + + private static class MutableVec3i { + + private int x, y, z; + + private MutableVec3i(int start) { + x = start; + y = start; + z = start; + } + + private void min(Vec3i vec) { + x = Math.min(x, vec.getX()); + y = Math.min(y, vec.getY()); + z = Math.min(z, vec.getZ()); + } + + private void max(Vec3i vec) { + x = Math.max(x, vec.getX()); + y = Math.max(y, vec.getY()); + z = Math.max(z, vec.getZ()); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/OverlayRenderer.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/OverlayRenderer.java new file mode 100644 index 0000000..2cc9fde --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/OverlayRenderer.java @@ -0,0 +1,33 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import net.minecraft.client.gui.screen.Screen; + +public interface OverlayRenderer { + + void renderOverlays(Screen screen, int mouseX, int mouseY); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/OverlayScreen.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/OverlayScreen.java new file mode 100644 index 0000000..4514719 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/OverlayScreen.java @@ -0,0 +1,87 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import com.terraforged.mod.gui.element.CheckBox; +import com.terraforged.mod.gui.element.Element; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.util.text.TranslationTextComponent; + +public class OverlayScreen extends Screen implements OverlayRenderer { + + public boolean showTooltips = false; + + public OverlayScreen() { + super(new TranslationTextComponent("")); + super.minecraft = Minecraft.getInstance(); + super.font = minecraft.fontRenderer; + } + + @Override + public T addButton(T buttonIn) { + return super.addButton(buttonIn); + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.render(mouseX, mouseY, partialTicks); + if (showTooltips) { + renderOverlays(this, mouseX, mouseY); + } + } + + @Override + public void renderOverlays(Screen screen, int mouseX, int mouseY) { + for (Widget button : buttons) { + if (button.isMouseOver(mouseX, mouseY)) { + if (button instanceof Element) { + screen.renderTooltip(((Element) button).getTooltip(), mouseX, mouseY); + return; + } + } + } + } + + @Override + protected void init() { + addButton(new CheckBox("Tooltips", showTooltips) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + showTooltips = isChecked(); + } + + @Override + public void render(int mouseX, int mouseY, float partial) { + this.x = OverlayScreen.this.width - width - 12; + this.y = 8; + super.render(mouseX, mouseY, partial); + } + }); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/ScrollPane.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/ScrollPane.java new file mode 100644 index 0000000..211044b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/ScrollPane.java @@ -0,0 +1,123 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import com.terraforged.mod.gui.element.Element; +import com.terraforged.mod.gui.preview.Preview; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.client.gui.widget.list.AbstractOptionList; + +import java.util.Collections; +import java.util.List; + +public class ScrollPane extends AbstractOptionList implements OverlayRenderer { + + private boolean hovered = false; + + public ScrollPane(int slotHeightIn) { + super(Minecraft.getInstance(), 0, 0, 0, 0, slotHeightIn); + } + + public void addButton(Widget button) { + super.addEntry(new Entry(button)); + } + + @Override + public void renderOverlays(Screen screen, int x, int y) { + for (Entry entry : this.children()) { + if (entry.isMouseOver(x, y) && entry.option.isMouseOver(x, y)) { + Widget button = entry.option; + if (button instanceof Element) { + screen.renderTooltip(((Element) button).getTooltip(), x, y); + return; + } + } + } + } + + @Override + public int getRowWidth() { + return width - 20; + } + + @Override + public void render(int x, int y, float partialTicks) { + super.render(x, y, partialTicks); + hovered = isMouseOver(x, y); + } + + @Override + protected int getScrollbarPosition() { + return getRight(); + } + + @Override + public boolean mouseScrolled(double x, double y, double direction) { + return hovered && super.mouseScrolled(x, y, direction); + } + + public class Entry extends AbstractOptionList.Entry { + + public final Widget option; + + public Entry(Widget option) { + this.option = option; + } + + @Override + public List children() { + return Collections.singletonList(option); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + return option.mouseClicked(x, y, button); + } + + @Override + public boolean mouseReleased(double x, double y, int button) { + return option.mouseReleased(x, y, button); + } + + @Override + public void render(int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean wut, float partialTicks) { + int optionWidth = Math.min(396, width); + int padding = (width - optionWidth) / 2; + option.x = left + padding; + option.y = top; + option.visible = true; + option.setWidth(optionWidth); + option.setHeight(height); + if (option instanceof Preview) { + option.setHeight(option.getWidth()); + } + option.render(mouseX, mouseY, partialTicks); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java new file mode 100644 index 0000000..f451d4c --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java @@ -0,0 +1,257 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.TerraWorld; +import com.terraforged.mod.gui.element.TerraLabel; +import com.terraforged.mod.gui.page.FeaturePage; +import com.terraforged.mod.gui.page.FilterPage; +import com.terraforged.mod.gui.page.GeneratorPage; +import com.terraforged.mod.gui.page.Page; +import com.terraforged.mod.gui.page.RiverPage; +import com.terraforged.mod.gui.page.StructurePage; +import com.terraforged.mod.gui.page.TerrainPage; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.CreateWorldScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.button.Button; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Util; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; + +public class SettingsScreen extends OverlayScreen { + + private static final Button.IPressable NO_ACTION = b -> {}; + + private final Page[] pages; + private final CreateWorldScreen parent; + private final PreviewPage preview = new PreviewPage(); + private final TerraSettings settings = new TerraSettings(); + + private int pageIndex = 0; + + public SettingsScreen(CreateWorldScreen parent) { + NBTHelper.deserialize(parent.chunkProviderSettingsJson, settings); + this.parent = parent; + this.pages = new Page[]{ + new GeneratorPage(settings, preview), + new TerrainPage(settings, preview), + new RiverPage(settings, preview), + new FilterPage(settings, preview), + new FeaturePage(settings), + new StructurePage(settings) + }; + } + + @Override + protected void init() { + super.buttons.clear(); + super.children.clear(); + + int buttonsCenter = width / 2; + int buttonWidth = 50; + int buttonHeight = 20; + int buttonPad = 2; + int buttonsRow = height - 25; + + if (pageIndex < pages.length) { + Page page = pages[pageIndex]; + TerraLabel title = new TerraLabel(page.getTitle()); + title.visible = true; + title.x = 16; + title.y = 15; + buttons.add(title); + + try { + page.initPage(10, 30, this); + preview.initPage(10, 30, this); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + // -52 + addButton(new Button(buttonsCenter - buttonWidth - buttonPad, buttonsRow, buttonWidth, buttonHeight, "Cancel" + , b -> onClose())); + + // +2 + addButton(new Button(buttonsCenter + buttonPad, buttonsRow, buttonWidth, buttonHeight, "Done", b -> { + for (Page page : pages) { + page.save(); + } + parent.chunkProviderSettingsJson = NBTHelper.serializeCompact(settings); + onClose(); + })); + + + // -106 + addButton(new Button(buttonsCenter - (buttonWidth * 2 + (buttonPad * 3)), buttonsRow, buttonWidth, + buttonHeight, "<<", NO_ACTION) { + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.active = hasPrevious(); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + if (hasPrevious()) { + pageIndex--; + init(); + } + } + + private boolean hasPrevious() { + return pageIndex > 0; + } + }); + + // +56 + addButton(new Button(buttonsCenter + buttonWidth + (buttonPad * 3), buttonsRow, buttonWidth, buttonHeight, + ">>", NO_ACTION) { + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.active = hasNext(); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + if (hasNext()) { + pageIndex++; + init(); + } + } + + private boolean hasNext() { + return pageIndex + 1 < pages.length; + } + }); + + addButton(new Button(width - buttonWidth - 15, buttonsRow, buttonWidth, buttonHeight, "Export", NO_ACTION) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + export(settings); + } + }); + + super.init(); + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.renderBackground(); + pages[pageIndex].visit(pane -> pane.render(mouseX, mouseY, partialTicks)); + preview.visit(pane -> pane.render(mouseX, mouseY, partialTicks)); + super.render(mouseX, mouseY, partialTicks); + } + + @Override + public void renderOverlays(Screen screen, int mouseX, int mouseY) { + super.renderOverlays(screen, mouseX, mouseY); + pages[pageIndex].visit(pane -> pane.renderOverlays(screen, mouseX, mouseY)); + preview.visit(pane -> pane.renderOverlays(screen, mouseX, mouseY)); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + boolean a = pages[pageIndex].action(pane -> pane.mouseClicked(x, y, button)); + boolean b = preview.action(pane -> pane.mouseClicked(x, y, button)); + boolean c = super.mouseClicked(x, y, button); + return a || b || c; + } + + @Override + public boolean mouseReleased(double x, double y, int button) { + boolean a = pages[pageIndex].action(pane -> pane.mouseReleased(x, y, button)); + boolean b = preview.action(pane -> pane.mouseReleased(x, y, button)); + boolean c = super.mouseReleased(x, y, button); + return a || b || c; + } + + @Override + public boolean mouseDragged(double x, double y, int button, double dx, double dy) { + boolean a = pages[pageIndex].action(pane -> pane.mouseDragged(x, y, button, dx, dy)); + boolean b = preview.action(pane -> pane.mouseDragged(x, y, button, dx, dy)); + boolean c = super.mouseDragged(x, y, button, dx, dy); + return a || b || c; + } + + @Override + public boolean mouseScrolled(double x, double y, double direction) { + boolean a = pages[pageIndex].action(pane -> pane.mouseScrolled(x, y, direction)); + boolean b = preview.action(pane -> pane.mouseScrolled(x, y, direction)); + boolean c = super.mouseScrolled(x, y, direction); + return a || b || c; + } + + @Override + public boolean keyPressed(int i, int j, int k) { + boolean a = pages[pageIndex].action(pane -> pane.keyPressed(i, j, k)); + boolean b = preview.action(pane -> pane.keyPressed(i, j, k)); + boolean c = super.keyPressed(i, j, k); + return a || b || c; + } + + @Override + public void onClose() { + for (Page page : pages) { + page.close(); + } + preview.close(); + Minecraft.getInstance().displayGuiScreen(parent); + } + + private void export(Settings settings) { + for (Page page : pages) { + page.save(); + } + CompoundNBT tag = NBTHelper.serializeCompact(settings); + JsonElement json = NBTHelper.toJson(tag); + File config = new File(Minecraft.getInstance().gameDir, "config"); + File file = new File(config, TerraWorld.SETTINGS_FILE_NAME); + try (Writer writer = new BufferedWriter(new FileWriter(file))) { + new GsonBuilder().setPrettyPrinting().create().toJson(json, writer); + Util.getOSType().openURI(file.getParentFile().toURI()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/CheckBox.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/CheckBox.java new file mode 100644 index 0000000..5a6cfeb --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/CheckBox.java @@ -0,0 +1,60 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +public class CheckBox extends TerraButton implements Element { + + private boolean checked = false; + + public CheckBox(String displayString, boolean isChecked) { + super(displayString); + this.visible = true; + this.width = 70; + this.height = 16; + checked = isChecked; + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + } + + @Override + public void onClick(double x, double y) { + super.onClick(x, y); + checked = !checked; + } + + @Override + public void render(int x, int y, float ticks) { + active = !checked; + super.render(x, y, ticks); + active = true; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/Element.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/Element.java new file mode 100644 index 0000000..2596595 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/Element.java @@ -0,0 +1,59 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.ListNBT; +import net.minecraftforge.common.util.Constants; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +public interface Element { + + AtomicInteger ID_COUNTER = new AtomicInteger(0); + + default List getTooltip() { + return Collections.emptyList(); + } + + static int nextID() { + return ID_COUNTER.getAndAdd(1); + } + + static List readTooltip(CompoundNBT value) { + if (value.contains("#comment")) { + ListNBT comment = value.getList("#comment", Constants.NBT.TAG_STRING); + return comment.stream() + .map(INBT::getString) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraButton.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraButton.java new file mode 100644 index 0000000..5966e4c --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraButton.java @@ -0,0 +1,35 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraftforge.fml.client.gui.widget.ExtendedButton; + +public class TerraButton extends ExtendedButton implements Element { + + public TerraButton(String displayString) { + super(0, 0, 200, 20, displayString, b -> {}); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraLabel.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraLabel.java new file mode 100644 index 0000000..8acddf5 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraLabel.java @@ -0,0 +1,52 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; + +public class TerraLabel extends TerraButton { + +// private final GuiLabel label; + + public TerraLabel(String text) { + super(text); + visible = true; +// label = new GuiLabel( +// Collections.singletonList(text), +// 0xFFFFFF, +// Minecraft.getInstance().fontRenderer +// ); +// label.visible = true; + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + Minecraft minecraft = Minecraft.getInstance(); + FontRenderer fontrenderer = minecraft.fontRenderer; + fontrenderer.drawStringWithShadow(getMessage(), x, y + (height - 8) / 2, 0xFFFFFF); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraSlider.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraSlider.java new file mode 100644 index 0000000..6689422 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/TerraSlider.java @@ -0,0 +1,100 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraftforge.fml.client.gui.widget.Slider; + +import java.util.List; + +public abstract class TerraSlider extends Slider implements Slider.ISlider, Element { + + private final CompoundNBT value; + private final List tooltip; + + private Runnable callback = () -> {}; + + public TerraSlider(String prefix, CompoundNBT value, boolean decimal) { + super(0, 0, 100, 20, prefix, "", value.getFloat("#min"), value.getFloat("#max"), 0F, decimal, true, b -> {}); + this.value = value; + this.parent = this; + this.tooltip = Element.readTooltip(value); + } + + public TerraSlider callback(Runnable callback) { + this.callback = callback; + return this; + } + + @Override + public List getTooltip() { + return tooltip; + } + + @Override + public void onChangeSliderValue(Slider slider) { + onChange(slider, value); + } + + @Override + public void onRelease(double mouseX, double mouseY) { + super.onRelease(mouseX, mouseY); + callback.run(); + } + + protected abstract void onChange(Slider slider, CompoundNBT value); + + public static class Int extends TerraSlider { + + public Int(String prefix, CompoundNBT value) { + super(prefix, value, false); + setValue(value.getInt("value")); + updateSlider(); + } + + @Override + protected void onChange(Slider slider, CompoundNBT value) { + value.putInt("value", slider.getValueInt()); + } + } + + public static class Float extends TerraSlider { + + public Float(String prefix, CompoundNBT value) { + super(prefix, value, true); + precision = 4; + setValue(value.getFloat("value")); + updateSlider(); + } + + @Override + protected void onChange(Slider slider, CompoundNBT value) { + int i = (int) (slider.getValue() * 1000); + float f = i / 1000F; + value.putFloat("value", f); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/Toggle.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/Toggle.java new file mode 100644 index 0000000..2dd2163 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/element/Toggle.java @@ -0,0 +1,86 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.element; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraftforge.common.util.Constants; + +public class Toggle extends TerraButton { + + private final String prefix; + private final CompoundNBT value; + private final ListNBT options; + + private int index; + private Runnable callback = () -> {}; + + public Toggle(String prefix, CompoundNBT value) { + super(value.getString("value")); + this.value = value; + this.prefix = prefix; + this.options = value.getList("#options", Constants.NBT.TAG_STRING); + for (int i = 0; i < options.size(); i++) { + String s = options.getString(i); + if (s.equals(value.getString("value"))) { + index = i; + break; + } + } + setMessage(prefix + value.getString("value")); + } + + public Toggle callback(Runnable runnable) { + this.callback = runnable; + return this; + } + + @Override + public boolean mouseClicked(double mx, double my, int button) { + if (super.isValidClickButton(button)) { + int direction = button == 0 ? 1 : -1; + this.playDownSound(Minecraft.getInstance().getSoundHandler()); + this.onClick(mx, my, direction); + return true; + } + return false; + } + + private void onClick(double mouseX, double mouseY, int direction) { + super.onClick(mouseX, mouseY); + index += direction; + if (index >= options.size()) { + index = 0; + } else if (index < 0) { + index = options.size() - 1; + } + String option = options.getString(index); + value.putString("value", option); + setMessage(prefix + option); + callback.run(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/BasePage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/BasePage.java new file mode 100644 index 0000000..e802b99 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/BasePage.java @@ -0,0 +1,33 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +public abstract class BasePage extends Page { + + public BasePage() { + super(4, 0, 0.7F, 0.3F); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/FeaturePage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/FeaturePage.java new file mode 100644 index 0000000..dfa0ead --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/FeaturePage.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class FeaturePage extends BasePage { + + private final TerraSettings settings; + private final CompoundNBT featureSettings; + + public FeaturePage(TerraSettings settings) { + this.settings = settings; + this.featureSettings = NBTHelper.serialize(settings.features); + } + + @Override + public String getTitle() { + return "Feature Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(featureSettings, settings.features); + } + + @Override + public void init(OverlayScreen parent) { + Column left = getColumn(0); + addElements(left.left, left.top, left, featureSettings, false, left.scrollPane::addButton, NO_CALLBACK); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/FilterPage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/FilterPage.java new file mode 100644 index 0000000..25cd306 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/FilterPage.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class FilterPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT filterSettings; + + public FilterPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.filterSettings = NBTHelper.serialize(settings.filters); + } + + @Override + public String getTitle() { + return "Filter Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(filterSettings, settings.filters); + } + + @Override + public void init(OverlayScreen parent) { + Column column = getColumn(0); + addElements(0, 0, column, filterSettings, true, column.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(filterSettings, settings.filters)); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/GeneratorPage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/GeneratorPage.java new file mode 100644 index 0000000..5308f50 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/GeneratorPage.java @@ -0,0 +1,65 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class GeneratorPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT generatorSettings; + + public GeneratorPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.generatorSettings = NBTHelper.serialize(settings.generator); + } + + @Override + public String getTitle() { + return "Generator Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(generatorSettings, settings.generator); + } + + @Override + public void init(OverlayScreen parent) { + Column left = getColumn(0); + addElements(left.left, left.top, left, generatorSettings, true, left.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(generatorSettings, settings.generator)); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/Page.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/Page.java new file mode 100644 index 0000000..68c365e --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/Page.java @@ -0,0 +1,201 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.mod.gui.OverlayRenderer; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.ScrollPane; +import com.terraforged.mod.gui.element.TerraButton; +import com.terraforged.mod.gui.element.TerraLabel; +import com.terraforged.mod.gui.element.TerraSlider; +import com.terraforged.mod.gui.element.Toggle; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.Widget; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; +import net.minecraftforge.common.util.Constants; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Function; + +public abstract class Page implements IGuiEventListener, OverlayRenderer { + + protected static final Runnable NO_CALLBACK = () -> {}; + + private static final int SLIDER_HEIGHT = 20; + private static final int SLIDER_PAD = 2; + + private final Column[] columns; + private final float[] sizes; + private final int hpad; + private final int vpad; + protected OverlayScreen parent; + + public Page(int hpad, int vpad, float... columnSizes) { + this.hpad = hpad; + this.vpad = vpad; + this.sizes = columnSizes; + this.columns = new Column[columnSizes.length]; + } + + public abstract void save(); + + public abstract void init(OverlayScreen parent); + + @Override + public void renderOverlays(Screen screen, int mouseX, int mouseY) { + for (Column column : columns) { + if (column.scrollPane.children().isEmpty()) { + continue; + } + column.scrollPane.renderOverlays(screen, mouseX, mouseY); + } + } + + public void visit(Consumer consumer) { + for (Column column : columns) { + if (column.scrollPane.children().isEmpty()) { + continue; + } + consumer.accept(column.scrollPane); + } + } + + public boolean action(Function action) { + boolean result = false; + for (Column column : columns) { + if (column.scrollPane.children().isEmpty()) { + continue; + } + boolean b = action.apply(column.scrollPane); + result = b || result; + } + return result; + } + + public void close() { + + } + + public String getTitle() { + return ""; + } + + public Column getColumn(int index) { + return columns[index]; + } + + public final void initPage(int marginH, int marginV, OverlayScreen parent) { + this.parent = parent; + int top = marginV; + int left = marginH; + int pageWidth = parent.width - (marginH * 2); + int pageHeight = parent.height; + for (int i = 0; i < columns.length; i++) { + int columnWidth = Math.round(sizes[i] * pageWidth) - (2 * hpad); + Column column = new Column(left, top, columnWidth, pageHeight, hpad, vpad); + columns[i] = column; + left += columnWidth + (2 * hpad); + } + init(parent); + } + + public void addElements(int x, int y, Column column, CompoundNBT settings, Consumer consumer, Runnable callback) { + addElements(x, y, column, settings, false, consumer, callback); + } + + public void addElements(int x, int y, Column column, CompoundNBT settings, boolean deep, Consumer consumer, Runnable callback) { + AtomicInteger top = new AtomicInteger(y); + + NBTHelper.stream(settings).forEach(value -> { + String name = value.getString("#display"); + Widget button = createButton(name, value, callback); + if (button != null) { + button.setWidth(column.width); + button.setHeight(SLIDER_HEIGHT); + button.x = x; + button.y = top.getAndAdd(SLIDER_HEIGHT + SLIDER_PAD); + consumer.accept(button); + } else if (deep) { + INBT child = value.get("value"); + if (child == null || child.getId() != Constants.NBT.TAG_COMPOUND) { + return; + } + TerraLabel label = new TerraLabel(name); + label.x = x; + label.y = top.getAndAdd(SLIDER_HEIGHT + SLIDER_PAD); + consumer.accept(label); + addElements(x, label.y, column, (CompoundNBT) child, consumer, callback); + } + }); + } + + public Widget createButton(String name, CompoundNBT value, Runnable callback) { + INBT tag = value.get("value"); + if (tag == null) { + return null; + } + + byte type = tag.getId(); + if (type == Constants.NBT.TAG_INT) { + return new TerraSlider.Int(name + ": ", value).callback(callback); + } else if (type == Constants.NBT.TAG_FLOAT) { + return new TerraSlider.Float(name + ": ", value).callback(callback); + } else if (type == Constants.NBT.TAG_STRING && value.contains("#options")) { + return new Toggle(name + ": ", value).callback(callback); + } else if (type == Constants.NBT.TAG_STRING) { + return new TerraButton(name); + } else { + return null; + } + } + + public static class Column { + + public final int left; + public final int right; + public final int top; + public final int bottom; + public final int width; + public final int height; + public final ScrollPane scrollPane; + + private Column(int left, int top, int width, int height, int vpad, int hpad) { + this.left = left + vpad; + this.right = left + width - vpad; + this.top = top + hpad; + this.bottom = height - hpad; + this.width = width; + this.height = height; + this.scrollPane = new ScrollPane(22); + this.scrollPane.updateSize(width, height, 30, height - 30); + this.scrollPane.setLeftPos(this.left); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/RiverPage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/RiverPage.java new file mode 100644 index 0000000..484093b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/RiverPage.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class RiverPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT riverSettings; + + public RiverPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.riverSettings = NBTHelper.serialize(settings.rivers); + } + + @Override + public String getTitle() { + return "River Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(riverSettings, settings.rivers); + } + + @Override + public void init(OverlayScreen parent) { + Column center = getColumn(0); + center.scrollPane.setScrollAmount(0D); + addElements(0, 0, center, riverSettings, true, center.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(riverSettings, settings.rivers)); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/StructurePage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/StructurePage.java new file mode 100644 index 0000000..ed8a522 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/StructurePage.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.settings.TerraSettings; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class StructurePage extends BasePage { + + private final TerraSettings settings; + private final CompoundNBT structureSettings; + + public StructurePage(TerraSettings settings) { + this.settings = settings; + this.structureSettings = NBTHelper.serialize(settings.structures); + } + + @Override + public String getTitle() { + return "Structure Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(structureSettings, settings.structures); + } + + @Override + public void init(OverlayScreen parent) { + Column left = getColumn(0); + addElements(left.left, left.top, left, structureSettings, false, left.scrollPane::addButton, NO_CALLBACK); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/TerrainPage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/TerrainPage.java new file mode 100644 index 0000000..a5514ce --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/page/TerrainPage.java @@ -0,0 +1,66 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.page; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.preview.PreviewPage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +public class TerrainPage extends BasePage { + + private final Settings settings; + private final PreviewPage preview; + private final CompoundNBT terrainSettings; + + public TerrainPage(Settings settings, PreviewPage preview) { + this.settings = settings; + this.preview = preview; + this.terrainSettings = NBTHelper.serialize(settings.terrain); + } + + @Override + public String getTitle() { + return "Terrain Settings"; + } + + @Override + public void save() { + NBTHelper.deserialize(terrainSettings, settings.terrain); + } + + @Override + public void init(OverlayScreen parent) { + Column center = getColumn(0); + center.scrollPane.setScrollAmount(0D); + addElements(0, 0, center, terrainSettings, true, center.scrollPane::addButton, this::update); + } + + private void update() { + preview.apply(settings -> NBTHelper.deserialize(terrainSettings, settings.terrain)); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/Preview.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/Preview.java new file mode 100644 index 0000000..29599f8 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/Preview.java @@ -0,0 +1,259 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.terraforged.core.cell.Cell; +import com.terraforged.core.region.Region; +import com.terraforged.core.region.RegionGenerator; +import com.terraforged.core.settings.Settings; +import com.terraforged.core.util.concurrent.ThreadPool; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.WorldGeneratorFactory; +import com.terraforged.core.world.terrain.Terrain; +import com.terraforged.core.world.terrain.Terrains; +import com.terraforged.mod.util.nbt.NBTHelper; +import me.dags.noise.util.NoiseUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.widget.button.Button; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.NativeImage; +import net.minecraft.nbt.CompoundNBT; + +import java.awt.*; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class Preview extends Button { + + private static final int FACTOR = 4; + private static final int BLOCK_SIZE = 256;//Size.chunkToBlock(1 << FACTOR); + private static final float[] LEGEND_SCALES = {1, 0.9F, 0.75F, 0.6F}; + + private final int offsetX; + private final int offsetZ; + private final Random random = new Random(System.currentTimeMillis()); + private final PreviewSettings previewSettings = new PreviewSettings(); + private final DynamicTexture texture = new DynamicTexture(new NativeImage(BLOCK_SIZE, BLOCK_SIZE, true)); + + private int seed; + private long lastUpdate = 0L; + private Settings settings = new Settings(); + private Future task = null; + private Region region = null; + + private String[] labels = {"Area: ", "Terrain: ", "Biome: "}; + private String[] values = {"", "", ""}; + + public Preview() { + super(0, 0, 0, 0, "", b -> {}); + this.seed = random.nextInt(); + this.offsetX = random.nextInt(50000) - 25000; + this.offsetZ = random.nextInt(50000) - 25000; + } + + public void regenerate() { + this.seed = random.nextInt(); + } + + public void close() { + texture.close(); + } + + @Override + public void render(int mx, int my, float partialTicks) { + preRender(); + + texture.bindTexture(); + RenderSystem.enableBlend(); + RenderSystem.enableRescaleNormal(); + RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + + AbstractGui.blit(x, y, 0, 0, width, height, width, height); + RenderSystem.disableRescaleNormal(); + + updateLegend(mx, my); + renderLegend(labels, values, x + 1, y + height + 2, 15, 0xFFFFFF); + } + + public void update(Settings settings, CompoundNBT prevSettings) { + long time = System.currentTimeMillis(); + if (time - lastUpdate < 50) { + return; + } + lastUpdate = time; + + NBTHelper.deserialize(prevSettings, previewSettings); + settings.generator.seed = seed; + + task = generate(settings, prevSettings); + } + + private void preRender() { + if (task != null && task.isDone()) { + try { + region = task.get(); + render(region); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.getCause().printStackTrace(); + } finally { + task = null; + } + } + } + + private void render(Region region) { + NativeImage image = texture.getTextureData(); + if (image == null) { + return; + } + + RenderMode renderer = previewSettings.mode; + Terrains terrains = Terrains.create(settings); + GeneratorContext context = new GeneratorContext(terrains, settings); + + int stroke = 2; + int width = region.getBlockSize().size; + region.iterate((cell, x, z) -> { + if (x < stroke || z < stroke || x >= width - stroke || z >= width - stroke) { + image.setPixelRGBA(x, z, Color.black.getRGB()); + } else { + Color color = renderer.color(cell, context); + image.setPixelRGBA(x, z, RenderMode.rgba(color)); + } + }); + + texture.updateDynamicTexture(); + } + + private Future generate(Settings settings, CompoundNBT prevSettings) { + NBTHelper.deserialize(prevSettings, previewSettings); + settings.generator.seed = seed; + this.settings = settings; + + GeneratorContext context = new GeneratorContext(Terrains.create(settings), settings); + + RegionGenerator renderer = RegionGenerator.builder() + .factory(new WorldGeneratorFactory(context)) + .pool(ThreadPool.getCommon()) + .size(FACTOR, 0) + .build(); + + return renderer.generate(offsetX, offsetZ, 101 - previewSettings.zoom, false); + } + + private void updateLegend(int mx ,int my) { + if (region != null) { + int zoom = (101 - previewSettings.zoom); + int width = Math.max(1, region.getBlockSize().size * zoom); + int height = Math.max(1, region.getBlockSize().size * zoom); + values[0] = width + "x" + height; + + if (mx >= this.x && mx <= this.x + this.width && my >= this.y && my <= this.y + this.height) { + float fx = (mx - this.x) / (float) this.width; + float fz = (my - this.y) / (float) this.height; + int ix = NoiseUtil.round(fx * region.getBlockSize().size); + int iz = NoiseUtil.round(fz * region.getBlockSize().size); + Cell cell = region.getCell(ix, iz); + values[1] = getTerrainName(cell); + values[2] = getBiomeName(cell); + } + } + } + + private float getLegendScale() { + int index = Minecraft.getInstance().gameSettings.guiScale - 1; + if (index < 0 || index >= LEGEND_SCALES.length) { + // index=-1 == GuiScale(AUTO) which is the same as GuiScale(4) + // values above 4 don't exist but who knows what mods might try set it to + // in both cases use the smallest acceptable scale + index = LEGEND_SCALES.length - 1; + } + return LEGEND_SCALES[index]; + } + + private void renderLegend(String[] labels, String[] values, int left, int top, int lineHeight, int color) { + float scale = getLegendScale(); + lineHeight = Math.round(lineHeight * scale); + + RenderSystem.pushMatrix(); + RenderSystem.translatef(left, top, 0); + RenderSystem.scalef(scale, scale, 1); + + FontRenderer renderer = Minecraft.getInstance().fontRenderer; + int spacing = 0; + for (String s : labels) { + spacing = Math.max(spacing, renderer.getStringWidth(s)); + } + + int maxX = this.x + this.width; + for (int i = 0; i < labels.length && i < values.length; i++) { + String label = labels[i]; + String value = values[i]; + + while (left + spacing + Minecraft.getInstance().fontRenderer.getStringWidth(value) > maxX) { + value = value.substring(0, value.length() - 1); + } + + drawString(renderer, label, 0, i * lineHeight, color); + drawString(renderer, value, spacing, i * lineHeight, color); + } + + RenderSystem.popMatrix(); + } + + private static String getTerrainName(Cell cell) { + String terrain = cell.tag.getName().toLowerCase(); + if (terrain.contains("river")) { + return "river"; + } + return terrain; + } + + private static String getBiomeName(Cell cell) { + String terrain = cell.tag.getName().toLowerCase(); + if (terrain.contains("ocean")) { + if (cell.temperature < 0.3) { + return "cold_ocean"; + } + if (cell.temperature > 0.6) { + return "warm_ocean"; + } + return "ocean"; + } + if (terrain.contains("river")) { + return "river"; + } + return cell.biomeType.name().toLowerCase(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java new file mode 100644 index 0000000..b63103d --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java @@ -0,0 +1,100 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.terraforged.core.settings.Settings; +import com.terraforged.mod.gui.OverlayScreen; +import com.terraforged.mod.gui.element.TerraButton; +import com.terraforged.mod.gui.page.BasePage; +import com.terraforged.mod.util.nbt.NBTHelper; +import net.minecraft.nbt.CompoundNBT; + +import java.util.function.Consumer; + +public class PreviewPage extends BasePage { + + private final Preview preview = new Preview(); + private final Settings settings = new Settings(); + private final CompoundNBT previewerSettings = NBTHelper.serialize(new PreviewSettings()); + + public PreviewPage() { + + } + + public void apply(Consumer consumer) { + consumer.accept(settings); + preview.update(settings, previewerSettings); + } + + @Override + public void close() { + preview.close(); + } + + @Override + public void save() { + + } + + @Override + public void init(OverlayScreen parent) { + Column right = getColumn(1); + preview.x = 0; + preview.y = 0; + preview.setWidth(256); + preview.setHeight(256); + + addElements(right.left, right.top, right, previewerSettings, right.scrollPane::addButton, this::update); + right.scrollPane.addButton(new TerraButton("Generate") { + @Override + public void onPress() { + preview.regenerate(); + update(); + } + }); + + right.scrollPane.addButton(preview); + + // used to pad the scroll-pane out so that the preview legend scrolls on larger gui scales + TerraButton spacer = createSpacer(); + for (int i = 0; i < 6; i++) { + right.scrollPane.addButton(spacer); + } + + update(); + } + + private void update() { + preview.update(settings, previewerSettings); + } + + private static TerraButton createSpacer() { + return new TerraButton("") { + @Override + public void render(int x, int y, float tick) { } + }; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewSettings.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewSettings.java new file mode 100644 index 0000000..661c80c --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewSettings.java @@ -0,0 +1,36 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.terraforged.core.util.serialization.annotation.Range; + +public class PreviewSettings { + + @Range(min = 1, max = 100) + public int zoom = 100 - 32; + + public RenderMode mode = RenderMode.BIOME_TYPE; +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/RenderMode.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/RenderMode.java new file mode 100644 index 0000000..3bb8caa --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/RenderMode.java @@ -0,0 +1,83 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.gui.preview; + +import com.terraforged.core.cell.Cell; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.heightmap.Levels; +import com.terraforged.core.world.terrain.Terrain; +import me.dags.noise.util.NoiseUtil; + +import java.awt.*; + +public enum RenderMode { + BIOME_TYPE, + TEMPERATURE, + MOISTURE, + BIOME_SHAPE, + ; + + public Color color(Cell cell, GeneratorContext context) { + float baseHeight = Levels.getSeaLevel(context.settings.generator); + if (cell.value < baseHeight) { + return new Color(40, 140, 200); + } + + float bands = 10F; + float alpha = 0.15F; + float elevation = (cell.value - baseHeight) / (1F - baseHeight); + + int band = NoiseUtil.round(elevation * bands); + float scale = 1F - alpha; + float bias = alpha * (band / bands); + + float saturation = 0.7F; + float brightness = 0.8F; + + switch (this) { + case BIOME_SHAPE: + return Color.getHSBColor(cell.biome, saturation, brightness); + case BIOME_TYPE: + Color color = cell.biomeType.getColor(); + float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), new float[3]); + return Color.getHSBColor(hsb[0], hsb[1], (hsb[2] * scale) + bias); + case MOISTURE: + return Color.getHSBColor(step(1 - cell.moisture, 8) * 0.65F, saturation, brightness); + case TEMPERATURE: + return Color.getHSBColor(step(cell.temperature, 8) * 0.65F, saturation, brightness); + default: + return Color.black; + } + } + + private static float step(float value, int steps) { + return ((float) NoiseUtil.round(value * steps)) / steps; + } + + public static int rgba(Color color) { + return color.getRed() + (color.getGreen() << 8) + (color.getBlue() << 16) + (255 << 24); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/material/MaterialHelper.java b/TerraForgedMod/src/main/java/com/terraforged/mod/material/MaterialHelper.java new file mode 100644 index 0000000..fdc1360 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/material/MaterialHelper.java @@ -0,0 +1,151 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material; + +import com.google.common.collect.Sets; +import com.terraforged.core.util.concurrent.ObjectPool; +import com.terraforged.mod.util.DummyBlockReader; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ConcretePowderBlock; +import net.minecraft.block.material.Material; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.ConfiguredFeature; +import net.minecraft.world.gen.feature.DecoratedFeatureConfig; +import net.minecraft.world.gen.feature.OreFeatureConfig; +import net.minecraftforge.common.Tags; +import net.minecraftforge.registries.IForgeRegistryEntry; + +import java.util.Set; + +public class MaterialHelper { + + private static final Set BLACKLIST = Sets.newHashSet( + Blocks.INFESTED_CHISELED_STONE_BRICKS, + Blocks.INFESTED_COBBLESTONE, + Blocks.INFESTED_CRACKED_STONE_BRICKS, + Blocks.INFESTED_MOSSY_STONE_BRICKS, + Blocks.INFESTED_STONE, + Blocks.INFESTED_STONE_BRICKS, + Blocks.SLIME_BLOCK, + Blocks.RED_SAND, + Blocks.SOUL_SAND, + // honey etc + Blocks.HONEY_BLOCK, + Blocks.HONEYCOMB_BLOCK, + Blocks.BEE_NEST, + Blocks.BEEHIVE, + Blocks.COMPOSTER + ); + + public static boolean isAir(Block block) { + return block == Blocks.AIR || block == Blocks.CAVE_AIR || block == Blocks.VOID_AIR; + } + + public static boolean isGrass(Block block) { + return block == Blocks.GRASS_BLOCK || block == Blocks.MYCELIUM; + } + + public static boolean isStone(Block block) { + return Tags.Blocks.STONE.contains(block) + && !isBlacklisted(block) + && !("" + block.getRegistryName()).contains("polished_"); + } + + public static boolean isDirt(Block block) { + return Tags.Blocks.DIRT.contains(block) + && !isBlacklisted(block); + } + + public static boolean isClay(Block block) { + return block.getDefaultState().getMaterial() == Material.CLAY + && !isBlacklisted(block); + } + + public static boolean isSand(Block block) { + return BlockTags.SAND.contains(block) + && !isBlacklisted(block) + && !(block instanceof ConcretePowderBlock); + } + + public static boolean isSediment(Block block) { + return (isSand(block) || isGravel(block)) + && !isBlacklisted(block) + && !(block instanceof ConcretePowderBlock); + } + + public static boolean isGravel(Block block) { + return getName(block).contains("gravel"); + } + + public static boolean isOre(Block block) { + return Tags.Blocks.ORES.contains(block) + && !isBlacklisted(block); + } + + public static boolean isBlacklisted(Block block) { + return BLACKLIST.contains(block); + } + + public static String getName(IForgeRegistryEntry entry) { + return "" + entry.getRegistryName(); + } + + public static String getNamespace(IForgeRegistryEntry entry) { + ResourceLocation name = entry.getRegistryName(); + if (name == null) { + return "unknown"; + } + return name.getNamespace(); + } + + public static float getHardness(BlockState state) { + try (ObjectPool.Item reader = DummyBlockReader.pooled()) { + reader.getValue().set(state); + return state.getBlockHardness(reader.getValue(), BlockPos.ZERO); + } + } + + public static boolean isCube(BlockState state) { + try (ObjectPool.Item reader = DummyBlockReader.pooled()) { + reader.getValue().set(state); + return state.isNormalCube(reader.getValue(), BlockPos.ZERO); + } + } + + public static OreFeatureConfig getOreConfig(ConfiguredFeature feature) { + if (feature.config instanceof DecoratedFeatureConfig) { + DecoratedFeatureConfig config = (DecoratedFeatureConfig) feature.config; + if (config.feature.config instanceof OreFeatureConfig) { + return (OreFeatureConfig) config.feature.config; + } + } + return null; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/material/Materials.java b/TerraForgedMod/src/main/java/com/terraforged/mod/material/Materials.java new file mode 100644 index 0000000..aa42ad1 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/material/Materials.java @@ -0,0 +1,163 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material; + +import com.terraforged.api.material.MaterialTags; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.api.material.state.States; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.tags.Tag; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Predicate; + +public class Materials { + + private final Set stone = create(MaterialTags.WG_ROCK); + private final Set dirt = create(MaterialTags.WG_EARTH); + private final Set clay = create(MaterialTags.WG_CLAY); + private final Set sediment = create(MaterialTags.WG_SEDIMENT); + private final Set ore = create(MaterialTags.WG_ORE); + private final Set erodible = create(MaterialTags.WG_ERODIBLE); + private final LayerManager layerManager = new LayerManager(); + + public Materials() { + Predicate filter = getTagFilter(); + for (Block block : ForgeRegistries.BLOCKS) { + if (filter.test(block)) { + continue; + } + + if (!MaterialHelper.isCube(block.getDefaultState())) { + continue; + } + + if (MaterialHelper.isStone(block)) { + stone.add(block); + } else if (MaterialHelper.isDirt(block)) { + dirt.add(block); + } else if (MaterialHelper.isClay(block)) { + clay.add(block); + } else if (MaterialHelper.isSediment(block)) { + sediment.add(block); + } else if (MaterialHelper.isOre(block)) { + ore.add(block); + } + } + + if (stone.isEmpty()) { + stone.add(Blocks.STONE); + } + } + + public LayerManager getLayerManager() { + return layerManager; + } + + public boolean isStone(Block block) { + return stone.contains(block); + } + + public boolean isEarth(Block block) { + return dirt.contains(block); + } + + public boolean isClay(Block block) { + return clay.contains(block); + } + + public boolean isSediment(Block block) { + return sediment.contains(block); + } + + public boolean isOre(Block block) { + return ore.contains(block); + } + + public boolean isErodible(Block block) { + return erodible.contains(block); + } + + public Collection getStone() { + if (stone.isEmpty()) { + return Collections.singleton(States.STONE.getBlock()); + } + return Collections.unmodifiableSet(stone); + } + + public Collection getDirt() { + if (dirt.isEmpty()) { + return Collections.singleton(States.DIRT.getBlock()); + } + return Collections.unmodifiableSet(dirt); + } + + public Collection getClay() { + if (clay.isEmpty()) { + return Collections.singleton(States.STONE.getBlock()); + } + return Collections.unmodifiableSet(clay); + } + + public Collection getSediment() { + if (sediment.isEmpty()) { + return Collections.singleton(States.CLAY.getBlock()); + } + return Collections.unmodifiableSet(sediment); + } + + public Collection getOre() { + if (ore.isEmpty()) { + return Collections.singleton(States.STONE.getBlock()); + } + return Collections.unmodifiableSet(ore); + } + + private static Set create(Tag tag) { + return new HashSet<>(tag.getAllElements()); + } + + private static Predicate getTagFilter() { + Set namespaces = new HashSet<>(); + collectNamespace(namespaces, MaterialTags.WG_ROCK.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_EARTH.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_EARTH.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_SEDIMENT.getAllElements()); + collectNamespace(namespaces, MaterialTags.WG_ORE.getAllElements()); + return b -> namespaces.contains(MaterialHelper.getNamespace(b)); + } + + private static void collectNamespace(Set set, Collection blocks) { + for (Block block : blocks) { + set.add(MaterialHelper.getNamespace(block)); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/material/geology/GeoGenerator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/material/geology/GeoGenerator.java new file mode 100644 index 0000000..75a770a --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/material/geology/GeoGenerator.java @@ -0,0 +1,118 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material.geology; + +import com.terraforged.api.material.geology.StrataConfig; +import com.terraforged.api.material.geology.StrataGenerator; +import com.terraforged.core.world.geology.Strata; +import com.terraforged.mod.material.MaterialHelper; +import com.terraforged.mod.material.Materials; +import me.dags.noise.Source; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Random; + +public class GeoGenerator implements StrataGenerator { + + private final List rock; + private final List soil; + private final List clay; + private final List sediment; + private final List types = new ArrayList<>(); + + public GeoGenerator(Materials materials) { + types.add(Source.PERLIN); + rock = new ArrayList<>(materials.getStone()); + soil = new ArrayList<>(materials.getDirt()); + clay = new ArrayList<>(materials.getClay()); + sediment = new ArrayList<>(materials.getSediment()); + } + + @Override + public Strata generate(int seed, int scale, StrataConfig config) { + Random random = new Random(); + Strata.Builder builder = Strata.builder(++seed, Source.build(++seed, scale, 3)); + addLayer(seed + 1, random, config.soil, soil, builder); + addLayer(seed + 2, random, config.sediment, sediment, builder); + addLayer(seed + 3, random, config.clay, clay, builder); + addLayer(seed + 4, random, config.rock, rock, builder); + return builder.build(); + } + + private void addLayer(int seed, Random random, StrataConfig.Config config, List materials, Strata.Builder builder) { + random.setSeed(seed); + List layers = generateLayers(materials, config, random); + layers.forEach(l -> builder.add(l.type, l.state, l.depth)); + } + + private List generateLayers(List materials, StrataConfig.Config config, Random random) { + int lastIndex = -1; + int layers = config.getLayers(random.nextFloat()); + List result = new ArrayList<>(); + for (int i = 0; i < layers; i++) { + int attempts = 3; + int index = random.nextInt(materials.size()); + while (--attempts >= 0 && index == lastIndex) { + index = random.nextInt(materials.size()); + } + if (index != lastIndex) { + lastIndex = index; + BlockState material = materials.get(index).getDefaultState(); + float depth = config.getDepth(random.nextFloat()); + Source type = nextType(random); + result.add(new Layer(material, depth, type)); + } + } + return result; + } + + private Source nextType(Random random) { + int index = random.nextInt(types.size()); + return types.get(index); + } + + private List sortHardness(List layers) { + layers.sort(Comparator.comparing(s -> MaterialHelper.getHardness(s.state))); + return layers; + } + + private static class Layer { + + private final BlockState state; + private final float depth; + private final Source type; + + private Layer(BlockState state, float depth, Source type) { + this.state = state; + this.depth = depth; + this.type = type; + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/material/geology/GeoManager.java b/TerraForgedMod/src/main/java/com/terraforged/mod/material/geology/GeoManager.java new file mode 100644 index 0000000..2b6634b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/material/geology/GeoManager.java @@ -0,0 +1,116 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.material.geology; + +import com.terraforged.api.material.geology.GeologyManager; +import com.terraforged.api.material.geology.StrataConfig; +import com.terraforged.core.util.Seed; +import com.terraforged.core.world.geology.Geology; +import com.terraforged.core.world.geology.Strata; +import com.terraforged.mod.chunk.TerraContext; +import com.terraforged.mod.material.Materials; +import me.dags.noise.Module; +import me.dags.noise.Source; +import net.minecraft.block.BlockState; +import net.minecraft.world.biome.Biome; + +import java.util.HashMap; +import java.util.Map; + +public class GeoManager implements GeologyManager { + + private final Module selector; + private final Materials materials; + private final GeoGenerator builder; + private final Geology general; + private final Map> specific = new HashMap<>(); + + public GeoManager(TerraContext context) { + int scale = context.settings.generator.land.regionSize / 2; + this.selector = Source.cell(context.seed.next(), scale) + .warp(context.seed.next(), scale / 4, 2, scale / 2D) + .warp(context.seed.next(), 15, 2, 30); + this.builder = new GeoGenerator(context.materials); + this.general = new Geology<>(selector); + this.materials = context.materials; + init(context.seed); + } + + public GeoGenerator getStrataGenerator() { + return builder; + } + + @Override + public void register(Strata strata) { + general.add(strata); + } + + @Override + public void register(Biome biome, Strata strata) { + register(biome, strata, false); + } + + /** + * Register a biome specific strata group. + * If a specific geology doesn't exist for a given biome, the global geology can optionally be added using + * the 'inheritGlobal' flag. + */ + public void register(Biome biome, Strata strata, boolean inheritGlobal) { + Geology geology = specific.get(biome); + if (geology == null) { + geology = new Geology<>(selector); + specific.put(biome, geology); + if (inheritGlobal) { + geology.add(general); + } + } + geology.add(strata); + } + + /** + * Register/replace a biome-specific geology group + */ + public void register(Biome biome, Geology geology) { + specific.put(biome, geology); + } + + public Geology getGeology(Biome biome) { + return specific.getOrDefault(biome, general); + } + + public Strata getStrata(Biome biome, float value) { + return getGeology(biome).getStrata(value); + } + + private void init(Seed seed) { + StrataConfig config = new StrataConfig(); + GeoGenerator generator = new GeoGenerator(materials); + for (int i = 0; i < 10; i++) { + Strata strata = generator.generate(seed.next(), 128, config); + general.add(strata); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/settings/FeatureSettings.java b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/FeatureSettings.java new file mode 100644 index 0000000..e623ae5 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/FeatureSettings.java @@ -0,0 +1,48 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.settings; + +import com.terraforged.core.util.serialization.annotation.Comment; +import com.terraforged.core.util.serialization.annotation.Serializable; + +@Serializable +public class FeatureSettings { + + @Comment("Modifies layer block levels (ie snow) to fit the terrain") + public boolean smoothLayerDecorator = true; + + @Comment("Generates strata (rock layers) instead of just stone") + public boolean strataDecorator = true; + + @Comment("Replace surface materials where erosion has occurred") + public boolean erosionDecorator = true; + + @Comment("Removes snow from the terrain where it shouldn't naturally settle") + public boolean naturalSnowDecorator = true; + + @Comment("Use custom biome features in place of vanilla ones (such as trees)") + public boolean customBiomeFeatures = true; +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/settings/StructureSettings.java b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/StructureSettings.java new file mode 100644 index 0000000..cc77d11 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/StructureSettings.java @@ -0,0 +1,58 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.settings; + +import com.terraforged.core.util.serialization.annotation.Comment; +import com.terraforged.core.util.serialization.annotation.Range; +import com.terraforged.core.util.serialization.annotation.Serializable; + +@Serializable +public class StructureSettings { + + @Range(min = 1, max = 10) + @Comment("Controls the distance between villages") + public int villageDistance = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between mansions") + public int mansionDistance = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between strongholds") + public int strongholdDistance = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between biome structures") + public int biomeStructureDistance = 2; + + @Range(min = 1, max = 10) + @Comment("Controls the distance between ocean monuments") + public int oceanMonumentSpacing = 4; + + @Range(min = 1, max = 10) + @Comment("Controls the separation between ocean monuments") + public int oceanMonumentSeparation = 4; +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/settings/TerraSettings.java b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/TerraSettings.java new file mode 100644 index 0000000..1dc1b42 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/TerraSettings.java @@ -0,0 +1,37 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.settings; + +import com.terraforged.core.settings.Settings; +import com.terraforged.core.util.serialization.annotation.Serializable; + +@Serializable +public class TerraSettings extends Settings { + + public FeatureSettings features = new FeatureSettings(); + + public StructureSettings structures = new StructureSettings(); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/DummyBlockReader.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/DummyBlockReader.java new file mode 100644 index 0000000..00254c4 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/DummyBlockReader.java @@ -0,0 +1,80 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util; + +import com.terraforged.core.util.concurrent.ObjectPool; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.fluid.IFluidState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; + +import javax.annotation.Nullable; + +public class DummyBlockReader implements IBlockReader { + + private static final ObjectPool pool = new ObjectPool<>(10, DummyBlockReader::new); + + private BlockState state; + private IFluidState fluid; + + public DummyBlockReader set(BlockState state) { + return set(state, Fluids.EMPTY.getDefaultState()); + } + + public DummyBlockReader set(FluidState fluid) { + return set(Blocks.AIR.getDefaultState(), fluid); + } + + public DummyBlockReader set(BlockState state, IFluidState fluid) { + this.state = state; + this.fluid = fluid; + return this; + } + + @Nullable + @Override + public TileEntity getTileEntity(BlockPos pos) { + return null; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return state; + } + + @Override + public IFluidState getFluidState(BlockPos pos) { + return fluid; + } + + public static ObjectPool.Item pooled() { + return pool.get(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/Environment.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/Environment.java new file mode 100644 index 0000000..d539ac0 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/Environment.java @@ -0,0 +1,43 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util; + +import com.terraforged.mod.Log; + +public class Environment { + + private static final boolean dev = System.getProperty("dev") != null; + + public static boolean isDev() { + return dev; + } + + static { + if (dev) { + Log.info("Running in developer mode!"); + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/ListUtils.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/ListUtils.java new file mode 100644 index 0000000..608d5be --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/ListUtils.java @@ -0,0 +1,74 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util; + +import me.dags.noise.util.NoiseUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ListUtils { + + public static T get(List list, float value, T def) { + if (list.isEmpty()) { + return def; + } + return get(list, list.size() - 1, value, def); + } + + public static T get(List list, int maxIndex, float value, T def) { + int index = NoiseUtil.round(value * maxIndex); + if (index < list.size()) { + return list.get(index); + } + return def; + } + + public static List minimize(List list) { + Map counts = count(list); + List result = new ArrayList<>(list.size()); + int min = counts.values().stream().min(Integer::compareTo).orElse(1); + for (T t : list) { + int count = counts.get(t); + int amount = count / min; + for (int i = 0; i < amount; i++) { + result.add(t); + } + } + return result; + } + + public static Map count(List list) { + Map map = new HashMap<>(list.size()); + for (T t : list) { + int count = map.getOrDefault(t, 0); + map.put(t, ++count); + } + return map; + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/annotation/Name.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/annotation/Name.java new file mode 100644 index 0000000..4809ef9 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/annotation/Name.java @@ -0,0 +1,31 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.annotation; + +public @interface Name { + + String value(); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/annotation/Ref.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/annotation/Ref.java new file mode 100644 index 0000000..b63e01b --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/annotation/Ref.java @@ -0,0 +1,31 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.annotation; + +public @interface Ref { + + Class[] value(); +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java new file mode 100644 index 0000000..3a07f3d --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java @@ -0,0 +1,116 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.nbt; + +import com.google.gson.JsonElement; +import com.mojang.datafixers.Dynamic; +import com.mojang.datafixers.types.JsonOps; +import com.terraforged.core.util.serialization.serializer.Serializer; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.nbt.NBTDynamicOps; + +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Stream; + +public class NBTHelper { + + public static JsonElement toJson(CompoundNBT tag) { + Dynamic input = new Dynamic<>(NBTDynamicOps.INSTANCE, tag); + Dynamic output = input.convert(JsonOps.INSTANCE); + return output.getValue(); + } + + public static Stream stream(CompoundNBT tag) { + return tag.keySet().stream() + .map(tag::getCompound) + .sorted(Comparator.comparing(t -> t.getInt("#order"))); + + } + + public static CompoundNBT serialize(Object object) { + try { + NBTWriter writer = new NBTWriter(); + writer.readFrom(object); + return writer.compound(); + } catch (IllegalAccessException e) { + return new CompoundNBT(); + } + } + + public static CompoundNBT serializeCompact(Object object) { + try { + NBTWriter writer = new NBTWriter(); + writer.readFrom(object); + return stripMetadata(writer.compound()); + } catch (IllegalAccessException e) { + return new CompoundNBT(); + } + } + + public static CompoundNBT readCompact(Object object) { + try { + NBTWriter writer = new NBTWriter(); + writer.readFrom(object); + new Serializer().serialize(object, writer); + return writer.compound(); + } catch (IllegalAccessException e) { + return new CompoundNBT(); + } + } + + public static T stripMetadata(T tag) { + if (tag instanceof CompoundNBT) { + CompoundNBT compound = (CompoundNBT) tag; + List keys = new LinkedList<>(compound.keySet()); + for (String key : keys) { + if (key.charAt(0) == '#') { + compound.remove(key); + } else { + stripMetadata(compound.get(key)); + } + } + } else if (tag instanceof ListNBT) { + ListNBT list = (ListNBT) tag; + for (int i = 0; i < list.size(); i++) { + stripMetadata(list.get(i)); + } + } + return tag; + } + + public static void deserialize(CompoundNBT settings, Object object) { + try { + NBTReader reader = new NBTReader(settings); + reader.writeTo(object); + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTReader.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTReader.java new file mode 100644 index 0000000..2ed5270 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTReader.java @@ -0,0 +1,121 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.nbt; + +import com.terraforged.core.util.serialization.serializer.Reader; +import net.minecraft.nbt.ByteNBT; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.FloatNBT; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.IntNBT; +import net.minecraft.nbt.ListNBT; + +import java.util.Collection; + +public class NBTReader implements Reader { + + private final INBT root; + + public NBTReader(INBT root) { + this.root = root; + } + + @Override + public int getSize() { + if (root instanceof CompoundNBT) { + return ((CompoundNBT) root).size(); + } + if (root instanceof ListNBT) { + return ((ListNBT) root).size(); + } + return 1; + } + + @Override + public NBTReader getChild(String key) { + return new NBTReader(((CompoundNBT) root).get(key)); + } + + @Override + public NBTReader getChild(int index) { + return new NBTReader(((ListNBT) root).get(index)); + } + + @Override + public Collection getKeys() { + return ((CompoundNBT) root).keySet(); + } + + @Override + public String getString(String key) { + return ((CompoundNBT) root).getString(key); + } + + @Override + public float getFloat(String key) { + return ((CompoundNBT) root).getFloat(key); + } + + @Override + public int getInt(String key) { + return ((CompoundNBT) root).getInt(key); + } + + @Override + public String getString(int index) { + return ((ListNBT) root).getString(index); + } + + @Override + public float getFloat(int index) { + return ((ListNBT) root).getFloat(index); + } + + @Override + public int getInt(int index) { + return ((ListNBT) root).getInt(index); + } + + @Override + public String getString() { + return root.getString(); + } + + @Override + public boolean getBool() { + return ((ByteNBT) root).getByte() == 1; + } + + @Override + public float getFloat() { + return ((FloatNBT) root).getFloat(); + } + + @Override + public int getInt() { + return ((IntNBT) root).getInt(); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTWriter.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTWriter.java new file mode 100644 index 0000000..a2a0550 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/nbt/NBTWriter.java @@ -0,0 +1,132 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.nbt; + +import com.terraforged.core.util.serialization.serializer.Writer; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.FloatNBT; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.IntNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.nbt.StringNBT; + +public class NBTWriter implements Writer { + + private final Context root = new Context(null); + + private String name = ""; + private Context context = root; + + public NBTWriter() { + + } + + public INBT root() { + return root.value; + } + + public CompoundNBT compound() { + return (CompoundNBT) root(); + } + + public ListNBT list() { + return (ListNBT) root(); + } + + private NBTWriter begin(INBT value) { + if (root.value == null) { + root.value = value; + context.value = value; + } else { + append(value); + context = new Context(context); + context.value = value; + } + return this; + } + + private NBTWriter append(INBT value) { + if (context.value instanceof CompoundNBT) { + ((CompoundNBT) context.value).put(name, value); + } else if (context.value instanceof ListNBT) { + ((ListNBT) context.value).add(value); + } + return this; + } + + @Override + public NBTWriter name(String name) { + this.name = name; + return this; + } + + @Override + public NBTWriter beginObject() { + return begin(new CompoundNBT()); + } + + @Override + public NBTWriter endObject() { + context = context.parent; + return this; + } + + @Override + public NBTWriter beginArray() { + return begin(new ListNBT()); + } + + @Override + public NBTWriter endArray() { + context = context.parent; + return this; + } + + @Override + public NBTWriter value(String value) { + return append(StringNBT.valueOf(value)); + } + + @Override + public NBTWriter value(float value) { + return append(FloatNBT.valueOf(value)); + } + + @Override + public NBTWriter value(int value) { + return append(IntNBT.valueOf(value)); + } + + private static class Context { + + private final Context parent; + private INBT value; + + private Context(Context root) { + this.parent = root; + } + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/setup/SetupDebug.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/setup/SetupDebug.java new file mode 100644 index 0000000..f0b73da --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/setup/SetupDebug.java @@ -0,0 +1,69 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.setup; + +import com.terraforged.api.event.SetupEvent; +import com.terraforged.mod.Log; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) +public class SetupDebug { + + @SubscribeEvent + public static void terrain(SetupEvent.Terrain event) { + log(event); + } + + @SubscribeEvent + public static void surface(SetupEvent.Surface event) { + log(event); + } + + @SubscribeEvent + public static void layers(SetupEvent.Layers event) { + log(event); + } + + @SubscribeEvent + public static void geology(SetupEvent.Geology event) { + log(event); + } + + @SubscribeEvent + public static void features(SetupEvent.Features event) { + log(event); + } + + @SubscribeEvent + public static void columns(SetupEvent.Decorators event) { + log(event); + } + + private static void log(SetupEvent event) { + Log.debug("Setting up {}", event.getManager().getClass().getSimpleName()); + } +} diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/util/setup/SetupHooks.java b/TerraForgedMod/src/main/java/com/terraforged/mod/util/setup/SetupHooks.java new file mode 100644 index 0000000..f533316 --- /dev/null +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/util/setup/SetupHooks.java @@ -0,0 +1,77 @@ +/* + * + * MIT License + * + * Copyright (c) 2020 TerraForged + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.terraforged.mod.util.setup; + +import com.terraforged.api.biome.modifier.ModifierManager; +import com.terraforged.api.chunk.column.ColumnDecorator; +import com.terraforged.api.chunk.column.DecoratorManager; +import com.terraforged.api.chunk.surface.SurfaceManager; +import com.terraforged.api.event.SetupEvent; +import com.terraforged.api.material.geology.GeologyManager; +import com.terraforged.api.material.layer.LayerManager; +import com.terraforged.core.world.GeneratorContext; +import com.terraforged.core.world.terrain.provider.TerrainProvider; +import com.terraforged.feature.modifier.FeatureModifiers; +import net.minecraftforge.common.MinecraftForge; + +import java.util.List; + +public class SetupHooks { + + public static T setup(T provider, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.Terrain(provider, context)); + return provider; + } + + public static T setup(T manager, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.Surface(manager, context)); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.BiomeModifier(manager, context)); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.Layers(manager, context)); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.Geology(manager, context)); + return manager; + } + + public static T setup(T manager, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.Features(manager, context)); + return manager; + } + + public static void setup(List base, List feature, GeneratorContext context) { + MinecraftForge.EVENT_BUS.post(new SetupEvent.Decorators(new DecoratorManager(base, feature), context)); + } +} diff --git a/TerraForgedMod/src/main/resources/META-INF/mods.toml b/TerraForgedMod/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..d0976c2 --- /dev/null +++ b/TerraForgedMod/src/main/resources/META-INF/mods.toml @@ -0,0 +1,12 @@ +modLoader="javafml" +loaderVersion="[31,)" +[[mods]] +modId="terraforged" +displayName="TerraForged" +version="${version}" +authors="dags" +credits="dags" +logoFile="terraforged.png" +displayURL="https://terraforged.com" +issueTrackerURL="https://github.com/TerraForged/TerraForged/issues" +description="A 'terrain first' world generator" \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/assets/terraforged/lang/en_us.json b/TerraForgedMod/src/main/resources/assets/terraforged/lang/en_us.json new file mode 100644 index 0000000..075525d --- /dev/null +++ b/TerraForgedMod/src/main/resources/assets/terraforged/lang/en_us.json @@ -0,0 +1,4 @@ +{ + "generator.terraforged": "TerraForged", + "generator.terratest": "TerraTest" +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/biomes.txt b/TerraForgedMod/src/main/resources/biomes.txt new file mode 100644 index 0000000..8abd632 --- /dev/null +++ b/TerraForgedMod/src/main/resources/biomes.txt @@ -0,0 +1,13 @@ +#TerraForged BiomeType Hex Colors (do not include hash/pound character) +#Fri Jan 10 23:15:10 GMT 2020 +ALPINE=4b7835 +TAIGA=4b7835 +TEMPERATE_RAINFOREST=3c602b +TUNDRA=ba9d47 +TROPICAL_RAINFOREST=4aa73a +SAVANNA=389a38 +GRASSLAND=429545 +TEMPERATE_FOREST=456938 +STEPPE=c3aa61 +DESERT=e5d98f +COLD_STEPPE=a7a374 \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/coal.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/coal.json new file mode 100644 index 0000000..ffc6646 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/coal.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:coal" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 17, + "target": "natural_stone", + "state": { + "Name": "minecraft:coal_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 20, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 160 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/diamond.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/diamond.json new file mode 100644 index 0000000..a937721 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/diamond.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:diamond_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 8, + "target": "natural_stone", + "state": { + "Name": "minecraft:diamond_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 1, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 32 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/gold.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/gold.json new file mode 100644 index 0000000..4bcbeba --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/gold.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:gold_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 9, + "target": "natural_stone", + "state": { + "Name": "minecraft:gold_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 2, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 80 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/gold_extra.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/gold_extra.json new file mode 100644 index 0000000..58d0771 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/gold_extra.json @@ -0,0 +1,39 @@ +{ + "biomes": [ + "minecraft:badlands*", + "minecraft:eroded_badlands*", + "minecraft:modified_badlands*", + "minecraft:modified_wooded_badlands*", + "minecraft:wooded_badlands*" + ], + "match": [ + [ + "minecraft:ore", + "minecraft:gold_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 9, + "target": "natural_stone", + "state": { + "Name": "minecraft:gold_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 20, + "bottom_offset": 64, + "top_offset": 64, + "maximum": 112 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/iron.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/iron.json new file mode 100644 index 0000000..e324866 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/iron.json @@ -0,0 +1,32 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:iron_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 9, + "target": "natural_stone", + "state": { + "Name": "minecraft:iron_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 20, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 112 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/lapis.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/lapis.json new file mode 100644 index 0000000..189b069 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/lapis.json @@ -0,0 +1,31 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:lapis_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 7, + "target": "natural_stone", + "state": { + "Name": "minecraft:lapis_ore" + } + } + }, + "decorator": { + "name": "minecraft:count_depth_average", + "config": { + "count": 1, + "baseline": 32, + "spread": 32 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/ores/redstone.json b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/redstone.json new file mode 100644 index 0000000..55fa194 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/ores/redstone.json @@ -0,0 +1,35 @@ +{ + "match": [ + [ + "minecraft:ore", + "minecraft:redstone_ore" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:ore", + "config": { + "size": 8, + "target": "natural_stone", + "state": { + "Name": "minecraft:redstone_ore", + "Properties": { + "lit": "false" + } + } + } + }, + "decorator": { + "name": "minecraft:count_range", + "config": { + "count": 8, + "bottom_offset": 0, + "top_offset": 0, + "maximum": 64 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/shrubs/dead_bush.json b/TerraForgedMod/src/main/resources/data/terraforged/features/shrubs/dead_bush.json new file mode 100644 index 0000000..f19f718 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/shrubs/dead_bush.json @@ -0,0 +1,42 @@ +{ + "match": [ + [ + "minecraft:decorated", + "minecraft:dead_bush" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:dead_bush" + } + }, + "block_placer": { + "type": "minecraft:simple_block_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 2, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": true, + "need_water": false + } + }, + "decorator": { + "name": "minecraft:count_heightmap_double", + "config": { + "count": 3 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/shrubs/forest_grass.json b/TerraForgedMod/src/main/resources/data/terraforged/features/shrubs/forest_grass.json new file mode 100644 index 0000000..e6a19e9 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/shrubs/forest_grass.json @@ -0,0 +1,52 @@ +{ + "biomes": [ + "minecraft:birch_forest", + "minecraft:birch_forest_hills", + "minecraft:forest", + "minecraft:forest_hills", + "minecraft:dark_forest", + "minecraft:dark_forest_hills" + ], + "match": [ + [ + "minecraft:decorated", + "minecraft:grass" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_patch", + "config": { + "state_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:grass" + } + }, + "block_placer": { + "type": "minecraft:simple_block_placer" + }, + "whitelist": [], + "blacklist": [], + "tries": 32, + "xspread": 7, + "yspread": 3, + "zspread": 7, + "can_replace": false, + "project": true, + "need_water": false + } + }, + "decorator": { + "name": "minecraft:noise_heightmap_double", + "config": { + "noise_level": -0.8, + "below_noise": 5, + "above_noise": 10 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/acacia.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/acacia.json new file mode 100644 index 0000000..cf5e9ac --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/acacia.json @@ -0,0 +1,42 @@ +{ + "match": [ + [ + "minecraft:acacia_log", + "minecraft:acacia_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:acacia_large", + "config": {}, + "chance": 0.4 + }, + { + "name": "terraforged:acacia_small", + "config": {}, + "chance": 0.15 + } + ], + "default": { + "name": "terraforged:acacia_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 0, + "extra_chance": 0.2, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/birch.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/birch.json new file mode 100644 index 0000000..aa2313d --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/birch.json @@ -0,0 +1,45 @@ +{ + "biomes": [ + "minecraft:birch_forest*" + ], + "match": [ + [ + "minecraft:birch_log", + "minecraft:birch_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_large", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:birch_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 21, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/birch_oak.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/birch_oak.json new file mode 100644 index 0000000..e9ffca8 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/birch_oak.json @@ -0,0 +1,57 @@ +{ + "biomes": [ + "minecraft:wooded_hills" + ], + "match": [ + [ + "minecraft:birch_log", + "minecraft:birch_leaves", + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_large", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_large", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:birch_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 20, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/dark_oak.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/dark_oak.json new file mode 100644 index 0000000..71c52a3 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/dark_oak.json @@ -0,0 +1,56 @@ +{ + "biomes": [ + "minecraft:dark_forest", + "minecraft:dark_forest_hills" + ], + "match": [ + [ + "minecraft:dark_oak_log", + "minecraft:dark_oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:dark_oak_large", + "config": {}, + "chance": 0.3 + }, + { + "name": "terraforged:dark_oak_small", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.05 + }, + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.025 + } + ], + "default": { + "name": "terraforged:dark_oak_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 10, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/jungle.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/jungle.json new file mode 100644 index 0000000..f13ec01 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/jungle.json @@ -0,0 +1,73 @@ +{ + "match": [ + [ + "minecraft:mega_jungle_tree" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:jungle_small", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:jungle_large", + "config": {}, + "chance": 0.3 + }, + { + "name": "terraforged:jungle_huge", + "config": {}, + "chance": 0.4 + }, + { + "name": "minecraft:jungle_ground_bush", + "config": { + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:jungle_log", + "Properties": { + "axis": "y" + } + } + }, + "leaves_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:oak_leaves", + "Properties": { + "distance": "7", + "persistent": "false" + } + } + }, + "decorators": [], + "base_height": 4 + }, + "chance": 0.5 + } + ], + "default": { + "name": "terraforged:jungle_small", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 15, + "extra_chance": 0.25, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_badlands.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_badlands.json new file mode 100644 index 0000000..6166a24 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_badlands.json @@ -0,0 +1,43 @@ +{ + "biomes": [ + "minecraft:wooded_badlands*", + "minecraft:shattered_savanna*", + "minecraft:modified_badlands*", + "minecraft:modified_wooded*" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:oak_small", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:oak_small", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 4, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_forest.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_forest.json new file mode 100644 index 0000000..dd1ff71 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_forest.json @@ -0,0 +1,45 @@ +{ + "biomes": [ + "minecraft:forest" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_large", + "config": {}, + "chance": 0.3 + } + ], + "default": { + "name": "terraforged:oak_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 10, + "extra_chance": 0.1, + "extra_count": 2 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json new file mode 100644 index 0000000..da7e09d --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json @@ -0,0 +1,46 @@ +{ + "biomes": [ + "minecraft:plains", + "minecraft:flower_forest" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:oak_huge", + "config": {}, + "chance": 0.1 + }, + { + "name": "terraforged:oak_small", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:oak_small", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 0, + "extra_chance": 0.02, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/pine.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/pine.json new file mode 100644 index 0000000..e3b26b3 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/pine.json @@ -0,0 +1,44 @@ +{ + "biomes": [ + "minecraft:taiga", + "minecraft:taiga_hills", + "minecraft:taiga_mountains", + "minecraft:taiga_scrub" + ], + "match": [ + [ + "minecraft:normal_tree", + "minecraft:spruce_log", + "minecraft:spruce_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:pine", + "config": {}, + "chance": 0.3 + } + ], + "default": { + "name": "terraforged:pine", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 8, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/redwood.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/redwood.json new file mode 100644 index 0000000..69f0998 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/redwood.json @@ -0,0 +1,46 @@ +{ + "match": [ + [ + "minecraft:mega_spruce_tree" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:redwood_huge", + "config": {}, + "chance": 0.025641026 + }, + { + "name": "terraforged:pine", + "config": {}, + "chance": 0.15 + }, + { + "name": "terraforged:redwood_large", + "config": {}, + "chance": 0.33333334 + } + ], + "default": { + "name": "terraforged:redwood_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 10, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/spruce.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/spruce.json new file mode 100644 index 0000000..f145636 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/spruce.json @@ -0,0 +1,46 @@ +{ + "biomes": [ + "minecraft:snowy_taiga", + "minecraft:snowy_taiga_hills", + "minecraft:snowy_taiga_mountains", + "minecraft:snowy_taiga_scrub", + "minecraft:snowy_tundra", + "minecraft:wooded_mountains" + ], + "match": [ + [ + "minecraft:normal_tree", + "minecraft:spruce_log", + "minecraft:spruce_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:pine", + "config": {}, + "chance": 0.3 + } + ], + "default": { + "name": "terraforged:pine", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 8, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/willow.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/willow.json new file mode 100644 index 0000000..ba31490 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/willow.json @@ -0,0 +1,48 @@ +{ + "action": "replace", + "biomes": [ + "minecraft:swamp", + "minecraft:swamp_hills" + ], + "match": [ + [ + "minecraft:normal_tree", + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:willow_small", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:willow_large", + "config": {}, + "chance": 0.35 + } + ], + "default": { + "name": "terraforged:willow_large", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 8, + "extra_chance": 0.1, + "extra_count": 1 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_1.nbt new file mode 100644 index 0000000..d6dc4ac Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_2.nbt new file mode 100644 index 0000000..d6dc4ac Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/bush/acacia_bush_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_1.nbt new file mode 100644 index 0000000..17e91d1 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_2.nbt new file mode 100644 index 0000000..c80c016 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/large/acacia_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_1.nbt new file mode 100644 index 0000000..de1dc6d Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_2.nbt new file mode 100644 index 0000000..fbfe087 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/acacia/small/acacia_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_1.nbt new file mode 100644 index 0000000..a207f2e Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_2.nbt new file mode 100644 index 0000000..e20cd28 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_3.nbt new file mode 100644 index 0000000..e14b0e1 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_4.nbt new file mode 100644 index 0000000..03675e3 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/forest/forest_birch_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_1.nbt new file mode 100644 index 0000000..3ecd569 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_2.nbt new file mode 100644 index 0000000..a729f97 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_3.nbt new file mode 100644 index 0000000..28c32ab Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/large/birch_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_1.nbt new file mode 100644 index 0000000..7d6a7e5 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_2.nbt new file mode 100644 index 0000000..680adee Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_bush_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_1.nbt new file mode 100644 index 0000000..6499e1c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_2.nbt new file mode 100644 index 0000000..559a1b0 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/birch/small/birch_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_1.nbt new file mode 100644 index 0000000..b0dced8 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_2.nbt new file mode 100644 index 0000000..bcd2635 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_3.nbt new file mode 100644 index 0000000..3d5c4a8 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_4.nbt new file mode 100644 index 0000000..f7a72fc Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_5.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_5.nbt new file mode 100644 index 0000000..a20faf1 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/large/dark_oak_tall_5.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_1.nbt new file mode 100644 index 0000000..f4cefe7 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_2.nbt new file mode 100644 index 0000000..aca73e6 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_3.nbt new file mode 100644 index 0000000..e271a5d Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_1.nbt new file mode 100644 index 0000000..4c39cfd Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_2.nbt new file mode 100644 index 0000000..9202c79 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/dark_oak/small/dark_oak_bush_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_1.nbt new file mode 100644 index 0000000..533df04 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_2.nbt new file mode 100644 index 0000000..0b86d6b Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_3.nbt new file mode 100644 index 0000000..31b9186 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_4.nbt new file mode 100644 index 0000000..eb1f0f2 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_5.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_5.nbt new file mode 100644 index 0000000..ac2da9d Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_5.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_6.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_6.nbt new file mode 100644 index 0000000..398d72c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/huge/jungle_massive_6.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_1.nbt new file mode 100644 index 0000000..6f0516a Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_2.nbt new file mode 100644 index 0000000..76ff007 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_3.nbt new file mode 100644 index 0000000..ca3719c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_4.nbt new file mode 100644 index 0000000..cc3a06f Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/large/jungle_tall_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_1.nbt new file mode 100644 index 0000000..37c90f7 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_2.nbt new file mode 100644 index 0000000..eae5e04 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_3.nbt new file mode 100644 index 0000000..14dc95b Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/jungle/small/jungle_small_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_1.nbt new file mode 100644 index 0000000..2e0d9de Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_2.nbt new file mode 100644 index 0000000..c044495 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/forest/forest_oak_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_1.nbt new file mode 100644 index 0000000..7f40e0b Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_2.nbt new file mode 100644 index 0000000..63982e3 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/huge/oak_big_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_1.nbt new file mode 100644 index 0000000..aecb79c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_2.nbt new file mode 100644 index 0000000..aecb79c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_3.nbt new file mode 100644 index 0000000..fb741e8 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_4.nbt new file mode 100644 index 0000000..8dccea0 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_5.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_5.nbt new file mode 100644 index 0000000..0d95ab0 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/large/oak_5.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_1.nbt new file mode 100644 index 0000000..66cd106 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_2.nbt new file mode 100644 index 0000000..e5e5f52 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_bush_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_1.nbt new file mode 100644 index 0000000..39338cb Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_2.nbt new file mode 100644 index 0000000..441a181 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_3.nbt new file mode 100644 index 0000000..5788941 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_4.nbt new file mode 100644 index 0000000..31e8968 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/oak/small/oak_small_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_1.nbt new file mode 100644 index 0000000..873740e Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_2.nbt new file mode 100644 index 0000000..cbfaff2 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_3.nbt new file mode 100644 index 0000000..53d7c1b Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/huangshan_pine_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_1.nbt new file mode 100644 index 0000000..ae5ee8c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_2.nbt new file mode 100644 index 0000000..1f8c56c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_1.nbt new file mode 100644 index 0000000..19f44b4 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_2.nbt new file mode 100644 index 0000000..dcd6a0c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/scots_pine_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_1.nbt new file mode 100644 index 0000000..8e59f5c Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_2.nbt new file mode 100644 index 0000000..e952b2a Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/pine/stone_pine_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_1.nbt new file mode 100644 index 0000000..d261f77 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_2.nbt new file mode 100644 index 0000000..35f97ba Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_3.nbt new file mode 100644 index 0000000..438ed8f Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_4.nbt new file mode 100644 index 0000000..1b8af9b Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_5.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_5.nbt new file mode 100644 index 0000000..b405fc5 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_5.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_6.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_6.nbt new file mode 100644 index 0000000..d12955d Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/huge/redwood_massive_6.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_1.nbt new file mode 100644 index 0000000..f662868 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_2.nbt new file mode 100644 index 0000000..afa43f1 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_3.nbt new file mode 100644 index 0000000..abaaa84 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_4.nbt new file mode 100644 index 0000000..a9b8c42 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/redwood/large/redwood_tall_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_1.nbt new file mode 100644 index 0000000..5ec0972 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_2.nbt new file mode 100644 index 0000000..3e43aa5 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/bush/spruce_bush_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_1.nbt new file mode 100644 index 0000000..f98ae16 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_2.nbt new file mode 100644 index 0000000..195d494 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_3.nbt new file mode 100644 index 0000000..afa1449 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_4.nbt new file mode 100644 index 0000000..ecd2945 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_5.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_5.nbt new file mode 100644 index 0000000..4521bd6 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/large/spruce_5.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_1.nbt new file mode 100644 index 0000000..2a8ba15 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_2.nbt new file mode 100644 index 0000000..195d494 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_3.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_3.nbt new file mode 100644 index 0000000..e2b27f8 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_3.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_4.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_4.nbt new file mode 100644 index 0000000..9a1f793 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/spruce/small/spruce_small_4.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_1.nbt new file mode 100644 index 0000000..d8346fb Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_2.nbt new file mode 100644 index 0000000..48ef0cf Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/large/weeping_willow_big_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_1.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_1.nbt new file mode 100644 index 0000000..5295f78 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_1.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_2.nbt b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_2.nbt new file mode 100644 index 0000000..a8b2573 Binary files /dev/null and b/TerraForgedMod/src/main/resources/data/terraforged/structures/trees/willow/small/weeping_willow_small_2.nbt differ diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/alpine.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/alpine.json new file mode 100644 index 0000000..3c7bc00 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/alpine.json @@ -0,0 +1,12 @@ +{ + "replaceable": false, + "values": [ + "minecraft:gravelly_mountains", + "minecraft:modified_gravelly_mountains", + "minecraft:mountains", + "minecraft:snowy_mountains", + "minecraft:snowy_taiga_mountains", + "minecraft:taiga_mountains", + "minecraft:wooded_mountains" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/cold_steppe.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/cold_steppe.json new file mode 100644 index 0000000..7078779 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/cold_steppe.json @@ -0,0 +1,6 @@ +{ + "replaceable": false, + "values": [ + "terraforged:cold_steppe" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/desert.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/desert.json new file mode 100644 index 0000000..d05ad84 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/desert.json @@ -0,0 +1,14 @@ +{ + "replaceable": false, + "values": [ + "minecraft:badlands", + "minecraft:badlands_plateau", + "minecraft:desert", + "minecraft:desert_hills", + "minecraft:desert_lakes", + "minecraft:eroded_badlands", + "minecraft:modified_badlands_plateau", + "minecraft:modified_wooded_badlands_plateau", + "minecraft:wooded_badlands_plateau" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/grassland.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/grassland.json new file mode 100644 index 0000000..31dbf0a --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/grassland.json @@ -0,0 +1,8 @@ +{ + "replaceable": false, + "values": [ + "minecraft:plains", + "minecraft:sunflower_plains", + "minecraft:swamp" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/savanna.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/savanna.json new file mode 100644 index 0000000..4e2b39f --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/savanna.json @@ -0,0 +1,11 @@ +{ + "replaceable": false, + "values": [ + "minecraft:savanna", + "minecraft:savanna_plateau", + "minecraft:shattered_savanna", + "minecraft:shattered_savanna_plateau", + "terraforged:savanna_scrub", + "terraforged:shattered_savanna_scrub" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/steppe.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/steppe.json new file mode 100644 index 0000000..1652fec --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/steppe.json @@ -0,0 +1,6 @@ +{ + "replaceable": false, + "values": [ + "terraforged:steppe" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/taiga.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/taiga.json new file mode 100644 index 0000000..5068d33 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/taiga.json @@ -0,0 +1,11 @@ +{ + "replaceable": false, + "values": [ + "minecraft:giant_spruce_taiga", + "minecraft:giant_tree_taiga", + "minecraft:giant_tree_taiga_hills", + "minecraft:taiga", + "minecraft:taiga_hills", + "terraforged:taiga_scrub" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/temperate_forest.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/temperate_forest.json new file mode 100644 index 0000000..3733c1b --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/temperate_forest.json @@ -0,0 +1,13 @@ +{ + "replaceable": false, + "values": [ + "minecraft:birch_forest", + "minecraft:birch_forest_hills", + "minecraft:dark_forest", + "minecraft:flower_forest", + "minecraft:forest", + "minecraft:plains", + "minecraft:tall_birch_forest", + "minecraft:wooded_hills" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/temperate_rainforest.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/temperate_rainforest.json new file mode 100644 index 0000000..37aae65 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/temperate_rainforest.json @@ -0,0 +1,10 @@ +{ + "replaceable": false, + "values": [ + "minecraft:dark_forest", + "minecraft:flower_forest", + "minecraft:forest", + "minecraft:plains", + "minecraft:wooded_hills" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/tropical_rainforest.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/tropical_rainforest.json new file mode 100644 index 0000000..2150999 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/tropical_rainforest.json @@ -0,0 +1,10 @@ +{ + "replaceable": false, + "values": [ + "minecraft:bamboo_jungle", + "minecraft:bamboo_jungle_hills", + "minecraft:jungle", + "minecraft:jungle_hills", + "minecraft:modified_jungle" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/tundra.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/tundra.json new file mode 100644 index 0000000..14046ad --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/biomes/tundra.json @@ -0,0 +1,10 @@ +{ + "replaceable": false, + "values": [ + "minecraft:ice_spikes", + "minecraft:snowy_taiga", + "minecraft:snowy_taiga_hills", + "minecraft:snowy_tundra", + "terraforged:snowy_taiga_scrub" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/clay.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/clay.json new file mode 100644 index 0000000..3dd193a --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/clay.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "minecraft:clay" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/earth.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/earth.json new file mode 100644 index 0000000..7e53f69 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/earth.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:dirt", + "minecraft:coarse_dirt" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/erodible.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/erodible.json new file mode 100644 index 0000000..8d79529 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/erodible.json @@ -0,0 +1,10 @@ +{ + "replace": false, + "values": [ + "minecraft:dirt", + "minecraft:grass_block", + "minecraft:mycelium", + "minecraft:coarse_dirt", + "minecraft:podzol" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/ore.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/ore.json new file mode 100644 index 0000000..59fe3e2 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/ore.json @@ -0,0 +1,12 @@ +{ + "replace": false, + "values": [ + "minecraft:lapis_ore", + "minecraft:diamond_ore", + "minecraft:coal_ore", + "minecraft:emerald_ore", + "minecraft:gold_ore", + "minecraft:redstone_ore", + "minecraft:iron_ore" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/rock.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/rock.json new file mode 100644 index 0000000..e965f64 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/rock.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + "minecraft:granite", + "minecraft:andesite", + "minecraft:stone", + "minecraft:diorite" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/sediment.json b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/sediment.json new file mode 100644 index 0000000..f605778 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/tags/blocks/sediment.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "minecraft:sand", + "minecraft:gravel", + "minecraft:red_sand" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/acacia_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/acacia_large.json new file mode 100644 index 0000000..3d3c39b --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/acacia_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:acacia_large", + "paths": [ + "terraforged:trees/acacia/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/acacia_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/acacia_small.json new file mode 100644 index 0000000..7fd1cab --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/acacia_small.json @@ -0,0 +1,9 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:acacia_small", + "paths": [ + "terraforged:trees/acacia/small", + "terraforged:trees/acacia/bush" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_forest.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_forest.json new file mode 100644 index 0000000..8e2334f --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_forest.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:birch_forest", + "paths": [ + "terraforged:trees/birch/forest" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_large.json new file mode 100644 index 0000000..517da81 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_large.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:birch_large", + "paths": [ + "terraforged:trees/birch/large" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_small.json new file mode 100644 index 0000000..285f490 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/birch_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:birch_small", + "paths": [ + "terraforged:trees/birch/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/dark_oak_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/dark_oak_large.json new file mode 100644 index 0000000..0d08afb --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/dark_oak_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:dark_oak_large", + "paths": [ + "terraforged:trees/dark_oak/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/dark_oak_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/dark_oak_small.json new file mode 100644 index 0000000..1cab783 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/dark_oak_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:dark_oak_small", + "paths": [ + "terraforged:trees/dark_oak/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_huge.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_huge.json new file mode 100644 index 0000000..9966e5b --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_huge.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:jungle_huge", + "paths": [ + "terraforged:trees/jungle/huge" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_large.json new file mode 100644 index 0000000..2158117 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:jungle_large", + "paths": [ + "terraforged:trees/jungle/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_small.json new file mode 100644 index 0000000..c242c73 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/jungle_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:jungle_small", + "paths": [ + "terraforged:trees/jungle/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_forest.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_forest.json new file mode 100644 index 0000000..eacbf1f --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_forest.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_forest", + "paths": [ + "terraforged:trees/oak/forest" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_huge.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_huge.json new file mode 100644 index 0000000..15704e9 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_huge.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_huge", + "paths": [ + "terraforged:trees/oak/huge" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_large.json new file mode 100644 index 0000000..dd11f3e --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_large.json @@ -0,0 +1,13 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_large", + "paths": [ + "terraforged:trees/oak/large" + ], + "decorators": { + "minecraft:beehive": { + "probability": 0.002 + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_small.json new file mode 100644 index 0000000..cbb9289 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/oak_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:oak_small", + "paths": [ + "terraforged:trees/oak/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/pine.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/pine.json new file mode 100644 index 0000000..8ec0f47 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/pine.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:pine", + "paths": [ + "terraforged:trees/pine" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/redwood_huge.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/redwood_huge.json new file mode 100644 index 0000000..f84b835 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/redwood_huge.json @@ -0,0 +1,21 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:redwood_huge", + "paths": [ + "terraforged:trees/redwood/huge" + ], + "decorators": { + "minecraft:alter_ground": { + "provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:podzol", + "Properties": { + "snowy": "false" + } + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/redwood_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/redwood_large.json new file mode 100644 index 0000000..c9c829c --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/redwood_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:redwood_large", + "paths": [ + "terraforged:trees/redwood/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/spruce_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/spruce_large.json new file mode 100644 index 0000000..4738b7b --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/spruce_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:spruce_large", + "paths": [ + "terraforged:trees/spruce/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/spruce_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/spruce_small.json new file mode 100644 index 0000000..1e0c950 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/spruce_small.json @@ -0,0 +1,9 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:spruce_small", + "paths": [ + "terraforged:trees/spruce/small", + "terraforged:trees/spruce/bush" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/willow_large.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/willow_large.json new file mode 100644 index 0000000..467ae54 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/willow_large.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:willow_large", + "paths": [ + "terraforged:trees/willow/large" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/willow_small.json b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/willow_small.json new file mode 100644 index 0000000..1de4946 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/templates/trees/willow_small.json @@ -0,0 +1,8 @@ +{ + "type": "tree", + "base": 3, + "name": "terraforged:willow_small", + "paths": [ + "terraforged:trees/willow/small" + ] +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/license.txt b/TerraForgedMod/src/main/resources/license.txt new file mode 100644 index 0000000..0b31935 --- /dev/null +++ b/TerraForgedMod/src/main/resources/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 TerraForged + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/TerraForgedMod/src/main/resources/pack.mcmeta b/TerraForgedMod/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..b11415b --- /dev/null +++ b/TerraForgedMod/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "TerraForged resources", + "pack_format": 5 + } +} diff --git a/TerraForgedMod/src/main/resources/terraforged.png b/TerraForgedMod/src/main/resources/terraforged.png new file mode 100644 index 0000000..0d649c9 Binary files /dev/null and b/TerraForgedMod/src/main/resources/terraforged.png differ