make it public

This commit is contained in:
dags- 2020-02-28 22:25:38 +00:00
parent 0811d01f16
commit b98c44609d
276 changed files with 12274 additions and 1 deletions

7
.gitignore vendored
View File

@ -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

7
TerraForgedMod/README.md Normal file
View File

@ -0,0 +1,7 @@
# TerraForged
### Commands
- `/terra query` - print the Terrain and Biome types at your location
- `/terra find <biome>` - find the nearest instance of the given biome type
- `/terra find <terrain>` - find the nearest instance of the given terrain type
- `/terra find <terrain> <biome>` - find the nearest instance of the given terrain and biome type

107
TerraForgedMod/build.gradle Normal file
View File

@ -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}"
}

172
TerraForgedMod/gradlew vendored Normal file
View File

@ -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" "$@"

84
TerraForgedMod/gradlew.bat vendored Normal file
View File

@ -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

Binary file not shown.

BIN
TerraForgedMod/psd/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

View File

@ -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);
}
}

View File

@ -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 <dags@dags.me>
*/
@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<Feature<?>> event) {
FeatureManager.registerTemplates(event);
}
private static void onShutdown(FMLServerStoppingEvent event) {
ThreadPool.shutdownCurrent();
}
}

View File

@ -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<WorldType> 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;
}
}

View File

@ -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;
}
}

View File

@ -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<BiomeVariant> 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<Biome> event) {
biomes.forEach(event.getRegistry()::register);
biomes.clear();
biomes.trimToSize();
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<Biome> getOceanBiomes(Biome.TempCategory temp) {
return Sets.newHashSet(ocean[temp.ordinal() - 1]);
}
@Override
public Set<Biome> getDeepOceanBiomes(Biome.TempCategory temp) {
return Sets.newHashSet(deepOcean[temp.ordinal() - 1]);
}
@Override
public Set<Biome> 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<Biome> 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];
}
}

View File

@ -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<Biome> getAllBiomes(BiomeType type) {
if (type.ordinal() >= biomeTypes.length) {
return Collections.emptyList();
}
return Arrays.asList(biomeTypes[type.ordinal()]);
}
@Override
public Set<Biome> 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;
}
}

View File

@ -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<Biome> biomes;
public BiomeGroup(FixedGrid<Biome> biomes) {
this.biomes = biomes;
}
}

View File

@ -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<Biome> getAllBiomes(BiomeType type);
Set<Biome> getBiomes(BiomeType type);
Set<Biome> getRivers(Biome.TempCategory temp);
Set<Biome> getOceanBiomes(Biome.TempCategory temp);
Set<Biome> 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();
}
}

View File

@ -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<Biome.TempCategory, List<Biome>> rivers = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> beaches = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> oceans = new HashMap<>();
private final Map<Biome.TempCategory, List<Biome>> deepOceans = new HashMap<>();
private final Map<BiomeType, List<Biome>> map = new EnumMap<>(BiomeType.class);
private final Map<Biome, BiomeData> dataMap = new HashMap<>();
private final int gridSize;
private final Function<BiomeMapBuilder, BiomeMap> constructor;
BiomeMapBuilder(Function<BiomeMapBuilder, BiomeMap> constructor, int gridSize, List<BiomeData> 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<Biome, Float> moisture = b -> dataMap.get(b).rainfall;
Function<Biome, Float> temperature = b -> dataMap.get(b).temperature;
for (BiomeType type : BiomeType.values()) {
List<Biome> list = map.getOrDefault(type, Collections.emptyList());
if (list.isEmpty()) {
continue;
}
FixedGrid<Biome> grid = FixedGrid.generate(gridSize, list, moisture, temperature);
biomes[type.ordinal()] = new BiomeGroup(grid);
}
return biomes;
}
private void add(List<Biome> list, Biome biome, int count) {
for (int i = 0; i < count; i++) {
list.add(biome);
}
}
private Biome[][] collectTemps(Map<Biome.TempCategory, List<Biome>> map) {
Biome[][] biomes = new Biome[3][];
for (Biome.TempCategory category : Biome.TempCategory.values()) {
if (category == Biome.TempCategory.OCEAN) {
continue;
}
List<Biome> 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<BiomeType, List<Biome>> map) {
Biome[][] biomes = new Biome[BiomeType.values().length][];
for (BiomeType type : BiomeType.values()) {
List<Biome> 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<BiomeData> biomes) {
return new BiomeMapBuilder(BasicBiomeMap::new, 0, biomes);
}
public static BiomeMap.Builder grid(int size, List<BiomeData> biomes) {
return new BiomeMapBuilder(GridBiomeMap::new, size, biomes);
}
}

View File

@ -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 <T> boolean anyMatch(T value, T[] test, BiPredicate<T, T> 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"));
}

View File

@ -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<Biome> getAllBiomes(BiomeType type) {
BiomeGroup group = biomeTypes[type.ordinal()];
if (group == null) {
return Collections.emptyList();
}
List<Biome> biomes = new LinkedList<>();
for (MappedList<FixedList<Biome>> row : group.biomes) {
for (FixedList<Biome> cell : row) {
for (Biome biome : cell) {
biomes.add(biome);
}
}
}
return biomes;
}
@Override
public Set<Biome> getBiomes(BiomeType type) {
BiomeGroup group = biomeTypes[type.ordinal()];
if (group == null) {
return Collections.emptySet();
}
Set<Biome> biomes = new HashSet<>();
for (MappedList<FixedList<Biome>> row : group.biomes) {
for (FixedList<Biome> 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<FixedList<Biome>> row : group.biomes) {
int colCount = 0;
float maxCol = row.size() - 1;
JsonObject rowJson = new JsonObject();
for (FixedList<Biome> 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;
}
}

View File

@ -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<Terrain> 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<Terrain> cell, int x, int z, float ox, float oz);
}

View File

@ -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<Terrain> 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<Terrain> cell, int x, int z, float ox, float oz);
}

