From 277fbccc0768cc85c3573cee4fbc90fde59776d2 Mon Sep 17 00:00:00 2001 From: dfsek Date: Sun, 4 Oct 2020 21:14:58 -0700 Subject: [PATCH] Config refactoring, work on caverns, multi-level tree gen --- .idea/inspectionProfiles/Project_Default.xml | 10 ++ src/main/java/com/dfsek/terra/TerraWorld.java | 2 +- .../terra/async/AsyncStructureFinder.java | 25 ++- .../com/dfsek/terra/biome/TerraBiomeGrid.java | 2 +- .../dfsek/terra/carving/SimplexCarver.java | 12 +- .../terra/carving/UserDefinedCarver.java | 2 +- .../com/dfsek/terra/config/ConfigLoader.java | 1 + .../com/dfsek/terra/config/TerraConfig.java | 1 + .../terra/config/{ => base}/ConfigPack.java | 10 +- .../dfsek/terra/config/base/ConfigUtil.java | 1 - .../dfsek/terra/config/base/WorldConfig.java | 1 - .../config/genconfig/BiomeGridConfig.java | 2 +- .../terra/config/genconfig/CarverConfig.java | 2 +- .../terra/config/genconfig/FloraConfig.java | 2 +- .../terra/config/genconfig/OreConfig.java | 2 +- .../terra/config/genconfig/PaletteConfig.java | 2 +- .../config/genconfig/StructureConfig.java | 2 +- .../genconfig/biome/AbstractBiomeConfig.java | 7 +- .../config/genconfig/biome/BiomeConfig.java | 9 +- .../genconfig/biome/BiomeConfigUtil.java | 51 ------ .../genconfig/biome/BiomeSlabConfig.java | 4 +- .../genconfig/biome/BiomeTreeConfig.java | 14 +- .../terra/generation/TerraChunkGenerator.java | 4 +- .../dfsek/terra/population/CavePopulator.java | 7 +- .../terra/population/FloraPopulator.java | 2 +- .../dfsek/terra/population/OrePopulator.java | 2 +- .../dfsek/terra/population/SnowPopulator.java | 15 ++ .../terra/population/StructurePopulator.java | 2 +- .../dfsek/terra/population/TreePopulator.java | 36 +++- .../com/dfsek/terra/procgen/math/Vector2.java | 157 ++++++++++++++++++ .../terra/procgen/pixel/Distribution.java | 7 + .../dfsek/terra/procgen/pixel/Polygon.java | 9 + .../dfsek/terra/procgen/pixel/Rectangle.java | 31 ++++ .../terra/procgen/voxel/VoxelGeometry.java | 2 +- 34 files changed, 328 insertions(+), 110 deletions(-) create mode 100644 .idea/inspectionProfiles/Project_Default.xml rename src/main/java/com/dfsek/terra/config/{ => base}/ConfigPack.java (96%) delete mode 100644 src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfigUtil.java create mode 100644 src/main/java/com/dfsek/terra/population/SnowPopulator.java create mode 100644 src/main/java/com/dfsek/terra/procgen/math/Vector2.java create mode 100644 src/main/java/com/dfsek/terra/procgen/pixel/Distribution.java create mode 100644 src/main/java/com/dfsek/terra/procgen/pixel/Polygon.java create mode 100644 src/main/java/com/dfsek/terra/procgen/pixel/Rectangle.java diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 000000000..875ffa22b --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/src/main/java/com/dfsek/terra/TerraWorld.java b/src/main/java/com/dfsek/terra/TerraWorld.java index 58790fbab..7909a7b01 100644 --- a/src/main/java/com/dfsek/terra/TerraWorld.java +++ b/src/main/java/com/dfsek/terra/TerraWorld.java @@ -4,7 +4,7 @@ import com.dfsek.terra.biome.BiomeZone; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedGrid; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.config.genconfig.BiomeGridConfig; diff --git a/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java b/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java index 35730d9d2..f61c04e9e 100644 --- a/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java +++ b/src/main/java/com/dfsek/terra/async/AsyncStructureFinder.java @@ -1,7 +1,6 @@ package com.dfsek.terra.async; import com.dfsek.terra.Terra; -import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.config.genconfig.StructureConfig; @@ -13,9 +12,7 @@ import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.util.Vector; import org.polydev.gaea.generation.GenerationPhase; -import org.polydev.gaea.profiler.ProfileFuture; -import java.util.Collections; import java.util.Random; public class AsyncStructureFinder implements Runnable { @@ -53,11 +50,13 @@ public class AsyncStructureFinder implements Runnable { int run = 1; boolean toggle = true; boolean found = false; + Vector spawn = null; main: for(int i = startRadius; i < maxRadius; i++) { for(int j = 0; j < run; j++) { if(toggle) x += 16; else x -= 16; - if(hasValidSpawn(x, z)) { + spawn = target.getSpawn().getNearestSpawn(x, z, seed); + if(isValidSpawn(spawn.getBlockX(), spawn.getBlockZ())) { found = true; break main; } @@ -65,7 +64,8 @@ public class AsyncStructureFinder implements Runnable { for(int j = 0; j < run; j++) { if(toggle) z += 16; else z -= 16; - if(hasValidSpawn(x, z)) { + spawn = target.getSpawn().getNearestSpawn(x, z, seed); + if(isValidSpawn(spawn.getBlockX(), spawn.getBlockZ())) { found = true; break main; } @@ -74,25 +74,22 @@ public class AsyncStructureFinder implements Runnable { toggle = !toggle; } if(found) { - Vector v = target.getSpawn().getNearestSpawn(x, z, seed); - x = v.getBlockX(); - z = v.getBlockZ(); - p.sendMessage("Located structure at (" + x + ", " + z + ")."); + p.sendMessage("Located structure at (" + spawn.getBlockX() + ", " + spawn.getBlockZ() + ")."); if(tp) { int finalX = x; int finalZ = z; Bukkit.getScheduler().runTask(Terra.getInstance(), () -> p.teleport(new Location(p.getWorld(), finalX, p.getLocation().getY(), finalZ))); } - } else if(p.isOnline()) p.sendMessage("Unable to locate structure."); + } else if(p.isOnline()) p.sendMessage("Unable to locate structure. " + spawn); } - private boolean hasValidSpawn(int x, int z) { - UserDefinedBiome b = (UserDefinedBiome) grid.getBiome(x, z, GenerationPhase.POPULATE); - Location spawn = target.getSpawn().getNearestSpawn(x, z, seed).toLocation(world); // Probably(tm) async safe + private boolean isValidSpawn(int x, int z) { + Location spawn = new Location(world, x, 255, z); // Probably(tm) async safe + UserDefinedBiome b = (UserDefinedBiome) grid.getBiome(spawn, GenerationPhase.POPULATE); Random r2 = new Random(spawn.hashCode()); GaeaStructure struc = target.getStructure(r2); main: for(int y = target.getSearchStart().get(r2); y > 0; y--) { - if(y > target.getBound().getMax() || y < target.getBound().getMin()) return false; spawn.setY(y); + if(y > target.getBound().getMax() || y < target.getBound().getMin()) return false; for(StructureSpawnRequirement s : struc.getSpawns()) { if(! s.isValidSpawn(spawn)) continue main; // Probably(tm) async safe if(!b.equals(grid.getBiome(spawn.clone().add(s.getX(), s.getY(), s.getZ()), GenerationPhase.POPULATE))) return false; diff --git a/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java b/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java index 5bc320a73..ca1b91e54 100644 --- a/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java +++ b/src/main/java/com/dfsek/terra/biome/TerraBiomeGrid.java @@ -1,6 +1,6 @@ package com.dfsek.terra.biome; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigUtil; import org.bukkit.Bukkit; import org.bukkit.Location; diff --git a/src/main/java/com/dfsek/terra/carving/SimplexCarver.java b/src/main/java/com/dfsek/terra/carving/SimplexCarver.java index 2713d4ccb..e77f6d4f8 100644 --- a/src/main/java/com/dfsek/terra/carving/SimplexCarver.java +++ b/src/main/java/com/dfsek/terra/carving/SimplexCarver.java @@ -57,9 +57,17 @@ public class SimplexCarver extends Carver { double mainNoise = noise.getNoise(x, z)*2; double columnNoise = Math.pow(Math.max(column.getNoise(x, z), 0)*2, 3); double hc = (acot(16*(hasCaves.getNoise(x, z)-0.2))/Math.PI)-0.1; + CarvingData.CarvingType type = CarvingData.CarvingType.BOTTOM; + double simplex = (Math.pow(mainNoise + root2inverse, 3)/2 + columnNoise) * hc; for(int y = 0; y < 64; y++) { - double finalNoise = (-0.05*Math.abs(y-(heightNoise*16 + 24))+1 - (Math.pow(mainNoise + root2inverse, 3)/2 + columnNoise)) * hc; - if(finalNoise > 0.5) c.carve(x-ox, y, z-oz, CarvingData.CarvingType.CENTER); + double finalNoise = (-0.05*Math.abs(y-(heightNoise*16 + 24))+1 - simplex) * hc; + if(finalNoise > 0.5) { + c.carve(x-ox, y, z-oz, type); + double finalNoiseUp = (-0.05*Math.abs((y+1)-(heightNoise*16 + 24))+1 - simplex) * hc; + if(finalNoiseUp > 0.5) { + type = CarvingData.CarvingType.CENTER; + } else type = CarvingData.CarvingType.TOP; + } } } } diff --git a/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java b/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java index 724a42911..e7c16591b 100644 --- a/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java +++ b/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java @@ -1,7 +1,7 @@ package com.dfsek.terra.carving; import com.dfsek.terra.TerraWorld; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import org.polydev.gaea.math.Range; import com.dfsek.terra.biome.UserDefinedBiome; import org.bukkit.World; diff --git a/src/main/java/com/dfsek/terra/config/ConfigLoader.java b/src/main/java/com/dfsek/terra/config/ConfigLoader.java index 43a1f27ae..5f82c51cb 100644 --- a/src/main/java/com/dfsek/terra/config/ConfigLoader.java +++ b/src/main/java/com/dfsek/terra/config/ConfigLoader.java @@ -1,5 +1,6 @@ package com.dfsek.terra.config; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigUtil; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; diff --git a/src/main/java/com/dfsek/terra/config/TerraConfig.java b/src/main/java/com/dfsek/terra/config/TerraConfig.java index 95ed50097..8c40c3545 100644 --- a/src/main/java/com/dfsek/terra/config/TerraConfig.java +++ b/src/main/java/com/dfsek/terra/config/TerraConfig.java @@ -1,5 +1,6 @@ package com.dfsek.terra.config; +import com.dfsek.terra.config.base.ConfigPack; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/src/main/java/com/dfsek/terra/config/ConfigPack.java b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java similarity index 96% rename from src/main/java/com/dfsek/terra/config/ConfigPack.java rename to src/main/java/com/dfsek/terra/config/base/ConfigPack.java index 1ac30cf99..3b6aca0ab 100644 --- a/src/main/java/com/dfsek/terra/config/ConfigPack.java +++ b/src/main/java/com/dfsek/terra/config/base/ConfigPack.java @@ -1,7 +1,8 @@ -package com.dfsek.terra.config; +package com.dfsek.terra.config.base; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.carving.UserDefinedCarver; +import com.dfsek.terra.config.ConfigLoader; import com.dfsek.terra.config.exception.ConfigException; import com.dfsek.terra.config.genconfig.biome.AbstractBiomeConfig; import com.dfsek.terra.config.genconfig.biome.BiomeConfig; @@ -26,6 +27,9 @@ import java.util.Map; import java.util.logging.Logger; import java.util.stream.Collectors; +/** + * Represents a Terra configuration pack. + */ public class ConfigPack extends YamlConfiguration { private static final Map configs = new HashMap<>(); private final Map ores; @@ -104,7 +108,7 @@ public class ConfigPack extends YamlConfiguration { return carvers; } - public static void loadAll(JavaPlugin main) { + public static synchronized void loadAll(JavaPlugin main) { configs.clear(); List subfolder; try { @@ -135,7 +139,7 @@ public class ConfigPack extends YamlConfiguration { return id; } - public static ConfigPack fromID(String id) { + public static synchronized ConfigPack fromID(String id) { return configs.get(id); } diff --git a/src/main/java/com/dfsek/terra/config/base/ConfigUtil.java b/src/main/java/com/dfsek/terra/config/base/ConfigUtil.java index 2017d30d6..9527b9463 100644 --- a/src/main/java/com/dfsek/terra/config/base/ConfigUtil.java +++ b/src/main/java/com/dfsek/terra/config/base/ConfigUtil.java @@ -1,7 +1,6 @@ package com.dfsek.terra.config.base; import com.dfsek.terra.TerraWorld; -import com.dfsek.terra.config.ConfigPack; import com.dfsek.terra.config.exception.ConfigException; import org.bukkit.Bukkit; import org.bukkit.Material; diff --git a/src/main/java/com/dfsek/terra/config/base/WorldConfig.java b/src/main/java/com/dfsek/terra/config/base/WorldConfig.java index 8f661cf4d..05e97e5bb 100644 --- a/src/main/java/com/dfsek/terra/config/base/WorldConfig.java +++ b/src/main/java/com/dfsek/terra/config/base/WorldConfig.java @@ -1,6 +1,5 @@ package com.dfsek.terra.config.base; -import com.dfsek.terra.config.ConfigPack; import com.dfsek.terra.image.ImageLoader; import org.bukkit.Bukkit; import org.bukkit.World; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java index 76c170224..542ac34cb 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/BiomeGridConfig.java @@ -2,7 +2,7 @@ package com.dfsek.terra.config.genconfig; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.biome.UserDefinedGrid; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.config.exception.ConfigException; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/CarverConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/CarverConfig.java index 09968ef70..d3e9d94d5 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/CarverConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/CarverConfig.java @@ -2,7 +2,7 @@ package com.dfsek.terra.config.genconfig; import com.dfsek.terra.Debug; import com.dfsek.terra.carving.UserDefinedCarver; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.exception.ConfigException; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/FloraConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/FloraConfig.java index 789e73aa3..de60f7ada 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/FloraConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/FloraConfig.java @@ -1,6 +1,6 @@ package com.dfsek.terra.config.genconfig; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.exception.ConfigException; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/OreConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/OreConfig.java index d71762f4b..7e4c1140e 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/OreConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/OreConfig.java @@ -1,6 +1,6 @@ package com.dfsek.terra.config.genconfig; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.exception.ConfigException; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/PaletteConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/PaletteConfig.java index 3f5548e72..89be07a8f 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/PaletteConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/PaletteConfig.java @@ -1,7 +1,7 @@ package com.dfsek.terra.config.genconfig; import com.dfsek.terra.Debug; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.exception.ConfigException; import org.bukkit.Bukkit; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java index 33e686dac..aaa792f98 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/StructureConfig.java @@ -1,7 +1,7 @@ package com.dfsek.terra.config.genconfig; import com.dfsek.terra.Debug; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.exception.ConfigException; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/AbstractBiomeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/AbstractBiomeConfig.java index 86710f581..c8cc87f4b 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/AbstractBiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/AbstractBiomeConfig.java @@ -1,19 +1,14 @@ package com.dfsek.terra.config.genconfig.biome; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.exception.ConfigException; -import com.dfsek.terra.config.genconfig.biome.BiomeConfigUtil; -import org.bukkit.Material; -import org.bukkit.block.data.BlockData; import org.bukkit.configuration.InvalidConfigurationException; -import org.polydev.gaea.world.palette.Palette; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; -import java.util.Objects; public class AbstractBiomeConfig extends TerraConfig { private final String biomeID; diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java index 6cd185b80..223b8cbec 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfig.java @@ -3,7 +3,7 @@ package com.dfsek.terra.config.genconfig.biome; import com.dfsek.terra.Debug; import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.carving.UserDefinedCarver; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.TerraConfig; import com.dfsek.terra.config.exception.ConfigException; import com.dfsek.terra.config.exception.NotFoundException; @@ -19,6 +19,7 @@ import org.polydev.gaea.math.FastNoise; import org.polydev.gaea.math.ProbabilityCollection; import org.polydev.gaea.math.Range; import org.polydev.gaea.math.parsii.tokenizer.ParseException; +import org.polydev.gaea.tree.Tree; import org.polydev.gaea.world.Flora; import org.polydev.gaea.world.palette.Palette; import org.polydev.gaea.world.palette.RandomPalette; @@ -39,6 +40,7 @@ public class BiomeConfig extends TerraConfig { private final BiomeOreConfig ore; private final BiomeCarverConfig carver; private final BiomeFloraConfig flora; + private final BiomeTreeConfig tree; private String eq; private int floraAttempts; private final BiomeSlabConfig slab; @@ -128,7 +130,6 @@ public class BiomeConfig extends TerraConfig { } else flora = new BiomeFloraConfig(this); // Check if trees should be handled by super biome. - BiomeTreeConfig tree; if(extending && abstractBiome.getTrees() != null && ! contains("trees")) { tree = abstractBiome.getTrees(); Debug.info("Using super trees"); @@ -273,4 +274,8 @@ public class BiomeConfig extends TerraConfig { public List getStructures() { return structures; } + + public Range getTreeRange(Tree t) { + return tree.getTreeHeights().getOrDefault(t, new Range(-1, -1)); + } } diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfigUtil.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfigUtil.java deleted file mode 100644 index b1c6ded6c..000000000 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeConfigUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.dfsek.terra.config.genconfig.biome; - -import com.dfsek.terra.Debug; -import com.dfsek.terra.config.exception.ConfigException; -import com.dfsek.terra.config.TerraConfig; -import com.dfsek.terra.config.exception.NotFoundException; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.block.data.BlockData; -import org.bukkit.configuration.InvalidConfigurationException; -import org.polydev.gaea.math.ProbabilityCollection; -import org.polydev.gaea.world.palette.Palette; -import org.polydev.gaea.world.palette.RandomPalette; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -public class BiomeConfigUtil { - protected static Map> getSlabPalettes(List> paletteConfigSection, TerraConfig config) throws InvalidConfigurationException { - Map> paletteMap = new HashMap<>(); - - for(Map e : paletteConfigSection) { - for(Map.Entry entry : e.entrySet()) { - try { - if(((String) entry.getValue()).startsWith("BLOCK:")) { - try { - Debug.info("Adding slab palette with single material " + entry.getKey()); - paletteMap.put(Bukkit.createBlockData((String) entry.getKey()).getMaterial(), new RandomPalette(new Random(0)).add(new ProbabilityCollection().add(Bukkit.createBlockData(((String) entry.getValue()).substring(6)), 1), 1)); - } catch(IllegalArgumentException ex) { - throw new ConfigException("Invalid BlockData in slab configuration: " + ex.getMessage(), config.getID()); - } - } else { - try { - Palette p = config.getConfig().getPalette((String) entry.getValue()).getPalette(); - if(p.getSize() != 1) throw new InvalidConfigurationException("Slab palette must hold only one layer. Palette " + entry.getValue() + " is too large/small"); - paletteMap.put(Bukkit.createBlockData((String) entry.getKey()).getMaterial(), p); - } catch(NullPointerException ex) { - throw new NotFoundException("Slab Palette", (String) entry.getValue(), config.getID()); - } - } - } catch(ClassCastException ex) { - throw new ConfigException("Unable to parse Slab Palette configuration! Check YAML syntax.", config.getID()); - } - } - } - Debug.info("Adding " + paletteMap.size() + " slab palettes..."); - return paletteMap; - } -} diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeSlabConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeSlabConfig.java index 91842bd19..dd9a88717 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeSlabConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeSlabConfig.java @@ -24,9 +24,9 @@ public class BiomeSlabConfig extends TerraConfigSection { private final Map> stairs; public BiomeSlabConfig(@NotNull TerraConfig parent) throws InvalidConfigurationException { super(parent); - slabs = BiomeConfigUtil.getSlabPalettes(parent.getMapList("slabs.palettes"), parent); + slabs = getSlabPalettes(parent.getMapList("slabs.palettes")); if(parent.contains("slabs.stair-palettes") && parent.getBoolean("slabs.use-stairs-if-available", false)) { - stairs = BiomeConfigUtil.getSlabPalettes(parent.getMapList("slabs.stair-palettes"), parent); + stairs = getSlabPalettes(parent.getMapList("slabs.stair-palettes")); } else stairs = new HashMap<>(); } protected Map> getSlabPalettes(List> paletteConfigSection) throws InvalidConfigurationException { diff --git a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java index dc012d74c..f716128c5 100644 --- a/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java +++ b/src/main/java/com/dfsek/terra/config/genconfig/biome/BiomeTreeConfig.java @@ -6,13 +6,17 @@ import com.dfsek.terra.config.exception.ConfigException; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.polydev.gaea.math.ProbabilityCollection; +import org.polydev.gaea.math.Range; import org.polydev.gaea.tree.Tree; import org.polydev.gaea.tree.TreeType; +import org.polydev.gaea.world.Flora; +import java.util.HashMap; import java.util.Map; public class BiomeTreeConfig extends TerraConfigSection { private final ProbabilityCollection trees = new ProbabilityCollection<>(); + private final Map treeHeights = new HashMap<>(); public BiomeTreeConfig(TerraConfig parent) throws InvalidConfigurationException { super(parent); ConfigurationSection c = parent.getConfigurationSection("trees"); @@ -21,7 +25,11 @@ public class BiomeTreeConfig extends TerraConfigSection { if(cfg.size() == 0) return; for(Map.Entry e : cfg.entrySet()) { try { - trees.add(TreeType.valueOf(e.getKey()), (Integer) e.getValue()); + Map val = ((ConfigurationSection) e.getValue()).getValues(false); + Map y = ((ConfigurationSection) val.get("y")).getValues(false); + Tree tree = TreeType.valueOf(e.getKey()); + trees.add(tree, (Integer) val.get("weight")); + treeHeights.put(tree, new Range((Integer) y.get("min"), (Integer) y.get("max"))); } catch(ClassCastException ex) { throw new ConfigException("Unable to parse Tree configuration! Check YAML syntax.", parent.getID()); } catch(IllegalArgumentException ex) { @@ -33,4 +41,8 @@ public class BiomeTreeConfig extends TerraConfigSection { public ProbabilityCollection getTrees() { return trees; } + + public Map getTreeHeights() { + return treeHeights; + } } diff --git a/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java b/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java index 041a03d60..a7a0241bc 100644 --- a/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java +++ b/src/main/java/com/dfsek/terra/generation/TerraChunkGenerator.java @@ -4,7 +4,7 @@ import com.dfsek.terra.Debug; import com.dfsek.terra.Terra; import com.dfsek.terra.TerraWorld; import com.dfsek.terra.biome.UserDefinedBiome; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import com.dfsek.terra.population.CavePopulator; import com.dfsek.terra.population.FloraPopulator; @@ -145,7 +145,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { needsLoad = false; } - public static void saveAll() { + public static synchronized void saveAll() { for(Map.Entry e : popMap.entrySet()) { try { e.getValue().saveBlocks(e.getKey()); diff --git a/src/main/java/com/dfsek/terra/population/CavePopulator.java b/src/main/java/com/dfsek/terra/population/CavePopulator.java index 28f38a06c..0996399da 100644 --- a/src/main/java/com/dfsek/terra/population/CavePopulator.java +++ b/src/main/java/com/dfsek/terra/population/CavePopulator.java @@ -2,8 +2,7 @@ package com.dfsek.terra.population; import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraWorld; -import com.dfsek.terra.carving.SimplexCarver; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.base.ConfigUtil; import com.dfsek.terra.config.genconfig.CarverConfig; import org.bukkit.Chunk; @@ -80,10 +79,10 @@ public class CavePopulator extends BlockPopulator { b.setBlockData(orig, true); } } - for(Map.Entry e : new SimplexCarver(chunk.getX(), chunk.getZ()).carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks().entrySet()) { + /*for(Map.Entry e : new SimplexCarver(chunk.getX(), chunk.getZ()).carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks().entrySet()) { Vector v = e.getKey(); chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ()).setBlockData(AIR, false); - } + }*/ } } diff --git a/src/main/java/com/dfsek/terra/population/FloraPopulator.java b/src/main/java/com/dfsek/terra/population/FloraPopulator.java index 75bd488a9..1073390b2 100644 --- a/src/main/java/com/dfsek/terra/population/FloraPopulator.java +++ b/src/main/java/com/dfsek/terra/population/FloraPopulator.java @@ -4,7 +4,7 @@ import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraWorld; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.genconfig.biome.BiomeConfig; import org.bukkit.Chunk; import org.bukkit.World; diff --git a/src/main/java/com/dfsek/terra/population/OrePopulator.java b/src/main/java/com/dfsek/terra/population/OrePopulator.java index 83a091a33..b96bf5d59 100644 --- a/src/main/java/com/dfsek/terra/population/OrePopulator.java +++ b/src/main/java/com/dfsek/terra/population/OrePopulator.java @@ -1,7 +1,7 @@ package com.dfsek.terra.population; import com.dfsek.terra.TerraWorld; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import org.polydev.gaea.math.Range; import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.biome.UserDefinedBiome; diff --git a/src/main/java/com/dfsek/terra/population/SnowPopulator.java b/src/main/java/com/dfsek/terra/population/SnowPopulator.java new file mode 100644 index 000000000..a6ea5e38c --- /dev/null +++ b/src/main/java/com/dfsek/terra/population/SnowPopulator.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.population; + +import org.bukkit.Chunk; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; +import org.polydev.gaea.population.GaeaBlockPopulator; + +import java.util.Random; + +public class SnowPopulator extends GaeaBlockPopulator { + @Override + public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { + + } +} diff --git a/src/main/java/com/dfsek/terra/population/StructurePopulator.java b/src/main/java/com/dfsek/terra/population/StructurePopulator.java index 02796c252..8c4dd0971 100644 --- a/src/main/java/com/dfsek/terra/population/StructurePopulator.java +++ b/src/main/java/com/dfsek/terra/population/StructurePopulator.java @@ -4,7 +4,7 @@ import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraWorld; import com.dfsek.terra.biome.TerraBiomeGrid; import com.dfsek.terra.biome.UserDefinedBiome; -import com.dfsek.terra.config.ConfigPack; +import com.dfsek.terra.config.base.ConfigPack; import com.dfsek.terra.config.genconfig.StructureConfig; import com.dfsek.terra.structure.GaeaStructure; import com.dfsek.terra.structure.StructureSpawnRequirement; diff --git a/src/main/java/com/dfsek/terra/population/TreePopulator.java b/src/main/java/com/dfsek/terra/population/TreePopulator.java index 2741909c1..0e4553ed5 100644 --- a/src/main/java/com/dfsek/terra/population/TreePopulator.java +++ b/src/main/java/com/dfsek/terra/population/TreePopulator.java @@ -4,18 +4,24 @@ import com.dfsek.terra.Terra; import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.TerraWorld; import com.dfsek.terra.biome.TerraBiomeGrid; +import com.dfsek.terra.biome.UserDefinedBiome; import com.dfsek.terra.config.base.WorldConfig; import com.dfsek.terra.generation.UserDefinedDecorator; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.block.Block; import org.jetbrains.annotations.NotNull; import org.polydev.gaea.biome.Biome; import org.polydev.gaea.generation.GenerationPhase; +import org.polydev.gaea.math.Range; import org.polydev.gaea.population.GaeaBlockPopulator; import org.polydev.gaea.profiler.ProfileFuture; +import org.polydev.gaea.tree.Tree; import org.polydev.gaea.util.WorldUtil; +import java.util.ArrayList; +import java.util.List; import java.util.Random; public class TreePopulator extends GaeaBlockPopulator { @@ -26,8 +32,9 @@ public class TreePopulator extends GaeaBlockPopulator { TerraBiomeGrid grid = tw.getGrid();; int x = random.nextInt(16); // Decrease chances of chunk-crossing trees int z = random.nextInt(16); - Location origin = chunk.getBlock(x, 0, z).getLocation(); - Biome b = grid.getBiome(origin, GenerationPhase.POPULATE); + int origX = chunk.getX() << 4; + int origZ = chunk.getZ() << 4; + Biome b = grid.getBiome(x+origX, z+origZ, GenerationPhase.POPULATE); if(((UserDefinedDecorator) b.getDecorator()).getTreeChance() < random.nextInt(100)) return; int max = 50; int att = 0; @@ -38,15 +45,28 @@ public class TreePopulator extends GaeaBlockPopulator { if(chunk.getBlock(x, y, z).getType().isAir() && chunk.getBlock(x, y-1, z).getType().isSolid()) break; y--; } - if(y == 0) continue; - origin = chunk.getBlock(x, y, z).getLocation().add(0, 1, 0); - b = grid.getBiome(origin, GenerationPhase.POPULATE); - try { - if(b.getDecorator().getTrees().get(random).plant(origin, random, false, Terra.getInstance())) i++; - } catch(NullPointerException ignore) {} + Tree tree = b.getDecorator().getTrees().get(random); + Range range = tw.getConfig().getBiome((UserDefinedBiome) b).getTreeRange(tree); + if(!tw.getConfig().getBiome((UserDefinedBiome) b).getTreeRange(tree).isInRange(y)) continue; + b = grid.getBiome(x+origX, z+origZ, GenerationPhase.POPULATE); + for(Block block : getValidSpawnsAt(chunk, x, z, range)) { + try { + if(tree.plant(block.getLocation(), random, false, Terra.getInstance())) i++; + } catch(NullPointerException ignore) {} + } + x = random.nextInt(16); z = random.nextInt(16); } } } + public List getValidSpawnsAt(Chunk chunk, int x, int z, Range check) { + List blocks = new ArrayList<>(); + for(int y : check) { + if(chunk.getBlock(x, y, z).getType().isSolid() && chunk.getBlock(x, y + 1, z).getType().isAir()) { + blocks.add(chunk.getBlock(x, y, z)); + } + } + return blocks; + } } diff --git a/src/main/java/com/dfsek/terra/procgen/math/Vector2.java b/src/main/java/com/dfsek/terra/procgen/math/Vector2.java new file mode 100644 index 000000000..83764e25d --- /dev/null +++ b/src/main/java/com/dfsek/terra/procgen/math/Vector2.java @@ -0,0 +1,157 @@ +package com.dfsek.terra.procgen.math; + +import org.bukkit.util.Vector; + +/** + * oh yeah + */ +public class Vector2 implements Cloneable { + private double x; + private double z; + + /** + * Create a vector with a given X and Z component + * @param x X component + * @param z Z component + */ + public Vector2(double x, double z) { + this.x = x; + this.z = z; + } + + /** + * Get X component + * @return X component + */ + public double getX() { + return x; + } + + /** + * Get Z component + * @return Z component + */ + public double getZ() { + return z; + } + + /** + * Multiply X and Z components by a value. + * @param m Value to multiply + * @return Mutated vector, for chaining. + */ + public Vector2 multiply(double m) { + x*=m; + z*=m; + return this; + } + + /** + * Divide X and Z components by a value. + * @param d Divisor + * @return Mutated vector, for chaining. + */ + public Vector2 divide(double d) { + x/=d; + z/=d; + return this; + } + + /** + * Get the squared length of this Vector + * @return squared length + */ + public double lengthSquared() { + return x*x+z*z; + } + + /** + * Get the length of this Vector + * @return length + */ + public double length() { + return Math.sqrt(lengthSquared()); + } + + /** + * Add this vector to another. + * @param other Vector to add + * @return Mutated vector, for chaining. + */ + public Vector2 add(Vector2 other) { + x+=other.x; + z+=other.z; + return this; + } + + /** + * Subtract a vector from this vector, + * @param other Vector to subtract + * @return Mutated vector, for chaining. + */ + public Vector2 subtract(Vector2 other) { + x-=other.x; + z-=other.z; + return this; + } + + /** + * Normalize this vector to length 1 + * @return Mutated vector, for chaining. + */ + public Vector2 normalize() { + divide(length()); + return this; + } + + /** + * Get the distance from this vector to another. + * @param other Another vector + * @return Distance between vectors + */ + public double distance(Vector2 other) { + return Math.sqrt(distanceSquared(other)); + } + + /** + * Get the squared distance between 2 vectors. + * @param other Another vector + * @return Squared distance + */ + public double distanceSquared(Vector2 other) { + double dx = other.x - x; + double dz = other.z - z; + return dx * dx + dz * dz; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Vector2)) { + return false; + } + Vector2 other = (Vector2) obj; + return other.x == this.x && other.z == this.z; + } + + @Override + public int hashCode() { + int hash = 17; + hash = 31 * hash + Double.hashCode(x); + hash = 31 * hash + Double.hashCode(z); + return hash; + } + + @Override + public String toString() { + return "(" + x + ", " + z + ")"; + } + + @Override + public Vector2 clone() { + try { + return (Vector2) super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } +} diff --git a/src/main/java/com/dfsek/terra/procgen/pixel/Distribution.java b/src/main/java/com/dfsek/terra/procgen/pixel/Distribution.java new file mode 100644 index 000000000..ff4dd475f --- /dev/null +++ b/src/main/java/com/dfsek/terra/procgen/pixel/Distribution.java @@ -0,0 +1,7 @@ +package com.dfsek.terra.procgen.pixel; + +public class Distribution { + public Distribution(Rectangle bound, int numPoints, double minRad) { + + } +} diff --git a/src/main/java/com/dfsek/terra/procgen/pixel/Polygon.java b/src/main/java/com/dfsek/terra/procgen/pixel/Polygon.java new file mode 100644 index 000000000..1072d6f44 --- /dev/null +++ b/src/main/java/com/dfsek/terra/procgen/pixel/Polygon.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.procgen.pixel; + +import com.dfsek.terra.procgen.math.Vector2; + +import java.util.Set; + +public abstract class Polygon { + public abstract Set getContainedPixels(); +} diff --git a/src/main/java/com/dfsek/terra/procgen/pixel/Rectangle.java b/src/main/java/com/dfsek/terra/procgen/pixel/Rectangle.java new file mode 100644 index 000000000..532762a1e --- /dev/null +++ b/src/main/java/com/dfsek/terra/procgen/pixel/Rectangle.java @@ -0,0 +1,31 @@ +package com.dfsek.terra.procgen.pixel; + +import com.dfsek.terra.procgen.math.Vector2; + +import java.util.HashSet; +import java.util.Set; + +public class Rectangle extends Polygon { + private Vector2 min; + private Vector2 max; + public Rectangle(Vector2 min, Vector2 max) { + this.max = new Vector2(Math.min(min.getX(), max.getX()), Math.min(min.getZ(), max.getZ())); + this.min = new Vector2(Math.max(min.getX(), max.getX()), Math.max(min.getZ(), max.getZ()));; + } + public Rectangle(Vector2 center, double xRadius, double zRadius) { + Vector2 rad = new Vector2(xRadius, zRadius); + this.min = center.clone().subtract(rad); + this.max = center.clone().add(rad); + } + + @Override + public Set getContainedPixels() { + Set pixels = new HashSet<>(); + for(int x = (int) min.getX(); x <= max.getX(); x++) { + for(int z = (int) min.getZ(); z <= max.getZ(); z++) { + pixels.add(new Vector2(x, z)); + } + } + return pixels; + } +} diff --git a/src/main/java/com/dfsek/terra/procgen/voxel/VoxelGeometry.java b/src/main/java/com/dfsek/terra/procgen/voxel/VoxelGeometry.java index 289f20603..21ef9d263 100644 --- a/src/main/java/com/dfsek/terra/procgen/voxel/VoxelGeometry.java +++ b/src/main/java/com/dfsek/terra/procgen/voxel/VoxelGeometry.java @@ -17,7 +17,7 @@ public abstract class VoxelGeometry { } public void merge(VoxelGeometry other) { - geometry.addAll(other.getGeometry()); + geometry.addAll(other.geometry); } public static VoxelGeometry getBlank() { return new VoxelGeometry() {};