From f53e9d5112e9646b540c6f9385bfbfa98f47c89d Mon Sep 17 00:00:00 2001 From: dfsek Date: Sat, 19 Sep 2020 22:14:00 -0700 Subject: [PATCH] Add block shifting to caves --- .../com/dfsek/terra/TerraChunkGenerator.java | 5 +- .../java/com/dfsek/terra/TerraProfiler.java | 5 +- .../terra/carving/UserDefinedCarver.java | 2 +- .../com/dfsek/terra/config/BiomeConfig.java | 2 +- .../dfsek/terra/config/BiomeGridConfig.java | 2 +- .../com/dfsek/terra/config/CarverConfig.java | 72 ++++++++++++++++--- .../com/dfsek/terra/config/FaunaConfig.java | 2 +- .../com/dfsek/terra/config/OreConfig.java | 2 +- .../com/dfsek/terra/config/PaletteConfig.java | 2 +- .../dfsek/terra/population/CavePopulator.java | 51 ++++++++++--- .../dfsek/terra/population/TreePopulator.java | 1 - 11 files changed, 114 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/dfsek/terra/TerraChunkGenerator.java b/src/main/java/com/dfsek/terra/TerraChunkGenerator.java index 900a3a433..dc6ec8d35 100644 --- a/src/main/java/com/dfsek/terra/TerraChunkGenerator.java +++ b/src/main/java/com/dfsek/terra/TerraChunkGenerator.java @@ -16,6 +16,7 @@ import org.polydev.gaea.math.FastNoise; import org.polydev.gaea.math.InterpolationType; import org.polydev.gaea.population.PopulationManager; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; @@ -55,7 +56,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { @Override public List getGenerationPopulators(World world) { - return Collections.singletonList(new CavePopulator()); + return Collections.emptyList(); } @Override @@ -65,7 +66,7 @@ public class TerraChunkGenerator extends GaeaChunkGenerator { @Override public @NotNull List getDefaultPopulators(@NotNull World world) { - return Collections.singletonList(popMan); + return Arrays.asList(new CavePopulator(), popMan); } @Override diff --git a/src/main/java/com/dfsek/terra/TerraProfiler.java b/src/main/java/com/dfsek/terra/TerraProfiler.java index 61e5f3fe9..416033578 100644 --- a/src/main/java/com/dfsek/terra/TerraProfiler.java +++ b/src/main/java/com/dfsek/terra/TerraProfiler.java @@ -15,9 +15,10 @@ public class TerraProfiler extends WorldProfiler { this.addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "TotalChunkGenTime") .addMeasurement(new Measurement(2500000, DataType.PERIOD_MILLISECONDS), "ChunkBaseGenTime") .addMeasurement(new Measurement(2000000, DataType.PERIOD_MILLISECONDS), "BiomeSetTime") - .addMeasurement(new Measurement(25000000, DataType.PERIOD_MILLISECONDS), "TreeGenTime") + .addMeasurement(new Measurement(25000000, DataType.PERIOD_NANOSECONDS), "TreeGenTime") .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "FaunaTime") - .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveTime"); + .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveTime") + .addMeasurement(new Measurement(1500000, DataType.PERIOD_MILLISECONDS), "CaveBlockUpdate"); profilerMap.put(w, this); } public static TerraProfiler fromWorld(World w) { diff --git a/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java b/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java index 845b6df4e..dae1a2d1e 100644 --- a/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java +++ b/src/main/java/com/dfsek/terra/carving/UserDefinedCarver.java @@ -59,7 +59,7 @@ public class UserDefinedCarver extends Carver { public void step() { setRadius(new int[] {(int) (runningRadius*radiusMultiplier[0]), (int) (runningRadius*radiusMultiplier[1]), (int) (runningRadius*radiusMultiplier[2])}); runningRadius += (getRandom().nextDouble()-0.5)*mutate[3]; - runningRadius = Math.min(runningRadius, maxRad); + runningRadius = Math.max(Math.min(runningRadius, maxRad), 1); direction.rotateAroundX(Math.toRadians(getRandom().nextDouble()*mutate[0])); direction.rotateAroundY(Math.toRadians(getRandom().nextDouble()*mutate[1])); direction.rotateAroundZ(Math.toRadians(getRandom().nextDouble()*mutate[2])); diff --git a/src/main/java/com/dfsek/terra/config/BiomeConfig.java b/src/main/java/com/dfsek/terra/config/BiomeConfig.java index 1b0dd5048..de7f6affd 100644 --- a/src/main/java/com/dfsek/terra/config/BiomeConfig.java +++ b/src/main/java/com/dfsek/terra/config/BiomeConfig.java @@ -214,7 +214,7 @@ public class BiomeConfig extends YamlConfiguration { } catch(IOException e) { e.printStackTrace(); } catch(InvalidConfigurationException | IllegalArgumentException e) { - logger.severe("Configuration error for Biome. "); + logger.severe("Configuration error for Biome. File: " + path.toString()); logger.severe(e.getMessage()); logger.severe("Correct this before proceeding!"); } diff --git a/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java b/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java index 7db3512e0..978d7b400 100644 --- a/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java +++ b/src/main/java/com/dfsek/terra/config/BiomeGridConfig.java @@ -91,7 +91,7 @@ public class BiomeGridConfig extends YamlConfiguration { } catch(IOException e) { e.printStackTrace(); } catch(InvalidConfigurationException | IllegalArgumentException e) { - Bukkit.getLogger().severe("[Terra] Configuration error for BiomeGrid. "); + Bukkit.getLogger().severe("[Terra] Configuration error for BiomeGrid. File: " + path.toString()); Bukkit.getLogger().severe("[Terra] " + e.getMessage()); Bukkit.getLogger().severe("[Terra] Correct this before proceeding!"); } diff --git a/src/main/java/com/dfsek/terra/config/CarverConfig.java b/src/main/java/com/dfsek/terra/config/CarverConfig.java index 48d1f00b2..d0d51992c 100644 --- a/src/main/java/com/dfsek/terra/config/CarverConfig.java +++ b/src/main/java/com/dfsek/terra/config/CarverConfig.java @@ -8,6 +8,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; import org.polydev.gaea.commons.io.FilenameUtils; import org.polydev.gaea.math.ProbabilityCollection; @@ -20,10 +21,12 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.TreeMap; import java.util.logging.Logger; import java.util.stream.Stream; @@ -33,6 +36,9 @@ public class CarverConfig extends YamlConfiguration { private String id; private final Set replaceableInner = new HashSet<>(); private final Set replaceableOuter = new HashSet<>(); + private final Map> shift = new HashMap<>(); + private Map> inner; + private Map> outer; private boolean replaceIsBlacklistInner; private boolean replaceIsBlacklistOuter; public CarverConfig(File file) throws IOException, InvalidConfigurationException { @@ -53,20 +59,29 @@ public class CarverConfig extends YamlConfiguration { public void load(@NotNull File file) throws IOException, InvalidConfigurationException { super.load(file); - if(contains("palette.inner.replace")) { - for(String s : getStringList("palette.inner.replace")) { - replaceableInner.add(Bukkit.createBlockData(s).getMaterial()); - } + inner = getBlocks("palette.inner.blocks"); + + outer = getBlocks("palette.outer.blocks"); + + for(String s : getStringList("palette.inner.replace")) { + replaceableInner.add(Bukkit.createBlockData(s).getMaterial()); } - if(contains("palette.outer.replace")) { - for(String s : getStringList("palette.outer.replace")) { - replaceableOuter.add(Bukkit.createBlockData(s).getMaterial()); - } + for(String s : getStringList("palette.outer.replace")) { + replaceableOuter.add(Bukkit.createBlockData(s).getMaterial()); } + for(Map.Entry e : getConfigurationSection("shift").getValues(false).entrySet()) { + Set l = new HashSet<>(); + for(String s : (List) e.getValue()) { + l.add(Bukkit.createBlockData(s).getMaterial()); + Bukkit.getLogger().info("Added " + s + " to shift-able blocks"); + } + shift.put(Bukkit.createBlockData(e.getKey()).getMaterial(), l); + Bukkit.getLogger().info("Added " + e.getKey() + " as master block"); + } + replaceIsBlacklistInner = getBoolean("palette.inner.replace-blacklist", false); replaceIsBlacklistOuter = getBoolean("palette.outer.replace-blacklist", false); - double[] start = new double[] {getDouble("start.x"), getDouble("start.y"), getDouble("start.z")}; double[] mutate = new double[] {getDouble("mutate.x"), getDouble("mutate.y"), getDouble("mutate.z"), getDouble("mutate.radius")}; double[] radiusMultiplier = new double[] {getDouble("start.radius.multiply.x"), getDouble("start.radius.multiply.y"), getDouble("start.radius.multiply.z")}; @@ -77,6 +92,29 @@ public class CarverConfig extends YamlConfiguration { carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier); } + private Map> getBlocks(String key) throws InvalidConfigurationException { + if(!contains(key)) throw new InvalidConfigurationException("Missing Carver Palette!"); + Map> result = new TreeMap<>(); + for(Map m : getMapList(key)) { + try { + ProbabilityCollection layer = new ProbabilityCollection<>(); + for(Map.Entry type : ((Map) m.get("materials")).entrySet()) { + layer.add(Bukkit.createBlockData(type.getKey()), type.getValue()); + Bukkit.getLogger().info("Added " + type.getKey() + " with probability " + type.getValue()); + } + result.put((Integer) m.get("y"), layer); + Bukkit.getLogger().info("Added at level " + m.get("y")); + } catch(ClassCastException e) { + throw new InvalidConfigurationException("SEVERE configuration error for Carver Palette: \n\n" + e.getMessage()); + } + } + return result; + } + + public Map> getShiftedBlocks() { + return shift; + } + public boolean isReplaceableInner(Material m) { if(replaceIsBlacklistInner) { return !replaceableInner.contains(m); @@ -91,6 +129,20 @@ public class CarverConfig extends YamlConfiguration { return replaceableOuter.contains(m); } + public ProbabilityCollection getPaletteInner(int y) { + for(Map.Entry> e : inner.entrySet()) { + if(e.getKey() >= y ) return e.getValue(); + } + return null; + } + + public ProbabilityCollection getPaletteOuter(int y) { + for(Map.Entry> e : outer.entrySet()) { + if(e.getKey() >= y ) return e.getValue(); + } + return null; + } + protected static void loadCaves(JavaPlugin main) { // TODO: Merge all load methods Logger logger = main.getLogger(); @@ -108,7 +160,7 @@ public class CarverConfig extends YamlConfiguration { } catch(IOException e) { e.printStackTrace(); } catch(InvalidConfigurationException | IllegalArgumentException e) { - logger.severe("Configuration error for Carver. "); + logger.severe("Configuration error for Carver. File: " + path.toString()); logger.severe(e.getMessage()); logger.severe("Correct this before proceeding!"); } diff --git a/src/main/java/com/dfsek/terra/config/FaunaConfig.java b/src/main/java/com/dfsek/terra/config/FaunaConfig.java index f9248ead7..5cdd00232 100644 --- a/src/main/java/com/dfsek/terra/config/FaunaConfig.java +++ b/src/main/java/com/dfsek/terra/config/FaunaConfig.java @@ -105,7 +105,7 @@ public class FaunaConfig extends YamlConfiguration implements Fauna { } catch(IOException e) { e.printStackTrace(); } catch(InvalidConfigurationException | IllegalArgumentException e) { - logger.severe("Configuration error for Fauna. "); + logger.severe("Configuration error for Fauna. File: " + path.toString()); logger.severe(e.getMessage()); logger.severe("Correct this before proceeding!"); } diff --git a/src/main/java/com/dfsek/terra/config/OreConfig.java b/src/main/java/com/dfsek/terra/config/OreConfig.java index 2b47d58ce..8460146d7 100644 --- a/src/main/java/com/dfsek/terra/config/OreConfig.java +++ b/src/main/java/com/dfsek/terra/config/OreConfig.java @@ -112,7 +112,7 @@ public class OreConfig extends YamlConfiguration { } catch(IOException e) { e.printStackTrace(); } catch(InvalidConfigurationException | IllegalArgumentException e) { - logger.severe("Configuration error for Ore. "); + logger.severe("Configuration error for Ore. File: " + path.toString()); logger.severe(e.getMessage()); logger.severe("Correct this before proceeding!"); } diff --git a/src/main/java/com/dfsek/terra/config/PaletteConfig.java b/src/main/java/com/dfsek/terra/config/PaletteConfig.java index 238f9041b..f91d65247 100644 --- a/src/main/java/com/dfsek/terra/config/PaletteConfig.java +++ b/src/main/java/com/dfsek/terra/config/PaletteConfig.java @@ -91,7 +91,7 @@ public class PaletteConfig extends YamlConfiguration { } catch(IOException e) { e.printStackTrace(); } catch(InvalidConfigurationException | IllegalArgumentException e) { - logger.severe("Configuration error for BlockPalette. "); + logger.severe("Configuration error for BlockPalette. File: " + path.toString()); logger.severe(e.getMessage()); logger.severe("Correct this before proceeding!"); } diff --git a/src/main/java/com/dfsek/terra/population/CavePopulator.java b/src/main/java/com/dfsek/terra/population/CavePopulator.java index d07787d93..e3b107644 100644 --- a/src/main/java/com/dfsek/terra/population/CavePopulator.java +++ b/src/main/java/com/dfsek/terra/population/CavePopulator.java @@ -2,37 +2,66 @@ package com.dfsek.terra.population; import com.dfsek.terra.TerraProfiler; import com.dfsek.terra.config.CarverConfig; +import org.bukkit.Chunk; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; import org.polydev.gaea.generation.GenerationPopulator; import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.world.carving.CarvingData; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Set; -public class CavePopulator extends GenerationPopulator { - +public class CavePopulator extends BlockPopulator { @Override - public ChunkGenerator.ChunkData populate(World world, ChunkGenerator.ChunkData chunk, Random random, int chunkX, int chunkZ) { + public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) { + ProfileFuture cave = TerraProfiler.fromWorld(world).measure("CaveTime"); for(CarverConfig c : CarverConfig.getCarvers()) { - ProfileFuture cave = TerraProfiler.fromWorld(world).measure("CaveTime"); - Map blocks = c.getCarver().carve(chunkX, chunkZ, world).getCarvedBlocks(); + Map shiftCandidate = new HashMap<>(); + Map blocks = c.getCarver().carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks(); for(Map.Entry e : blocks.entrySet()) { Vector v = e.getKey(); - Material m = chunk.getType(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + Material m = b.getType(); + boolean liquid = m.equals(Material.WATER) || m.equals(Material.LAVA); if(e.getValue().equals(CarvingData.CarvingType.CENTER) && c.isReplaceableInner(m)) { - chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(), Material.AIR); + if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType()); + b.setBlockData(c.getPaletteInner(v.getBlockY()).get(random), liquid); } else if(c.isReplaceableOuter(m)){ - chunk.setBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ(), Material.ANDESITE); + if(c.getShiftedBlocks().containsKey(b.getType())) shiftCandidate.put(b.getLocation(), b.getType()); + b.setBlockData(c.getPaletteOuter(v.getBlockY()).get(random), liquid); + } else if(liquid) { + b.setBlockData(b.getBlockData(), true); } - } - if(cave != null) cave.complete(); + int i = 0; + int j = 0; + for(Location l : shiftCandidate.keySet()) { + Location mut = l.clone(); + Material orig = l.getBlock().getType(); + do mut.subtract(0, 1, 0); + while(mut.getBlock().getType().equals(orig)); + try { + if(c.getShiftedBlocks().get(shiftCandidate.get(l)).contains(mut.getBlock().getType())) { + mut.getBlock().setType(shiftCandidate.get(l)); + j++; + } + } catch(NullPointerException ignored) {} + i++; + } + if(i > 0) System.out.println("Shifted " + i + " blocks. " + j + " successful shifts."); } - return chunk; + + if(cave != null) cave.complete(); } } diff --git a/src/main/java/com/dfsek/terra/population/TreePopulator.java b/src/main/java/com/dfsek/terra/population/TreePopulator.java index 3e871a78c..51e5f5123 100644 --- a/src/main/java/com/dfsek/terra/population/TreePopulator.java +++ b/src/main/java/com/dfsek/terra/population/TreePopulator.java @@ -10,7 +10,6 @@ import org.bukkit.World; import org.jetbrains.annotations.NotNull; import org.polydev.gaea.biome.Biome; import org.polydev.gaea.population.GaeaBlockPopulator; -import org.polydev.gaea.population.PopulationManager; import org.polydev.gaea.profiler.ProfileFuture; import org.polydev.gaea.util.WorldUtil;