View File

@ -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<Terrain> cell, int x, int z) {
if (cell.tag == terrain.beach) {
return biomeMap.getBeach(cell.temperature, cell.moisture, cell.biome);
}
return in;
}
}

View File

@ -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<BiomeModifier> biomeModifiers;
public BiomeModifierManager(TerraContext context, BiomeMap biomes) {
desertBiomes = new DesertBiomes(context.materials, biomes.getAllBiomes(BiomeType.DESERT));
List<BiomeModifier> 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<Terrain> cell, int x, int z) {
for (BiomeModifier modifier : biomeModifiers) {
if (modifier.test(biome)) {
biome = modifier.modify(biome, cell, x, z);
}
}
return biome;
}
}

View File

@ -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<Terrain> 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;
}
}

View File

@ -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<Biome> 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<Terrain> cell, int x, int z, float ox, float oz) {
return Biomes.BADLANDS;
}
}

View File

@ -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<Terrain> 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;
}
}

View File

@ -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<Biome> 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<Biome> 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<Biome> biomes, Random random) {
return findBiomePosition(centerX, centerY, centerZ, range, biomes, random);
}
public abstract Biome getBiome(int x, int y, int z);
public abstract Set<Biome> getBiomesInSquare(int x, int y, int z, int size);
public abstract BlockPos findBiomePosition(int centerX, int centerY, int centerZ, int range, List<Biome> biomes, Random random);
}

View File

@ -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<Biome> 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<BiomeType, BiomePredicate> PREDICATES = new HashMap<BiomeType, BiomePredicate>() {{
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<BiomeData> biomes) {
return BiomeMapBuilder.basic(biomes);
}
public static BiomeMap getDefaultBiomeMap() {
List<BiomeData> 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<BiomeType> 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<BiomeData> biomes = getAllBiomeData();
BiomeMap.Builder builder = getBuilder(biomes);
Map<String, BiomeData> biomeMap = biomes.stream().collect(Collectors.toMap(d -> d.name, d -> d));
Map<BiomeType, BiomeSettings.BiomeGroup> groupMap = settings.asMap();
for (Map.Entry<BiomeType, BiomeSettings.BiomeGroup> 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<BiomeType> getTypes(BiomeData data, Biome biome) {
Set<BiomeType> types = new HashSet<>();
for (Map.Entry<BiomeType, BiomePredicate> entry : PREDICATES.entrySet()) {
if (entry.getValue().test(data, biome)) {
types.add(entry.getKey());
}
}
return types;
}
public static List<BiomeData> getAllBiomeData() {
Collection<Biome> biomes = TerraBiomeRegistry.getInstance().getAll(BiomeHelper::filter);
Vec2f tempRange = getRange(biomes, Biome::getDefaultTemperature);
Vec2f moistRange = getRange(biomes, Biome::getDownfall);
List<BiomeData> 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<Biome> biomes, Function<Biome, Float> 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);
}
}

View File

@ -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<Cell<Terrain>> item = Cell.pooled()) {
context.heightmap.apply(item.getValue(), x, z);
return getBiome(item.getValue(), x, z);
}
}
@Override
public Set<Biome> 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<Biome> 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<Biome> biomes, Random random) {
int minX = centerX - (range >> 2);
int minZ = centerZ - (range >> 2);
int maxX = centerX + (range >> 2);
int maxZ = centerZ + (range >> 2);
Set<Biome> 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<BlockState> getSurfaceBlocks() {
if (this.topBlocksCache.isEmpty()) {
for (Biome biome : defaultBiomes) {
this.topBlocksCache.add(biome.getSurfaceBuilderConfig().getTop());
}
}
return this.topBlocksCache;
}
public Biome getBiome(Cell<Terrain> 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<Terrain> cell) {
return biomeMap.getBiome(cell.biomeType, cell.temperature, cell.moisture, cell.biome);
}
public Biome modifyBiome(Biome biome, Cell<Terrain> 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();
}
}

