From 2805ccd9adec7eb52de9577eb51d62f63d0d844a Mon Sep 17 00:00:00 2001 From: dags- Date: Fri, 3 Apr 2020 21:08:16 +0100 Subject: [PATCH] - fix reading of the defaults file - fix tree density in flower forest biomes - fix preview map not rendering with the custom default settings when first opening the settings ui - further improvements to village terrain blending --- .../com/terraforged/mod/TerraForgedMod.java | 2 + .../mod/chunk/ObfHelperChunkGenerator.java | 2 +- .../mod/chunk/TerraChunkGenerator.java | 8 +- .../mod/feature/TerrainHelper.java | 142 ++++++++---------- .../terraforged/mod/gui/SettingsScreen.java | 2 +- .../mod/gui/preview/PreviewPage.java | 7 +- .../mod/settings/SettingsHelper.java | 42 ++++-- .../features/trees/flower_forest.json | 55 +++++++ .../features/trees/oak_plains.json | 5 +- gradle.properties | 2 +- 10 files changed, 165 insertions(+), 102 deletions(-) create mode 100644 TerraForgedMod/src/main/resources/data/terraforged/features/trees/flower_forest.json diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java b/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java index bcac106..7898c6d 100644 --- a/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/TerraForgedMod.java @@ -32,6 +32,7 @@ import com.terraforged.mod.data.DataGen; import com.terraforged.mod.feature.decorator.poisson.PoissonAtSurface; import com.terraforged.mod.feature.feature.DiskFeature; import com.terraforged.mod.feature.tree.SaplingManager; +import com.terraforged.mod.settings.SettingsHelper; import com.terraforged.mod.util.DataPackFinder; import com.terraforged.mod.util.Environment; import net.minecraft.world.biome.Biomes; @@ -61,6 +62,7 @@ public class TerraForgedMod { TerraWorld.init(); SaplingManager.init(); TerraCommand.init(); + SettingsHelper.moveSettings(); // temp fix BiomeDictionary.addTypes(Biomes.BAMBOO_JUNGLE, BiomeDictionary.Type.OVERWORLD); diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java index 55aceef..5c9843c 100644 --- a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/ObfHelperChunkGenerator.java @@ -135,7 +135,7 @@ public abstract class ObfHelperChunkGenerator exte if (type == Heightmap.Type.OCEAN_FLOOR || type == Heightmap.Type.OCEAN_FLOOR_WG) { return level; } - return Math.max(getGroundHeight(), level); + return Math.max(getSeaLevel(), level); } public final double getSurfaceNoise(int x, int z) { diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java index b8890d8..33f98b5 100644 --- a/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/chunk/TerraChunkGenerator.java @@ -109,7 +109,7 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator generator, TemplateManager templates) { + public void generateStructures(BiomeManager biomes, IChunk chunk, ChunkGenerator generator, TemplateManager templates) { ChunkPos pos = chunk.getPos(); int regionX = regionCache.chunkToRegion(pos.x); int regionZ = regionCache.chunkToRegion(pos.z); // start generating the heightmap as early as possible regionCache.queueRegion(regionX, regionZ); - super.generateStructures(unused, chunk, this, templates); + super.generateStructures(biomes, chunk, this, templates); } @Override @@ -160,7 +160,7 @@ public class TerraChunkGenerator extends ObfHelperChunkGenerator pieces = new ObjectArrayList<>(10); collectPieces(world, chunk, pieces); - buildBases(chunk, reader, pieces, chunkStartX, chunkStartZ); + buildBases(chunk, pieces); } // see NoiseChunkGenerator @@ -92,82 +86,72 @@ public class TerrainHelper { } // lowers or raises the terrain matcher the base height of each structure piece - private void buildBases(IChunk chunk, ChunkReader reader,ObjectList pieces, int chunkStartX, int chunkStartZ) { + private void buildBases(IChunk chunk, ObjectList pieces) { + int chunkStartX = chunk.getPos().getXStart(); + int chunkStartZ = chunk.getPos().getZStart(); BlockPos.Mutable pos = new BlockPos.Mutable(); + ObjectListIterator iterator = pieces.iterator(); 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; - } + for (int dz = 0; dz < 16; dz++) { + for (int dx = 0; dx < 16; dx++) { + int x = chunkStartX + dx; + int z = chunkStartZ + dz; + int surface = chunk.getTopBlockY(Heightmap.Type.OCEAN_FLOOR_WG, dx, dz); + float y = surface; - // 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); - - // y position of the structure piece - int level = pieceBounds.minY + piece.getGroundLevelDelta(); - - // 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; - - int surface = chunk.getTopBlockY(Heightmap.Type.OCEAN_FLOOR_WG, dx, dz); - if (surface == level) { + AbstractVillagePiece highest = null; + while (iterator.hasNext()) { + AbstractVillagePiece piece = iterator.next(); + MutableBoundingBox pieceBounds = piece.getBoundingBox(); + int length = Math.min(pieceBounds.maxX - pieceBounds.minX, pieceBounds.maxZ - pieceBounds.minZ); + int borderRadius = Math.min(5, Math.max(10, NoiseUtil.round(length * radius))); + MutableBoundingBox expanded = expand(pieceBounds, borderRadius); + if (!expanded.intersectsWith(chunkBounds)) { continue; } - if (surface > level) { - flatten(chunk, reader, pieceBounds, pos.setPos(x, surface, z), dx, dz, level, surface, borderRadius); - } else { - // piece is higher than world-surface .: raise ground to form a base - raise(chunk, pieceBounds, pos.setPos(x, surface, z), dx, dz, level, surface, borderRadius); + int level = pieceBounds.minY + piece.getGroundLevelDelta(); + if (level > y) { + y = raise(pieceBounds, pos.setPos(x, surface, z), level, y, borderRadius); + } else if (level < surface && pieceBounds.getYSize() > 4) { + if (highest == null) { + highest = piece; + } else if (highest.getBoundingBox().maxY < pieceBounds.maxY) { + highest = piece; + } + } + } + + // reset iterator for next pass + iterator.back(pieces.size()); + + if (y > surface) { + int delta = (int) y - surface; + for (int dy = 0; dy < delta; dy++) { + pos.setPos(dx, surface + dy, dz); + chunk.setBlockState(pos, Blocks.STONE.getDefaultState(), false); + } + } + + if (highest != null && highest.getBoundingBox().minY < surface) { + MutableBoundingBox bounds = highest.getBoundingBox(); + if (x > bounds.minX && x < bounds.maxX && z > bounds.minZ && z < bounds.maxZ) { + for (int dy = bounds.minY + 1; dy <= surface; dy++) { + pos.setPos(dx, dy, dz); + chunk.setBlockState(pos, Blocks.AIR.getDefaultState(), false); + } } } } } } - private void flatten(IChunk chunk, ChunkReader reader, MutableBoundingBox bounds, BlockPos.Mutable pos, int dx, int dz, int level, int surface, int borderRadius) { - if (pos.getX() >= bounds.minX && pos.getX() <= bounds.maxX && pos.getZ() >= bounds.minZ && pos.getZ() <= bounds.maxZ) { - for (int dy = level + 1; dy <= surface; dy++) { - chunk.setBlockState(pos.setPos(dx, dy, dz), Blocks.AIR.getDefaultState(), false); - } - } - } - - private void raise(IChunk chunk, MutableBoundingBox bounds, BlockPos.Mutable pos, int dx, int dz, int level, int surface, int borderRadius) { - float radius2 = Math.max(1, borderRadius * borderRadius * noise.getValue(pos.getX(), pos.getZ())); - float alpha = getAlpha(bounds, radius2, pos.getX(), pos.getZ()); - if (alpha == 0F) { - // outside of the raise-able radius - return; - } - - int heightDelta = level - surface - 1; - if (alpha < 1F) { - // sharper fall-off - alpha = alpha * alpha; - heightDelta = NoiseUtil.round(alpha * heightDelta); - } - - BlockState state = States.STONE.getDefaultState(); - for (int dy = surface + heightDelta; dy >= surface; dy--) { - pos.setPos(dx, dy, dz); - if (chunk.getBlockState(pos).isSolid()) { - return; - } - chunk.setBlockState(pos.setPos(dx, dy, dz), state, false); - } + private float raise(MutableBoundingBox bounds, BlockPos.Mutable pos, float level, float surface, int borderRadius) { + float radius2 = Math.max(1, borderRadius * borderRadius); + float alpha = 1 - getDistAlpha(pos.getX(), pos.getZ(), bounds, radius2); + alpha = (float) Math.pow(alpha, 2F - alpha); + return NoiseUtil.lerp(surface, level, alpha); } private static MutableBoundingBox expand(MutableBoundingBox box, int radius) { @@ -181,16 +165,16 @@ public class TerrainHelper { ); } - private static float getAlpha(MutableBoundingBox box, float radius2, int x, int y) { + private static float getDistAlpha(int x, int z, MutableBoundingBox box, float radius2) { 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; + int dz = z < box.minZ ? box.minZ - z : z > box.maxZ ? z - box.maxZ : 0; + int d2 = dx * dx + dz * dz; if (d2 == 0) { - return 1F; + return 0; } if (d2 > radius2) { - return 0F; + return 1F; } - return 1 - (d2 / radius2); + return d2 / radius2; } } diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java index 37f0052..6364996 100644 --- a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/SettingsScreen.java @@ -62,7 +62,7 @@ public class SettingsScreen extends OverlayScreen { public SettingsScreen(CreateWorldScreen parent) { SettingsHelper.applyDefaults(parent.chunkProviderSettingsJson, settings); this.parent = parent; - this.preview = new PreviewPage(getSeed(parent)); + this.preview = new PreviewPage(settings, getSeed(parent)); this.pages = new Page[]{ new GeneratorPage(settings, preview), new ClimatePage(settings, preview), diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java index 101951c..eea35af 100644 --- a/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/gui/preview/PreviewPage.java @@ -37,11 +37,12 @@ import java.util.function.Consumer; public class PreviewPage extends BasePage { private final Preview preview; - private final Settings settings = new Settings(); + private final Settings settings; private final CompoundNBT previewerSettings = NBTHelper.serialize(new PreviewSettings()); - public PreviewPage(int seed) { - preview = new Preview(seed); + public PreviewPage(Settings settings, int seed) { + this.preview = new Preview(seed); + this.settings = settings; } public int getSeed() { diff --git a/TerraForgedMod/src/main/java/com/terraforged/mod/settings/SettingsHelper.java b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/SettingsHelper.java index a80a4dd..56014ef 100644 --- a/TerraForgedMod/src/main/java/com/terraforged/mod/settings/SettingsHelper.java +++ b/TerraForgedMod/src/main/java/com/terraforged/mod/settings/SettingsHelper.java @@ -7,7 +7,6 @@ import com.google.gson.JsonParser; import com.terraforged.mod.Log; import com.terraforged.mod.TerraWorld; import com.terraforged.mod.util.nbt.NBTHelper; -import net.minecraft.client.Minecraft; import net.minecraft.nbt.CompoundNBT; import net.minecraft.world.IWorld; import net.minecraft.world.storage.WorldInfo; @@ -20,10 +19,13 @@ import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; +import java.nio.file.Files; public class SettingsHelper { public static final String SETTINGS_FILE_NAME = "terraforged-generator.json"; + public static final File SETTINGS_DIR = new File("config", "terraforged"); + public static final File SETTINGS_FILE= new File(SETTINGS_DIR, SETTINGS_FILE_NAME); private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static int getVersion(WorldInfo info) { @@ -43,8 +45,7 @@ public class SettingsHelper { } public static void clearDefaults() { - File file = new File("config", SettingsHelper.SETTINGS_FILE_NAME); - if (file.exists() && file.delete()) { + if (SETTINGS_FILE.exists() && SETTINGS_FILE.delete()) { Log.info("Deleted generator defaults"); } } @@ -52,9 +53,7 @@ public class SettingsHelper { public static void exportDefaults(TerraSettings settings) { CompoundNBT tag = NBTHelper.serializeCompact(settings); JsonElement json = NBTHelper.toJson(tag); - File config = new File(Minecraft.getInstance().gameDir, "config"); - File file = new File(config, SettingsHelper.SETTINGS_FILE_NAME); - try (Writer writer = new BufferedWriter(new FileWriter(file))) { + try (Writer writer = new BufferedWriter(new FileWriter(SETTINGS_FILE))) { GSON.toJson(json, writer); } catch (IOException e) { e.printStackTrace(); @@ -63,7 +62,7 @@ public class SettingsHelper { public static void applyDefaults(CompoundNBT options, TerraSettings dest) { if (options.isEmpty()) { - try (Reader reader = new BufferedReader(new FileReader(new File("config", SETTINGS_FILE_NAME)))) { + try (Reader reader = new BufferedReader(new FileReader(SETTINGS_FILE))) { JsonElement json = new JsonParser().parse(reader); options = NBTHelper.fromJson(json); } catch (IOException ignored) { @@ -76,11 +75,12 @@ public class SettingsHelper { public static TerraSettings getSettings(IWorld world) { TerraSettings settings = new TerraSettings(); if (world.getWorldInfo().getGeneratorOptions().isEmpty()) { - File defaults = new File("config", SETTINGS_FILE_NAME); - if (defaults.exists()) { - try (Reader reader = new BufferedReader(new FileReader(defaults))) { + if (SETTINGS_FILE.exists()) { + try (Reader reader = new BufferedReader(new FileReader(SETTINGS_FILE))) { Log.info("Loading generator settings from json"); - return new Gson().fromJson(reader, TerraSettings.class); + JsonElement json = new JsonParser().parse(reader); + CompoundNBT root = NBTHelper.fromJson(json); + NBTHelper.deserialize(root, settings); } catch (Throwable t) { t.printStackTrace(); } @@ -98,4 +98,24 @@ public class SettingsHelper { CompoundNBT options = NBTHelper.serialize(settings); info.setGeneratorOptions(options); } + + public static void moveSettings() { + if (SETTINGS_FILE.exists()) { + return; + } + + File src = new File("config", SETTINGS_FILE_NAME); + if (src.exists()) { + if (SETTINGS_DIR.exists() || SETTINGS_DIR.mkdirs()) { + try { + Files.copy(src.toPath(), SETTINGS_FILE.toPath()); + if (src.delete()) { + Log.info("Moved settings file to new location: {}", SETTINGS_FILE.getAbsoluteFile()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } } diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/flower_forest.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/flower_forest.json new file mode 100644 index 0000000..d399328 --- /dev/null +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/flower_forest.json @@ -0,0 +1,55 @@ +{ + "biomes": [ + "minecraft:flower_forest" + ], + "match": [ + [ + "minecraft:oak_log", + "minecraft:oak_leaves" + ] + ], + "replace": { + "name": "minecraft:decorated", + "config": { + "feature": { + "name": "minecraft:random_selector", + "config": { + "features": [ + { + "name": "terraforged:birch_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:birch_large", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_forest", + "config": {}, + "chance": 0.2 + }, + { + "name": "terraforged:oak_large", + "config": {}, + "chance": 0.2 + } + ], + "default": { + "name": "terraforged:birch_forest", + "config": {} + } + } + }, + "decorator": { + "name": "minecraft:count_extra_heightmap", + "config": { + "count": 2, + "extra_chance": 0.1, + "extra_count": 2 + } + } + } + } +} \ No newline at end of file diff --git a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json index da7e09d..530c07b 100644 --- a/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json +++ b/TerraForgedMod/src/main/resources/data/terraforged/features/trees/oak_plains.json @@ -1,10 +1,11 @@ { "biomes": [ - "minecraft:plains", - "minecraft:flower_forest" + "minecraft:plains" ], "match": [ [ + "minecraft:birch_log", + "minecraft:birch_leaves", "minecraft:oak_log", "minecraft:oak_leaves" ] diff --git a/gradle.properties b/gradle.properties index 3d4248a..d1a308e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -mod_version=0.0.11 +mod_version=0.0.12 mc_version=1.15.2 forge_version=31.1.1 mcp_channel=snapshot