From 2edc791a3d70e8e684e4567adf70609d1157a41f Mon Sep 17 00:00:00 2001 From: dags- Date: Tue, 30 Jun 2020 12:16:42 +0100 Subject: [PATCH] - improve how terrain is cut out above village pieces - further refinements to transition points - fix incorrect preset jsons - improve accuracy of biome lookups --- Engine | 2 +- build.gradle | 4 +-- .../api/chunk/column/ColumnDecorator.java | 13 +++++++ .../terraforged/mod/biome/map/BiomeMap.java | 2 +- .../mod/biome/map/SimpleBiomeMap.java | 5 +-- .../mod/biome/modifier/CoastModifier.java | 6 +++- .../biome/provider/TerraBiomeProvider.java | 6 ++++ .../mod/chunk/column/ErosionDecorator.java | 9 +++-- .../mod/chunk/column/GeologyDecorator.java | 3 +- .../mod/chunk/generator/TerrainGenerator.java | 2 +- .../mod/chunk/settings/SettingsHelper.java | 34 ++++++++++++------ .../chunk/settings/preset/PresetManager.java | 15 ++------ .../client/gui/element/TerraBoundSlider.java | 2 +- .../mod/client/gui/preview/Preview.java | 5 ++- .../mod/feature/TerrainHelper.java | 35 +++++++++++++++++-- .../mod/server/command/TerraCommand.java | 6 +++- .../command/search/BiomeSearchTask.java | 5 ++- .../terraforged/mod/util/nbt/NBTHelper.java | 5 +-- 18 files changed, 112 insertions(+), 47 deletions(-) diff --git a/Engine b/Engine index d9dee33..b4fd74c 160000 --- a/Engine +++ b/Engine @@ -1 +1 @@ -Subproject commit d9dee330393aa0bce3bc69920734d80617c82be2 +Subproject commit b4fd74c174412ca08d72c694dad5ee85e1e95d9e diff --git a/build.gradle b/build.gradle index 6d829e9..e0dc13d 100644 --- a/build.gradle +++ b/build.gradle @@ -109,8 +109,8 @@ classes { dependsOn(collectLibs) } -jar { - finalizedBy("reobfJar") +build { + dependsOn("reobfJar") } publishing { diff --git a/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java b/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java index b26a718..1f2b1ba 100644 --- a/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java +++ b/src/main/java/com/terraforged/api/chunk/column/ColumnDecorator.java @@ -52,6 +52,19 @@ public interface ColumnDecorator { } } + default void fillDownSolid(DecoratorContext context, IChunk chunk, int x, int z, int from, int to, BlockState state) { + for (int dy = from; dy > to; dy--) { ; + replaceSolid(chunk, context.pos.setPos(x, dy, z), state); + } + } + + static void replaceSolid(IChunk chunk, BlockPos pos, BlockState state) { + if (chunk.getBlockState(pos).isAir(chunk, pos)) { + return; + } + chunk.setBlockState(pos, state, false); + } + static float getNoise(float x, float z, int seed, float scale, float bias) { return (variance.getValue(x, z, seed) * scale) + bias; } diff --git a/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java b/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java index ccaa9fe..0b57e2f 100644 --- a/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java +++ b/src/main/java/com/terraforged/mod/biome/map/BiomeMap.java @@ -38,7 +38,7 @@ public interface BiomeMap { Biome getBeach(Cell cell); - Biome getCoast(Cell cell, Biome current); + Biome getCoast(Cell cell); Biome getRiver(Cell cell); diff --git a/src/main/java/com/terraforged/mod/biome/map/SimpleBiomeMap.java b/src/main/java/com/terraforged/mod/biome/map/SimpleBiomeMap.java index dff6c7d..d6b4106 100644 --- a/src/main/java/com/terraforged/mod/biome/map/SimpleBiomeMap.java +++ b/src/main/java/com/terraforged/mod/biome/map/SimpleBiomeMap.java @@ -54,6 +54,7 @@ public class SimpleBiomeMap implements BiomeMap { } } + @Override public Biome provideBiome(Cell cell, Levels levels) { TerrainType type = cell.terrain.getType(); if (type.isSubmerged() && cell.value > levels.water) { @@ -78,7 +79,7 @@ public class SimpleBiomeMap implements BiomeMap { } @Override - public Biome getCoast(Cell cell, Biome current) { + public Biome getCoast(Cell cell) { int inland = land.getSize(cell); Biome[] coastal = coast.getSet(cell); int total = inland + coastal.length; @@ -86,7 +87,7 @@ public class SimpleBiomeMap implements BiomeMap { if (index >= inland) { return coastal[index - inland]; } - return current; + return DefaultBiomes.NONE; } @Override diff --git a/src/main/java/com/terraforged/mod/biome/modifier/CoastModifier.java b/src/main/java/com/terraforged/mod/biome/modifier/CoastModifier.java index a19ac06..b1acb6d 100644 --- a/src/main/java/com/terraforged/mod/biome/modifier/CoastModifier.java +++ b/src/main/java/com/terraforged/mod/biome/modifier/CoastModifier.java @@ -28,6 +28,7 @@ package com.terraforged.mod.biome.modifier; import com.terraforged.api.biome.modifier.BiomeModifier; import com.terraforged.core.cell.Cell; import com.terraforged.mod.biome.map.BiomeMap; +import com.terraforged.mod.biome.map.defaults.DefaultBiomes; import com.terraforged.mod.chunk.TerraContext; import com.terraforged.world.terrain.Terrains; import net.minecraft.world.biome.Biome; @@ -57,7 +58,10 @@ public class CoastModifier implements BiomeModifier { @Override public Biome modify(Biome in, Cell cell, int x, int z) { if (cell.terrain.isCoast()) { - return biomeMap.getCoast(cell, in); + Biome coast = biomeMap.getCoast(cell); + if (coast != DefaultBiomes.NONE) { + return coast; + } } return in; } diff --git a/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeProvider.java b/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeProvider.java index 730cdd5..bf6f7c4 100644 --- a/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeProvider.java +++ b/src/main/java/com/terraforged/mod/biome/provider/TerraBiomeProvider.java @@ -69,6 +69,12 @@ public class TerraBiomeProvider extends BiomeProvider { return getWorldLookup().getCell(x, z); } + public Biome getBiome(int x, int z) { + try (Resource resource = getWorldLookup().getCell(x, z, true)) { + return getBiome(resource.get(), x, z); + } + } + @Override public Biome getNoiseBiome(int x, int y, int z) { x = (x << 2); diff --git a/src/main/java/com/terraforged/mod/chunk/column/ErosionDecorator.java b/src/main/java/com/terraforged/mod/chunk/column/ErosionDecorator.java index 2055448..1ee4eb5 100644 --- a/src/main/java/com/terraforged/mod/chunk/column/ErosionDecorator.java +++ b/src/main/java/com/terraforged/mod/chunk/column/ErosionDecorator.java @@ -96,7 +96,7 @@ public class ErosionDecorator implements ColumnDecorator { erodeRock(context, chunk, x, y, z); return; } else { - fillDown(context, chunk, x, z, y, y - 4, material); + fillDownSolid(context, chunk, x, z, y, y - 4, material); } } placeScree(chunk, context, x, y, z); @@ -105,7 +105,7 @@ public class ErosionDecorator implements ColumnDecorator { protected void erodeRock(DecoratorContext context, IChunk chunk, int dx, int y, int dz) { int depth = 32; - BlockState material = Blocks.GRAVEL.getDefaultState(); + BlockState material = States.GRAVEL.get(); // find the uppermost layer of rock & record it's depth for (int dy = 3; dy < 32; dy++) { context.pos.setPos(dx, y - dy, dz); @@ -119,8 +119,7 @@ public class ErosionDecorator implements ColumnDecorator { // fill downwards to the first rock layer for (int dy = 0; dy < depth; dy++) { - context.pos.setPos(dx, y - dy, dz); - chunk.setBlockState(context.pos, material, false); + ColumnDecorator.replaceSolid(chunk, context.pos.setPos(dx, y - dy, dz), material); } } @@ -133,7 +132,7 @@ public class ErosionDecorator implements ColumnDecorator { 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()); + fillDownSolid(context, chunk, x, z, y, y - 2, States.GRAVEL.get()); } } diff --git a/src/main/java/com/terraforged/mod/chunk/column/GeologyDecorator.java b/src/main/java/com/terraforged/mod/chunk/column/GeologyDecorator.java index 2c8915a..8322b64 100644 --- a/src/main/java/com/terraforged/mod/chunk/column/GeologyDecorator.java +++ b/src/main/java/com/terraforged/mod/chunk/column/GeologyDecorator.java @@ -48,8 +48,7 @@ public class GeologyDecorator implements ColumnDecorator { 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, context.depthBuffer.get(), (py, state) -> { - context.pos.setPos(x, py, z); - buffer.getDelegate().setBlockState(context.pos, state, false); + ColumnDecorator.replaceSolid(buffer.getDelegate(), context.pos.setPos(x, py, z), state); return true; }); } diff --git a/src/main/java/com/terraforged/mod/chunk/generator/TerrainGenerator.java b/src/main/java/com/terraforged/mod/chunk/generator/TerrainGenerator.java index 6b7d327..91ceed1 100644 --- a/src/main/java/com/terraforged/mod/chunk/generator/TerrainGenerator.java +++ b/src/main/java/com/terraforged/mod/chunk/generator/TerrainGenerator.java @@ -26,7 +26,7 @@ public class TerrainGenerator implements Generator.Terrain { this.levels = generator.getContext().levels; this.terrain = generator.getContext().terrain; this.climate = generator.getContext().factory.getClimate(); - this.terrainHelper = new TerrainHelper(0.75F); + this.terrainHelper = new TerrainHelper(0.75F, 4F); } @Override diff --git a/src/main/java/com/terraforged/mod/chunk/settings/SettingsHelper.java b/src/main/java/com/terraforged/mod/chunk/settings/SettingsHelper.java index 0e98163..bfea94f 100644 --- a/src/main/java/com/terraforged/mod/chunk/settings/SettingsHelper.java +++ b/src/main/java/com/terraforged/mod/chunk/settings/SettingsHelper.java @@ -31,6 +31,28 @@ public class SettingsHelper { } } + public static TerraSettings loadSettings(File file) { + TerraSettings settings = new TerraSettings(); + try (Reader reader = new BufferedReader(new FileReader(file))) { + JsonElement data = new JsonParser().parse(reader); + CompoundNBT nbt = NBTHelper.fromJson(data); + if (NBTHelper.deserialize(nbt, settings)) { + return settings; + } + } catch (IOException e) { + e.printStackTrace(); + } + + try (Writer writer = new BufferedWriter(new FileWriter(file))) { + CompoundNBT tag = NBTHelper.serializeCompact(settings); + JsonElement json = NBTHelper.toJson(tag); + GSON.toJson(json, writer); + } catch (IOException e) { + e.printStackTrace(); + } + return settings; + } + public static void exportDefaults(TerraSettings settings) { CompoundNBT tag = NBTHelper.serializeCompact(settings); JsonElement json = NBTHelper.toJson(tag); @@ -51,18 +73,10 @@ public class SettingsHelper { } public static TerraSettings readDefaults() { - TerraSettings settings = new TerraSettings(); if (DEFAULTS_FILE.exists()) { - try (Reader reader = new BufferedReader(new FileReader(DEFAULTS_FILE))) { - Log.info("Loading generator settings from json"); - JsonElement json = new JsonParser().parse(reader); - CompoundNBT root = NBTHelper.fromJson(json); - NBTHelper.deserialize(root, settings); - } catch (Throwable t) { - t.printStackTrace(); - } + return loadSettings(DEFAULTS_FILE); } - return settings; + return new TerraSettings(); } public static TerraSettings getSettings(WorldInfo info) { diff --git a/src/main/java/com/terraforged/mod/chunk/settings/preset/PresetManager.java b/src/main/java/com/terraforged/mod/chunk/settings/preset/PresetManager.java index 6ab2d3a..a205d10 100644 --- a/src/main/java/com/terraforged/mod/chunk/settings/preset/PresetManager.java +++ b/src/main/java/com/terraforged/mod/chunk/settings/preset/PresetManager.java @@ -3,20 +3,16 @@ package com.terraforged.mod.chunk.settings.preset; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; -import com.google.gson.JsonParser; import com.terraforged.mod.Log; import com.terraforged.mod.chunk.settings.SettingsHelper; import com.terraforged.mod.chunk.settings.TerraSettings; import com.terraforged.mod.util.nbt.NBTHelper; import net.minecraft.nbt.CompoundNBT; -import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.io.Reader; import java.io.Writer; import java.util.ArrayList; import java.util.Collections; @@ -127,15 +123,8 @@ public class PresetManager implements Iterable { } String name = file.getName().substring(0, file.getName().length() - 5); - try (Reader reader = new BufferedReader(new FileReader(file))) { - JsonElement data = new JsonParser().parse(reader); - CompoundNBT nbt = NBTHelper.fromJson(data); - TerraSettings settings = new TerraSettings(); - NBTHelper.deserialize(nbt, settings); - presets.add(new Preset(name, file, settings)); - } catch (IOException e) { - e.printStackTrace(); - } + TerraSettings settings = SettingsHelper.loadSettings(file); + presets.add(new Preset(name, file, settings)); } return new PresetManager(presets); diff --git a/src/main/java/com/terraforged/mod/client/gui/element/TerraBoundSlider.java b/src/main/java/com/terraforged/mod/client/gui/element/TerraBoundSlider.java index 333a9c4..fd97311 100644 --- a/src/main/java/com/terraforged/mod/client/gui/element/TerraBoundSlider.java +++ b/src/main/java/com/terraforged/mod/client/gui/element/TerraBoundSlider.java @@ -11,7 +11,7 @@ public class TerraBoundSlider extends TerraSlider.Float { private final String upper; public TerraBoundSlider(String name, CompoundNBT value) { - this(name, value, 0.01F); + this(name, value, 0.005F); } public TerraBoundSlider(String name, CompoundNBT value, float pad) { diff --git a/src/main/java/com/terraforged/mod/client/gui/preview/Preview.java b/src/main/java/com/terraforged/mod/client/gui/preview/Preview.java index 8621b67..bd02f8f 100644 --- a/src/main/java/com/terraforged/mod/client/gui/preview/Preview.java +++ b/src/main/java/com/terraforged/mod/client/gui/preview/Preview.java @@ -40,6 +40,7 @@ import com.terraforged.mod.util.nbt.NBTHelper; import com.terraforged.n2d.util.NoiseUtil; import com.terraforged.world.GeneratorContext; import com.terraforged.world.continent.MutableVeci; +import com.terraforged.world.continent.SpawnType; import com.terraforged.world.heightmap.Levels; import com.terraforged.world.terrain.Terrains; import net.minecraft.client.Minecraft; @@ -204,7 +205,9 @@ public class Preview extends Button { GeneratorContext context = GeneratorContext.createNoCache(Terrains.create(settings), settings); MutableVeci center = new MutableVeci(); - context.factory.getHeightmap().getContinent().getNearestCenter(offsetX, offsetZ, center); + if (settings.world.properties.spawnType == SpawnType.CONTINENT_CENTER) { + context.factory.getHeightmap().getContinent().getNearestCenter(offsetX, offsetZ, center); + } TileGenerator renderer = TileGenerator.builder() .pool(threadPool) diff --git a/src/main/java/com/terraforged/mod/feature/TerrainHelper.java b/src/main/java/com/terraforged/mod/feature/TerrainHelper.java index 650b141..a50e807 100644 --- a/src/main/java/com/terraforged/mod/feature/TerrainHelper.java +++ b/src/main/java/com/terraforged/mod/feature/TerrainHelper.java @@ -59,9 +59,15 @@ public class TerrainHelper { ); private final float radius; + private final float overhang; + private final float overhang2; - public TerrainHelper(float radius) { - this.radius = radius; + // base - the size of the base built up around a piece as a percentage of its bounding box size + // overhang - the amount of overhead overhang to be cut out + public TerrainHelper(float base, float cutout) { + this.radius = base; + this.overhang = cutout; + this.overhang2 = cutout * cutout; } public void flatten(IWorld world, IChunk chunk) { @@ -148,7 +154,22 @@ public class TerrainHelper { if (highest != null) { MutableBoundingBox bounds = highest.getBoundingBox(); - for (int dy = bounds.minY + highestOffset; dy <= surface; dy++) { + int minY = bounds.minY + highestOffset; + int maxY = minY + bounds.getYSize(); + + if (maxY <= surface) { + // gets weaker the further from the center of the piece + float dist = getCenterDistance2(x, z, bounds); + float distAlpha = 1F - NoiseUtil.clamp(dist / overhang2, 0, 1); + + // gets weaker the more material is overhead creating the inverse cutout (ie overhang) + float depth = surface - maxY; + float depthAlpha = 1F - NoiseUtil.clamp(depth / overhang, 0, 1); + + maxY += NoiseUtil.round(depthAlpha * distAlpha * overhang); + } + + for (int dy = minY; dy <= maxY; dy++) { pos.setPos(dx, dy, dz); chunk.setBlockState(pos, Blocks.AIR.getDefaultState(), false); } @@ -164,6 +185,14 @@ public class TerrainHelper { return NoiseUtil.lerp(surface, level, alpha); } + private float getCenterDistance2(int x, int z, MutableBoundingBox bounds) { + float cx = bounds.minX + (bounds.getXSize() / 2F); + float cz = bounds.minZ + (bounds.getZSize() / 2F); + float dx = cx - x; + float dz = cz - z; + return dx * dx + dz * dz; + } + private static void collectPiece(StructurePiece structurepiece, List list) { if (structurepiece instanceof AbstractVillagePiece) { AbstractVillagePiece piece = (AbstractVillagePiece) structurepiece; diff --git a/src/main/java/com/terraforged/mod/server/command/TerraCommand.java b/src/main/java/com/terraforged/mod/server/command/TerraCommand.java index 856dd1c..3c50df0 100644 --- a/src/main/java/com/terraforged/mod/server/command/TerraCommand.java +++ b/src/main/java/com/terraforged/mod/server/command/TerraCommand.java @@ -132,7 +132,11 @@ public class TerraCommand { try (Resource cell = biomeProvider.lookupPos(pos.getX(), pos.getZ())) { Biome biome = biomeProvider.getBiome(cell.get(), pos.getX(), pos.getZ()); context.getSource().sendFeedback( - new StringTextComponent("Terrain=" + cell.get().terrain.getName() + ", Biome=" + biome.getRegistryName()), + new StringTextComponent( + "Terrain=" + cell.get().terrain.getName() + + ", Biome=" + biome.getRegistryName() + + ", BiomeType=" + cell.get().biomeType.name() + ), false ); } diff --git a/src/main/java/com/terraforged/mod/server/command/search/BiomeSearchTask.java b/src/main/java/com/terraforged/mod/server/command/search/BiomeSearchTask.java index 5b02027..9d2099e 100644 --- a/src/main/java/com/terraforged/mod/server/command/search/BiomeSearchTask.java +++ b/src/main/java/com/terraforged/mod/server/command/search/BiomeSearchTask.java @@ -27,6 +27,9 @@ public class BiomeSearchTask extends ChunkGeneratorSearch { @Override public boolean test(BlockPos pos) { biomeProvider.getWorldLookup().applyCell(cell, pos.getX(), pos.getZ()); - return biomeProvider.getBiome(cell, pos.getX(), pos.getZ()) == biome; + if (biomeProvider.getBiome(cell, pos.getX(), pos.getZ()) == biome) { + return biomeProvider.getBiome(pos.getX(), pos.getZ()) == biome; + } + return false; } } diff --git a/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java b/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java index 536261a..8bedde5 100644 --- a/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java +++ b/src/main/java/com/terraforged/mod/util/nbt/NBTHelper.java @@ -114,12 +114,13 @@ public class NBTHelper { return tag; } - public static void deserialize(CompoundNBT settings, Object object) { + public static boolean deserialize(CompoundNBT settings, Object object) { try { NBTReader reader = new NBTReader(settings); - reader.writeTo(object); + return reader.writeTo(object); } catch (Throwable e) { e.printStackTrace(); + return false; } } }