View File

@ -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<Biome> reds;
private final Set<Biome> whites;
private final List<Biome> redSand;
private final List<Biome> whiteSand;
private final LayerManager layerManager;
private final int maxRedIndex;
private final int maxWhiteIndex;
public DesertBiomes(Materials materials, List<Biome> deserts) {
List<Biome> white = new LinkedList<>();
List<Biome> red = new LinkedList<>();
try (ObjectPool.Item<DummyBlockReader> 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);
}
}

View File

@ -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());
}
}

View File

@ -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<Biome> getBiome(ResourceLocation name) {
if (ForgeRegistries.BIOMES.containsKey(name)) {
return Optional.ofNullable(ForgeRegistries.BIOMES.getValue(name));
}
return Optional.empty();
}
public Collection<Biome> getAll(Predicate<Biome> filter) {
List<Biome> combined = new LinkedList<>(ForgeRegistries.BIOMES.getValues());
combined.removeIf(filter);
return combined;
}
public static TerraBiomeRegistry getInstance() {
return instance;
}
}

View File

@ -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<Biome> collection = new TagCollection<>(
Registry.BIOME::getValue,
"tags/biomes",
BiomeTagManager.RETAIN_ORDER,
"biomes"
);
@Override
public CompletableFuture<Void> 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());
}
}

View File

@ -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 extends ChunkGenerator<?>> {
T create(TerraContext context, BiomeProvider biomeProvider, OverworldGenSettings settings);
}

View File

@ -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<T extends GenerationSettings> extends ChunkGenerator<T> {
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<Biome.SpawnListEntry> 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);
}

View File

@ -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<GenerationSettings> {
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<ColumnDecorator> baseDecorators;
private final List<ColumnDecorator> 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<ColumnDecorator> getBaseDecorators() {
return baseDecorators;
}
public final List<ColumnDecorator> 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<ColumnDecorator> createBaseDecorators(TerraContext context) {
List<ColumnDecorator> 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<ColumnDecorator> createFeatureDecorators(TerraContext context) {
List<ColumnDecorator> 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);
}
}

View File

@ -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<Terrain> 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);
}
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<Terrain> cell, int x, int z) {
if (cell.biome < 0.5F) {
return ModBiomes.TAIGA_SCRUB;
}
return Test.getBiome();
}
}

View File

@ -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<Terrain> cell, float x, float y) {
super.apply(cell, x, y);
populator.apply(cell, x, y);
}
@Override
public void tag(Cell<Terrain> cell, float x, float y) {
populator.tag(cell, x, y);
}
}
}

View File

@ -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<CommandSource> dispatcher) {
dispatcher.register(command());
}
private static LiteralArgumentBuilder<CommandSource> 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<CommandSource> 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<Terrain> 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<CommandSource> context) throws CommandSyntaxException {
context.getSource().sendFeedback(
new StringTextComponent("Exporting data"),
true
);
DataGen.dumpData();
return Command.SINGLE_SUCCESS;
}
private static int findTerrain(CommandContext<CommandSource> 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<CommandSource> 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<CommandSource> 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<TerraContext> getContext(CommandContext<CommandSource> 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<CommandSource> 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")))
);
}
}

View File

@ -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<Biome> {
@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 <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> 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> biome() {
return new BiomeArgType();
}
public static <S> Biome getBiome(CommandContext<S> context, String name) {
return context.getArgument(name, Biome.class);
}
}

View File

@ -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<Terrain> {
private final List<Terrain> 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 <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder suggestions) {
return ISuggestionProvider.suggest(terrains.stream().map(Terrain::getName).collect(Collectors.toList()), suggestions);
}
public static ArgumentType<Terrain> terrain() {
return new TerrainArgType();
}
public static <S> Terrain getTerrain(CommandContext<S> 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<Terrain> getTerrains() {
Terrains terrains = Terrains.create(new Settings());
List<Terrain> 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;
}
}

View File

@ -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<Terrain> 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<Terrain> 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;
}
}

View File

@ -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<Terrain> 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<Terrain> cell, int x, int z) {
return cell.continentEdge > 0.5 && cell.regionEdge > 0.8F && cell.tag == type;
}
}

View File

@ -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<Vec2i> {
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);
}

View File

