- improve how terrain is cut out above village pieces
- further refinements to transition points - fix incorrect preset jsons - improve accuracy of biome lookups
This commit is contained in:
parent
a73058062c
commit
2edc791a3d
2
Engine
2
Engine
@ -1 +1 @@
|
||||
Subproject commit d9dee330393aa0bce3bc69920734d80617c82be2
|
||||
Subproject commit b4fd74c174412ca08d72c694dad5ee85e1e95d9e
|
@ -109,8 +109,8 @@ classes {
|
||||
dependsOn(collectLibs)
|
||||
}
|
||||
|
||||
jar {
|
||||
finalizedBy("reobfJar")
|
||||
build {
|
||||
dependsOn("reobfJar")
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -69,6 +69,12 @@ public class TerraBiomeProvider extends BiomeProvider {
|
||||
return getWorldLookup().getCell(x, z);
|
||||
}
|
||||
|
||||
public Biome getBiome(int x, int z) {
|
||||
try (Resource<Cell> 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);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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<Preset> {
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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<StructurePiece> list) {
|
||||
if (structurepiece instanceof AbstractVillagePiece) {
|
||||
AbstractVillagePiece piece = (AbstractVillagePiece) structurepiece;
|
||||
|
@ -132,7 +132,11 @@ public class TerraCommand {
|
||||
try (Resource<Cell> 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
|
||||
);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user