From aec54861449510ee69c915dc9290425b584e8d54 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Thu, 30 Jul 2020 02:58:08 -0400 Subject: [PATCH] Fixes --- src/main/java/com/volmit/iris/Iris.java | 8 +++ .../generator/ContextualChunkGenerator.java | 2 +- .../generator/DimensionChunkGenerator.java | 1 + .../iris/generator/IrisChunkGenerator.java | 38 +++++++++++++ .../generator/ParallaxChunkGenerator.java | 14 ++++- .../iris/generator/TerrainChunkGenerator.java | 56 +++++++++++++++++-- .../com/volmit/iris/layer/GenLayerCarve.java | 45 +++++++++++++++ .../volmit/iris/layer/post/PostSlabber.java | 2 +- .../iris/layer/post/PostWallPatcher.java | 5 ++ .../iris/object/IrisBiomeDecorator.java | 2 +- .../com/volmit/iris/object/IrisDimension.java | 24 ++++++++ .../iris/object/atomics/AtomicRegionData.java | 14 ++++- .../iris/object/atomics/AtomicSliver.java | 31 ++++++++++ .../volmit/iris/util/IrisPostBlockFilter.java | 12 ++++ 14 files changed, 241 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/volmit/iris/layer/GenLayerCarve.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index a8bd5202d..637bf14cc 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -226,6 +226,14 @@ public class Iris extends JavaPlugin implements BoardProvider i.close(); } + for(World i : Bukkit.getWorlds()) + { + if(i.getGenerator() instanceof IrisChunkGenerator) + { + ((IrisChunkGenerator) i).close(); + } + } + executors.clear(); manager.onDisable(); Bukkit.getScheduler().cancelTasks(this); diff --git a/src/main/java/com/volmit/iris/generator/ContextualChunkGenerator.java b/src/main/java/com/volmit/iris/generator/ContextualChunkGenerator.java index 164dc755b..176330385 100644 --- a/src/main/java/com/volmit/iris/generator/ContextualChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/ContextualChunkGenerator.java @@ -183,7 +183,7 @@ public abstract class ContextualChunkGenerator extends ChunkGenerator implements } } - protected void close() + public void close() { HandlerList.unregisterAll(this); Bukkit.getScheduler().cancelTask(getTask()); diff --git a/src/main/java/com/volmit/iris/generator/DimensionChunkGenerator.java b/src/main/java/com/volmit/iris/generator/DimensionChunkGenerator.java index a88c5fb08..d7acc10c0 100644 --- a/src/main/java/com/volmit/iris/generator/DimensionChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/DimensionChunkGenerator.java @@ -19,6 +19,7 @@ public abstract class DimensionChunkGenerator extends ContextualChunkGenerator { protected final String dimensionName; protected static final BlockData AIR = Material.AIR.createBlockData(); + protected static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData(); protected static final BlockData BEDROCK = Material.BEDROCK.createBlockData(); public DimensionChunkGenerator(String dimensionName) diff --git a/src/main/java/com/volmit/iris/generator/IrisChunkGenerator.java b/src/main/java/com/volmit/iris/generator/IrisChunkGenerator.java index 87b844745..daea1a11a 100644 --- a/src/main/java/com/volmit/iris/generator/IrisChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/IrisChunkGenerator.java @@ -1,9 +1,11 @@ package com.volmit.iris.generator; +import java.io.IOException; import java.lang.reflect.Method; import java.util.concurrent.locks.ReentrantLock; import org.bukkit.Chunk; +import org.bukkit.World; import org.bukkit.entity.Player; import com.volmit.iris.Iris; @@ -40,6 +42,19 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon lock.unlock(); } + public void onInit(World world, RNG rng) + { + try + { + super.onInit(world, rng); + } + + catch(Throwable e) + { + fail(e); + } + } + @Override public BiomeResult getBiome(int x, int z) { @@ -68,6 +83,29 @@ public class IrisChunkGenerator extends CeilingChunkGenerator implements IrisCon protected void onClose() { super.onClose(); + + try + { + parallaxMap.saveAll(); + ceilingParallaxMap.saveAll(); + parallaxMap.getLoadedChunks().clear(); + parallaxMap.getLoadedRegions().clear(); + ceilingParallaxMap.getLoadedChunks().clear(); + ceilingParallaxMap.getLoadedRegions().clear(); + } + + catch(IOException e) + { + e.printStackTrace(); + } + + setBiomeCache(null); + setAvailableFilters(null); + setBiomeHitCache(null); + setCacheTrueBiome(null); + setCacheHeightMap(null); + setCeilingSliverCache(null); + setSliverCache(null); Iris.info("Closing Iris Dimension " + getWorld().getName()); } diff --git a/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java b/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java index de4041ee8..ea824a4db 100644 --- a/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java @@ -89,7 +89,19 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple @Override public int getHighest(int x, int z, boolean ignoreFluid) { - return (int) Math.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z)); + int h = (int) Math.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z)); + + if(getDimension().isCarving() && h >= getDimension().getCarvingMin()) + { + while(getGlCarve().isCarved(x, h, z)) + { + h--; + } + + return h; + } + + return h; } @Override diff --git a/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java b/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java index 56e7b7185..9fd235ee9 100644 --- a/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java @@ -9,6 +9,7 @@ import org.bukkit.block.data.Bisected.Half; import org.bukkit.block.data.BlockData; import com.volmit.iris.Iris; +import com.volmit.iris.layer.GenLayerCarve; import com.volmit.iris.layer.GenLayerCave; import com.volmit.iris.object.DecorationPart; import com.volmit.iris.object.InferredType; @@ -35,6 +36,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator private long lastUpdateRequest = M.ms(); private long lastChunkLoad = M.ms(); private GenLayerCave glCave; + private GenLayerCarve glCarve; private RNG rockRandom; private int[] cacheHeightMap; private IrisBiome[] cacheTrueBiome; @@ -55,6 +57,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator super.onInit(world, rng); rockRandom = getMasterRandom().nextParallelRNG(2858678); glCave = new GenLayerCave(this, rng.nextParallelRNG(238948)); + glCarve = new GenLayerCarve(this, rng.nextParallelRNG(968346576)); } public KList getCaves(int x, int z) @@ -78,6 +81,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator try { + int highestPlaced = 0; BlockData block; int fluidHeight = getDimension().getFluidHeight(); double ox = getModifiedX(rx, rz); @@ -87,6 +91,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator int depth = 0; double noise = getNoiseHeight(rx, rz); int height = (int) Math.round(noise) + fluidHeight; + boolean carvable = getDimension().isCarving() && height > getDimension().getCarvingMin(); IrisRegion region = sampleRegion(rx, rz); IrisBiome biome = sampleTrueBiome(rx, rz).getBiome(); @@ -107,14 +112,15 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator { Iris.error("Failed to write cache at " + x + " " + z + " in chunk " + cx + " " + cz); } - } KList layers = biome.generateLayers(wx, wz, masterRandom, height, height - getFluidHeight()); KList seaLayers = biome.isSea() ? biome.generateSeaLayers(wx, wz, masterRandom, fluidHeight - height) : new KList<>(); cacheInternalBiome(x, z, biome); + boolean caverning = false; + KList cavernHeights = new KList<>(); + int lastCavernHeight = -1; - // Set ground biome (color) to HEIGHT - HEIGHT+3 for(int k = Math.max(height, fluidHeight); k < Math.max(height, fluidHeight) + 3; k++) { if(k < Math.max(height, fluidHeight) + 3) @@ -128,12 +134,41 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator for(int k = Math.max(height, fluidHeight); k >= 0; k--) { + boolean cavernSurface = false; + if(k == 0) { + if(biomeMap != null) + { + sliver.set(k, biome.getDerivative()); + biomeMap.setBiome(x, z, biome); + } + sliver.set(k, BEDROCK); continue; } + if(carvable && glCarve.isCarved(rx, k, rz)) + { + if(biomeMap != null) + { + sliver.set(k, biome.getDerivative()); + biomeMap.setBiome(x, z, biome); + } + + sliver.set(k, CAVE_AIR); + caverning = true; + continue; + } + + else if(carvable && caverning) + { + lastCavernHeight = k; + cavernSurface = true; + cavernHeights.add(k); + caverning = false; + } + boolean underwater = k > height && k <= fluidHeight; if(biomeMap != null) @@ -147,6 +182,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator block = seaLayers.hasIndex(fluidHeight - k) ? layers.get(depth) : getDimension().getFluid(rockRandom, wx, k, wz); } + else if(layers.hasIndex(lastCavernHeight - k)) + { + block = layers.get(lastCavernHeight - k); + } + else { block = layers.hasIndex(depth) ? layers.get(depth) : getDimension().getRock(rockRandom, wx, k, wz); @@ -154,15 +194,14 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator } sliver.set(k, block); + highestPlaced = Math.max(highestPlaced, k); - // Decorate underwater - if(k == height && block.getMaterial().isSolid() && k < fluidHeight) + if(!cavernSurface && (k == height && block.getMaterial().isSolid() && k < fluidHeight)) { decorateUnderwater(biome, sliver, wx, k, wz, rx, rz, block); } - // Decorate land - if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k > fluidHeight) + if((carvable && cavernSurface) || (k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k > fluidHeight)) { decorateLand(biome, sliver, wx, k, wz, rx, rz, block); } @@ -205,6 +244,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator } } } + + if(caching && highestPlaced < height) + { + cacheHeightMap[(z << 4) | x] = highestPlaced; + } } catch(Throwable e) diff --git a/src/main/java/com/volmit/iris/layer/GenLayerCarve.java b/src/main/java/com/volmit/iris/layer/GenLayerCarve.java new file mode 100644 index 000000000..bf4ab0684 --- /dev/null +++ b/src/main/java/com/volmit/iris/layer/GenLayerCarve.java @@ -0,0 +1,45 @@ +package com.volmit.iris.layer; + +import com.volmit.iris.generator.DimensionChunkGenerator; +import com.volmit.iris.util.CellGenerator; +import com.volmit.iris.util.GenLayer; +import com.volmit.iris.util.IrisInterpolation; +import com.volmit.iris.util.M; +import com.volmit.iris.util.RNG; + +public class GenLayerCarve extends GenLayer +{ + private CellGenerator cell; + + public GenLayerCarve(DimensionChunkGenerator iris, RNG rng) + { + super(iris, rng); + cell = new CellGenerator(rng.nextParallelRNG(-135486678)); + } + + public boolean isCarved(int xc, int y, int zc) + { + if(y > iris.getDimension().getCarvingMax() || y < iris.getDimension().getCarvingMin()) + { + return false; + } + + double x = ((double) xc / iris.getDimension().getCarvingZoom()); + double z = ((double) zc / iris.getDimension().getCarvingZoom()); + + double opacity = Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(iris.getDimension().getCarvingMin(), iris.getDimension().getCarvingMax(), y)), 4); + + if(cell.getDistance(x - (Math.cos(y / iris.getDimension().getCarvingRippleThickness()) + 0.5D) / 2D, y / iris.getDimension().getCarvingSliverThickness(), z + (Math.sin(y / iris.getDimension().getCarvingRippleThickness()) + 0.5D) / 2D) < opacity * iris.getDimension().getCarvingEnvelope()) + { + return true; + } + + return false; + } + + @Override + public double generate(double x, double z) + { + return 0; + } +} diff --git a/src/main/java/com/volmit/iris/layer/post/PostSlabber.java b/src/main/java/com/volmit/iris/layer/post/PostSlabber.java index baaf31937..4bdc579b2 100644 --- a/src/main/java/com/volmit/iris/layer/post/PostSlabber.java +++ b/src/main/java/com/volmit/iris/layer/post/PostSlabber.java @@ -34,7 +34,7 @@ public class PostSlabber extends IrisPostBlockFilter int hc = highestTerrainBlock(x - 1, z); int hd = highestTerrainBlock(x, z - 1); - if(ha == h + 1 || hb == h + 1 || hc == h + 1 || hd == h + 1) + if((ha == h + 1 && isSolid(x + 1, ha, z)) || (hb == h + 1 && isSolid(x, hb, z + 1)) || (hc == h + 1 && isSolid(x - 1, hc, z)) || (hd == h + 1 && isSolid(x, hd, z - 1))) { BlockData d = gen.sampleTrueBiome(x, z).getBiome().getSlab().get(rng, x, h, z); diff --git a/src/main/java/com/volmit/iris/layer/post/PostWallPatcher.java b/src/main/java/com/volmit/iris/layer/post/PostWallPatcher.java index 396a27fc6..b5c25042c 100644 --- a/src/main/java/com/volmit/iris/layer/post/PostWallPatcher.java +++ b/src/main/java/com/volmit/iris/layer/post/PostWallPatcher.java @@ -64,6 +64,11 @@ public class PostWallPatcher extends IrisPostBlockFilter continue; } + if(isAirOrWater(x, i, z)) + { + continue; + } + setPostBlock(x, i, z, d); } } diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java index f2ef63859..b473e809c 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java +++ b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java @@ -124,7 +124,7 @@ public class IrisBiomeDecorator double xx = dispersion.equals(Dispersion.SCATTER) ? nrng.i(-100000, 100000) : x; double zz = dispersion.equals(Dispersion.SCATTER) ? nrng.i(-100000, 100000) : z; - if(getGenerator(nrng).fitDoubleD(0D, 1D, xx, zz) <= chance) + if(getGenerator(rng).fitDoubleD(0D, 1D, xx, zz) <= chance) { try { diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index afe9ae447..f58d70bf6 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -54,6 +54,30 @@ public class IrisDimension extends IrisRegistrant @Desc("Generate caves or not.") private boolean caves = true; + @DontObfuscate + @Desc("Carve terrain or not") + private double carvingZoom = 3.5; + + @DontObfuscate + @Desc("Carving starts at this height") + private int carvingMin = 115; + + @DontObfuscate + @Desc("The maximum height carving happens at") + private int carvingMax = 239; + + @DontObfuscate + @Desc("The thickness of carvings (vertical)") + private double carvingSliverThickness = 5.5D; + + @DontObfuscate + @Desc("The thickness of ripples on carved walls") + private double carvingRippleThickness = 3D; + + @DontObfuscate + @Desc("How much of 3D space is carved out. Higher values make carvings cross into 3d space more often (bigger)") + private double carvingEnvelope = 0.335D; + @DontObfuscate @Desc("Carve terrain or not") private boolean carving = true; diff --git a/src/main/java/com/volmit/iris/object/atomics/AtomicRegionData.java b/src/main/java/com/volmit/iris/object/atomics/AtomicRegionData.java index 855952645..4bcf552c5 100644 --- a/src/main/java/com/volmit/iris/object/atomics/AtomicRegionData.java +++ b/src/main/java/com/volmit/iris/object/atomics/AtomicRegionData.java @@ -77,9 +77,17 @@ public class AtomicRegionData return data; } - ByteArrayTag btag = (ByteArrayTag) tag.get(rx + "." + rz); - ByteArrayInputStream in = new ByteArrayInputStream(btag.getValue()); - data.read(in); + try + { + ByteArrayTag btag = (ByteArrayTag) tag.get(rx + "." + rz); + ByteArrayInputStream in = new ByteArrayInputStream(btag.getValue()); + data.read(in); + } + + catch(Throwable e) + { + + } return data; } diff --git a/src/main/java/com/volmit/iris/object/atomics/AtomicSliver.java b/src/main/java/com/volmit/iris/object/atomics/AtomicSliver.java index cbedea163..6bd3d82b4 100644 --- a/src/main/java/com/volmit/iris/object/atomics/AtomicSliver.java +++ b/src/main/java/com/volmit/iris/object/atomics/AtomicSliver.java @@ -3,6 +3,7 @@ package com.volmit.iris.object.atomics; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.concurrent.locks.ReentrantLock; import org.bukkit.Material; import org.bukkit.block.Biome; @@ -25,6 +26,7 @@ public class AtomicSliver private KMap block; private KMap truebiome; private KMap biome; + private ReentrantLock lock = new ReentrantLock(); private int highestBlock = 0; private int highestBiome = 0; private long last = M.ms(); @@ -65,8 +67,17 @@ public class AtomicSliver return; } + lock.lock(); block.put(h, d); + + if(d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR)) + { + lock.unlock(); + return; + } + highestBlock = h > highestBlock ? h : highestBlock; + lock.unlock(); } public void setSilently(int h, BlockData d) @@ -76,7 +87,9 @@ public class AtomicSliver return; } + lock.lock(); block.put(h, d); + lock.unlock(); } public boolean isSolid(int h) @@ -98,17 +111,22 @@ public class AtomicSliver public void set(int h, Biome d) { + lock.lock(); biome.put(h, d); highestBiome = h > highestBiome ? h : highestBiome; + lock.unlock(); } public void set(int h, IrisBiome d) { + lock.lock(); truebiome.put(h, d); + lock.unlock(); } public void write(ChunkData d) { + lock.lock(); for(int i = 0; i <= highestBlock; i++) { if(block.get(i) == null) @@ -121,10 +139,12 @@ public class AtomicSliver d.setBlock(x, i, z, block.get(i)); } } + lock.unlock(); } public void write(BiomeGrid d) { + lock.lock(); for(int i = 0; i <= highestBiome; i++) { if(biome.get(i) != null) @@ -132,15 +152,19 @@ public class AtomicSliver d.setBiome(x, i, z, biome.get(i)); } } + lock.unlock(); } public void write(HeightMap height) { + lock.lock(); height.setHeight(x, z, highestBlock); + lock.unlock(); } public void read(DataInputStream din) throws IOException { + lock.lock(); this.block = new KMap(); int h = din.readByte() - Byte.MIN_VALUE; highestBlock = h; @@ -149,10 +173,12 @@ public class AtomicSliver { block.put(i, BlockDataTools.getBlockData(din.readUTF())); } + lock.unlock(); } public void write(DataOutputStream dos) throws IOException { + lock.lock(); dos.writeByte(highestBlock + Byte.MIN_VALUE); for(int i = 0; i <= highestBlock; i++) @@ -160,10 +186,12 @@ public class AtomicSliver BlockData dat = block.get(i); dos.writeUTF((dat == null ? AIR : dat).getAsString(true)); } + lock.unlock(); } public void insert(AtomicSliver atomicSliver) { + lock.lock(); for(int i = 0; i < 256; i++) { if(block.get(i) == null || block.get(i).equals(AIR)) @@ -177,10 +205,12 @@ public class AtomicSliver block.put(i, b); } } + lock.unlock(); } public void inject(ChunkData currentData) { + lock.lock(); for(int i = 0; i < 256; i++) { if(block.get(i) != null && !block.get(i).equals(AIR)) @@ -189,6 +219,7 @@ public class AtomicSliver currentData.setBlock(x, i, z, b); } } + lock.unlock(); } public boolean isOlderThan(long m) diff --git a/src/main/java/com/volmit/iris/util/IrisPostBlockFilter.java b/src/main/java/com/volmit/iris/util/IrisPostBlockFilter.java index 8724babf4..0175e322a 100644 --- a/src/main/java/com/volmit/iris/util/IrisPostBlockFilter.java +++ b/src/main/java/com/volmit/iris/util/IrisPostBlockFilter.java @@ -64,6 +64,18 @@ public abstract class IrisPostBlockFilter implements IPostBlockAccess return d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR); } + public boolean isSolid(int x, int y, int z) + { + BlockData d = getPostBlock(x, y, z); + return d.getMaterial().isSolid(); + } + + public boolean isAirOrWater(int x, int y, int z) + { + BlockData d = getPostBlock(x, y, z); + return d.getMaterial().equals(Material.WATER) || d.getMaterial().equals(Material.AIR) || d.getMaterial().equals(Material.CAVE_AIR); + } + public boolean isSlab(int x, int y, int z) { BlockData d = getPostBlock(x, y, z);