@ -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<Terrain> 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<Terrain> cell) {
return cell.continentEdge > 0.5 && cell.regionEdge > 0.8F && cell.tag == type;
}
}

View File

@ -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;
}
}

View File

@ -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<Biome> 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());
}
}

View File

@ -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<Block> 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);
});
}
}

View File

@ -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<JsonElement> 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);
});
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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;
});
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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<BlockState> 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);
}
}

View File

@ -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<Terrain> cell) {
return cell.biomeMask(0F, 0.75F) * cell.mask(0.4F, 0.5F, 0F, 0.8F);
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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<AbstractVillagePiece> pieces = new ObjectArrayList<>(10);
collectPieces(world, chunk, pieces);
buildBases(chunk, pieces, chunkStartX, chunkStartZ);
}
// see NoiseChunkGenerator
private void collectPieces(IWorld world, IChunk chunk, ObjectList<AbstractVillagePiece> 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<AbstractVillagePiece> 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);
}
}

View File

@ -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);
}
}

View File

@ -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<Feature<NoFeatureConfig>> TOKEN = new TypeToken<Feature<NoFeatureConfig>>() {
};
private final Map<ResourceLocation, Integer> normal;
private final Map<ResourceLocation, Integer> giant;
public SaplingConfig() {
normal = new HashMap<>();
giant = new HashMap<>();
}
public <T> SaplingConfig(T config, DynamicOps<T> 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 <T> Map<ResourceLocation, Integer> getSection(String key, T config, DynamicOps<T> ops) {
return ops.get(config, key).flatMap(ops::getMapValues).map(map -> {
Map<ResourceLocation, Integer> backing = new HashMap<>();
for (Map.Entry<T, T> 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<Feature<NoFeatureConfig>> getNormal() {
return build(normal);
}
public List<Feature<NoFeatureConfig>> getGiant() {
return build(giant);
}
@SuppressWarnings("unchecked")
public static List<Feature<NoFeatureConfig>> build(Map<ResourceLocation, Integer> map) {
List<Feature<NoFeatureConfig>> list = new LinkedList<>();
for (Map.Entry<ResourceLocation, Integer> entry : map.entrySet()) {
Feature<?> feature = ForgeRegistries.FEATURES.getValue(entry.getKey());
if (feature == null) {
continue;
}
if (TOKEN.getRawType().isAssignableFrom(feature.getClass())) {
Feature<NoFeatureConfig> noConfFeature = (Feature<NoFeatureConfig>) feature;
list.add(noConfFeature);
}
}
return list;
}
}

View File

@ -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<Feature<NoFeatureConfig>> normal;
private final List<Feature<NoFeatureConfig>> giant;
public SaplingFeature(SaplingConfig config) {
this.normal = new ArrayList<>(config.getNormal());
this.giant = new ArrayList<>(config.getGiant());
}
public Feature<NoFeatureConfig> nextNormal(Random random) {
if (normal.isEmpty()) {
return null;
}
return normal.get(random.nextInt(normal.size()));
}
public Feature<NoFeatureConfig> 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();
}
}

View File

@ -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<NoFeatureConfig> 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");
}
}

View File

@ -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<ResourceLocation, SaplingFeature> 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 <T> void register(ResourceLocation location, T config, DynamicOps<T> 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");
}
}

View File

@ -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<NoFeatureConfig> 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 <W extends DecoratorWorld> boolean placeDecorated(DecoratedFeature<?, W> 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<NoFeatureConfig> 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;
}
}

View File

@ -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<TemplateFeature.BlockInfo> 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<TemplateFeature.BlockInfo> 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<NoFeatureConfig> feature, BlockPos pos, Random random) {
placeFeature(feature, pos, random, NoFeatureConfig.NO_FEATURE_CONFIG);
}
public <T extends IFeatureConfig> void placeFeature(Feature<T> 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());
}
}
}

View File

@ -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);
}

View File

@ -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 extends Widget> 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);
}
});
}
}

View File

@ -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<ScrollPane.Entry> 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<Entry> {
public final Widget option;
public Entry(Widget option) {
this.option = option;
}
@Override
public List<? extends IGuiEventListener> 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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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<String> getTooltip() {
return Collections.emptyList();
}
static int nextID() {
return ID_COUNTER.getAndAdd(1);
}
static List<String> 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();
}
}

View File

@ -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 -> {});
}
}

View File

@ -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);
}
}

View File

@ -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<String> 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<String> 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);
}
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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<ScrollPane> consumer) {
for (Column column : columns) {
if (column.scrollPane.children().isEmpty()) {
continue;
}
consumer.accept(column.scrollPane);
}
}
public boolean action(Function<ScrollPane, Boolean> 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<Widget> 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<Widget> 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);
}
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show More