From bccb4e154ded3c4ff81faaebf9397ff06ee3447d Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Tue, 28 Jul 2020 03:13:33 -0400 Subject: [PATCH] Cave Biomes --- src/main/java/com/volmit/iris/Iris.java | 3 +- .../generator/ParallaxChunkGenerator.java | 49 +++++- .../iris/generator/TerrainChunkGenerator.java | 160 ++++++++++++++++-- .../java/com/volmit/iris/layer/BiomeData.java | 10 -- .../volmit/iris/layer/BiomeDataProvider.java | 37 ++++ .../com/volmit/iris/layer/GenLayerBiome.java | 138 ++++++++------- .../com/volmit/iris/layer/GenLayerCave.java | 49 ++++-- .../com/volmit/iris/object/InferredType.java | 6 + .../com/volmit/iris/object/IrisObject.java | 7 +- .../com/volmit/iris/object/IrisRegion.java | 98 +++++++++++ .../iris/object/atomics/AtomicSliver.java | 18 ++ .../com/volmit/iris/util/CellGenerator.java | 10 ++ 12 files changed, 479 insertions(+), 106 deletions(-) delete mode 100644 src/main/java/com/volmit/iris/layer/BiomeData.java create mode 100644 src/main/java/com/volmit/iris/layer/BiomeDataProvider.java diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 159123e4c..034aea957 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -115,8 +115,9 @@ public class Iris extends JavaPlugin implements BoardProvider { IrisChunkGenerator g = (IrisChunkGenerator) world.getGenerator(); int x = player.getLocation().getBlockX(); + int y = player.getLocation().getBlockY(); int z = player.getLocation().getBlockZ(); - BiomeResult er = g.sampleTrueBiome(x, z); + BiomeResult er = g.sampleTrueBiome(x, y, z); IrisBiome b = er != null ? er.getBiome() : null; lines.add("&7&m-----------------"); lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s " + Form.duration(g.getMetrics().getTotal().getAverage(), 1) + ""); diff --git a/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java b/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java index c1520942e..c01378908 100644 --- a/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/ParallaxChunkGenerator.java @@ -16,9 +16,11 @@ import com.volmit.iris.object.atomics.AtomicSliverMap; import com.volmit.iris.object.atomics.AtomicWorldData; import com.volmit.iris.object.atomics.MasterLock; import com.volmit.iris.util.BiomeMap; +import com.volmit.iris.util.CaveResult; import com.volmit.iris.util.ChunkPosition; import com.volmit.iris.util.HeightMap; import com.volmit.iris.util.IObjectPlacer; +import com.volmit.iris.util.KList; import com.volmit.iris.util.KMap; import com.volmit.iris.util.RNG; @@ -242,7 +244,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple { for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { - k.generate((x * 16) + ro.nextInt(16), (z * 16) + ro.nextInt(16), ro, this); + k.generate((i * 16) + ro.nextInt(16), (j * 16) + ro.nextInt(16), ro, this); } } @@ -250,7 +252,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple { for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { - k.generate((x * 16) + ro.nextInt(16), (z * 16) + ro.nextInt(16), ro, this); + k.generate((i * 16) + ro.nextInt(16), (j * 16) + ro.nextInt(16), ro, this); } } @@ -258,7 +260,30 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple { for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++) { - k.generate((x * 16) + ro.nextInt(16), (z * 16) + ro.nextInt(16), ro, this); + k.generate((i * 16) + ro.nextInt(16), (j * 16) + ro.nextInt(16), ro, this); + } + } + + if(getDimension().isCaves()) + { + int bx = (i * 16) + ro.nextInt(16); + int bz = (j * 16) + ro.nextInt(16); + + IrisBiome biome = sampleCaveBiome(bx, bz).getBiome(); + + if(biome == null) + { + return; + } + + if(biome.getObjects().isEmpty()) + { + return; + } + + for(IrisObjectPlacement k : biome.getObjects()) + { + placeCaveObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + g++) * i * j) + i - j + 1869322)); } } }); @@ -279,6 +304,24 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple } } + public void placeCaveObject(IrisObjectPlacement o, int x, int z, RNG rng) + { + for(int i = 0; i < o.getTriesForChunk(rng); i++) + { + rng = rng.nextParallelRNG((i * 3 + 8) - 23040); + int xx = (x * 16) + rng.nextInt(16); + int zz = (z * 16) + rng.nextInt(16); + KList res = getCaves(xx, zz); + + if(res.isEmpty()) + { + continue; + } + + o.getSchematic(rng).place(xx, res.get(rng.nextParallelRNG(29345 * (i + 234)).nextInt(res.size())).getFloor() + 2, zz, this, o, rng); + } + } + @Override protected void onTick(int ticks) { diff --git a/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java b/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java index a6eebe020..655231c89 100644 --- a/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java +++ b/src/main/java/com/volmit/iris/generator/TerrainChunkGenerator.java @@ -4,6 +4,7 @@ import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.data.Bisected; import org.bukkit.block.data.Bisected.Half; +import org.bukkit.block.data.BlockData; import com.volmit.iris.layer.GenLayerCave; import com.volmit.iris.object.DecorationPart; @@ -15,13 +16,12 @@ import com.volmit.iris.object.atomics.AtomicSliver; import com.volmit.iris.util.BiomeMap; import com.volmit.iris.util.BiomeResult; import com.volmit.iris.util.BlockDataTools; +import com.volmit.iris.util.CaveResult; import com.volmit.iris.util.HeightMap; import com.volmit.iris.util.KList; import com.volmit.iris.util.M; import com.volmit.iris.util.RNG; -import org.bukkit.block.data.BlockData; - import lombok.Data; import lombok.EqualsAndHashCode; @@ -46,6 +46,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator glCave = new GenLayerCave(this, rng.nextParallelRNG(238948)); } + public KList getCaves(int x, int z) + { + return glCave.genCaves(x, z, x & 15, z & 15, null); + } + @Override protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap) { @@ -60,11 +65,13 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator int depth = 0; double noise = getNoiseHeight(rx, rz); int height = (int) Math.round(noise) + fluidHeight; + IrisRegion region = sampleRegion(rx, rz); IrisBiome biome = sampleTrueBiome(rx, rz).getBiome(); KList layers = biome.generateLayers(wx, wz, masterRandom, height, height - getFluidHeight()); KList seaLayers = biome.isSea() ? biome.generateSeaLayers(wx, wz, masterRandom, fluidHeight - height) : new KList<>(); cacheBiome(x, z, biome); + // 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) @@ -76,6 +83,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator } } + // Set Biomes & Blocks from HEIGHT/FLUIDHEIGHT to 0 for(int k = Math.max(height, fluidHeight); k >= 0; k--) { if(k == 0) @@ -105,18 +113,56 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator sliver.set(k, block); + // Decorate underwater if(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) { decorateLand(biome, sliver, wx, k, wz, rx, rz, block); } } - glCave.genCaves(rx, rz, x, z, sliver); + KList caveResults = glCave.genCaves(rx, rz, x, z, sliver); + IrisBiome caveBiome = glBiome.generateData(InferredType.CAVE, wx, wz, rx, rz, region).getBiome(); + + if(caveBiome != null) + { + for(CaveResult i : caveResults) + { + for(int j = i.getFloor(); j <= i.getCeiling(); j++) + { + sliver.set(j, caveBiome); + sliver.set(j, caveBiome.getGroundBiome(masterRandom, rz, j, rx)); + } + + KList floor = caveBiome.generateLayers(wx, wz, rockRandom, i.getFloor() - 2, i.getFloor() - 2); + KList ceiling = caveBiome.generateLayers(wx + 256, wz + 256, rockRandom, height - i.getCeiling() - 2, height - i.getCeiling() - 2); + BlockData blockc = null; + for(int j = 0; j < floor.size(); j++) + { + if(j == 0) + { + blockc = floor.get(j); + } + + sliver.set(i.getFloor() - j, floor.get(j)); + } + + for(int j = ceiling.size() - 1; j > 0; j--) + { + sliver.set(i.getCeiling() + j, ceiling.get(j)); + } + + if(blockc != null && !sliver.isSolid(i.getFloor() + 1)) + { + decorateCave(caveBiome, sliver, wx, i.getFloor(), wz, rx, rz, blockc); + } + } + } } catch(Throwable e) @@ -212,6 +258,72 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator } } + private void decorateCave(IrisBiome biome, AtomicSliver sliver, double wx, int k, double wz, int rx, int rz, BlockData block) + { + if(!getDimension().isDecorate()) + { + return; + } + + int j = 0; + + for(IrisBiomeDecorator i : biome.getDecorators()) + { + BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz); + + if(d != null) + { + if(!canPlace(d.getMaterial(), block.getMaterial())) + { + continue; + } + + if(d.getMaterial().equals(Material.CACTUS)) + { + if(!block.getMaterial().equals(Material.SAND) && !block.getMaterial().equals(Material.RED_SAND)) + { + sliver.set(k, BlockDataTools.getBlockData("SAND")); + } + } + + if(d instanceof Bisected && k < 254) + { + Bisected t = ((Bisected) d.clone()); + t.setHalf(Half.TOP); + Bisected b = ((Bisected) d.clone()); + b.setHalf(Half.BOTTOM); + sliver.set(k + 1, b); + sliver.set(k + 2, t); + } + + else + { + int stack = i.getHeight(getMasterRandom().nextParallelRNG(39456 + i.hashCode()), wx, wz); + + if(stack == 1) + { + sliver.set(k + 1, d); + } + + else if(k < 255 - stack) + { + for(int l = 0; l < stack; l++) + { + if(sliver.isSolid(k + l + 1)) + { + break; + } + + sliver.set(k + l + 1, d); + } + } + } + + break; + } + } + } + private void decorateUnderwater(IrisBiome biome, AtomicSliver sliver, double wx, int y, double wz, int rx, int rz, BlockData block) { if(!getDimension().isDecorate()) @@ -290,39 +402,58 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator double sh = region.getShoreHeight(wx, wz); IrisBiome current = sampleBiome(x, z).getBiome(); - // Stop shores from spawning on land if(current.isShore() && height > sh) { - return glBiome.generateLandData(wx, wz, x, z, region); + return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region); } - // Stop land & shore from spawning underwater if(current.isShore() || current.isLand() && height <= getDimension().getFluidHeight()) { - return glBiome.generateSeaData(wx, wz, x, z, region); + return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region); } - // Stop oceans from spawning on land if(current.isSea() && height > getDimension().getFluidHeight()) { - return glBiome.generateLandData(wx, wz, x, z, region); + return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region); } - // Stop land from spawning underwater if(height <= getDimension().getFluidHeight()) { - return glBiome.generateSeaData(wx, wz, x, z, region); + return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region); } - // Stop land from spawning where shores go if(height <= getDimension().getFluidHeight() + sh) { - return glBiome.generateShoreData(wx, wz, x, z, region); + return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region); } return glBiome.generateRegionData(wx, wz, x, z, region); } + public BiomeResult sampleCaveBiome(int x, int z) + { + double wx = getModifiedX(x, z); + double wz = getModifiedZ(x, z); + return glBiome.generateData(InferredType.CAVE, wx, wz, x, z, sampleRegion(x, z)); + } + + public BiomeResult sampleTrueBiome(int x, int y, int z) + { + if(y < getTerrainHeight(x, z)) + { + double wx = getModifiedX(x, z); + double wz = getModifiedZ(x, z); + BiomeResult r = glBiome.generateData(InferredType.CAVE, wx, wz, x, z, sampleRegion(x, z)); + + if(r.getBiome() != null) + { + return r; + } + } + + return sampleTrueBiome(x, z); + } + public BiomeResult sampleTrueBiome(int x, int z) { if(!getDimension().getFocus().equals("")) @@ -338,10 +469,9 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator BiomeResult res = sampleTrueBiomeBase(x, z); IrisBiome current = res.getBiome(); - // Stop oceans from spawning on the first level of beach if(current.isSea() && height > getDimension().getFluidHeight() - sh) { - return glBiome.generateShoreData(wx, wz, x, z, region); + return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region); } return res; diff --git a/src/main/java/com/volmit/iris/layer/BiomeData.java b/src/main/java/com/volmit/iris/layer/BiomeData.java deleted file mode 100644 index 056a7cc27..000000000 --- a/src/main/java/com/volmit/iris/layer/BiomeData.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.volmit.iris.layer; - -import com.volmit.iris.object.InferredType; - -public class BiomeData -{ - private InferredType type; - private CellGenerator generator; - -} diff --git a/src/main/java/com/volmit/iris/layer/BiomeDataProvider.java b/src/main/java/com/volmit/iris/layer/BiomeDataProvider.java new file mode 100644 index 000000000..ecfabaf74 --- /dev/null +++ b/src/main/java/com/volmit/iris/layer/BiomeDataProvider.java @@ -0,0 +1,37 @@ +package com.volmit.iris.layer; + +import com.volmit.iris.object.InferredType; +import com.volmit.iris.object.IrisRegion; +import com.volmit.iris.util.BiomeResult; +import com.volmit.iris.util.CellGenerator; +import com.volmit.iris.util.RNG; + +import lombok.Data; + +@Data +public class BiomeDataProvider +{ + private InferredType type; + private CellGenerator generator; + private GenLayerBiome layer; + + public BiomeDataProvider(GenLayerBiome layer, InferredType type, RNG rng) + { + this.type = type; + this.layer = layer; + generator = new CellGenerator(rng.nextParallelRNG(4645079 + (type.ordinal() * 23845))); + } + + public BiomeResult generatePureData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) + { + getGenerator().setShuffle(12); + double zoom = (layer.getIris().getDimension().getBiomeZoom() * regionData.getBiomeZoom(getType())) * 3.15; + getGenerator().setCellScale(1D / zoom); + return layer.generateBiomeData(bx, bz, regionData, getGenerator(), regionData.getBiomes(getType()), getType()); + } + + public BiomeResult generateData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) + { + return layer.generateImpureData(rawX, rawZ, getType(), regionData, generatePureData(bx, bz, rawX, rawZ, regionData)); + } +} diff --git a/src/main/java/com/volmit/iris/layer/GenLayerBiome.java b/src/main/java/com/volmit/iris/layer/GenLayerBiome.java index 793411c9c..5317a5a0c 100644 --- a/src/main/java/com/volmit/iris/layer/GenLayerBiome.java +++ b/src/main/java/com/volmit/iris/layer/GenLayerBiome.java @@ -13,34 +13,44 @@ import com.volmit.iris.util.GenLayer; import com.volmit.iris.util.KList; import com.volmit.iris.util.RNG; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) public class GenLayerBiome extends GenLayer { - private CellGenerator region; - private CellGenerator bridge; - private CellGenerator land; - private CellGenerator shore; - private CellGenerator sea; - + private CellGenerator regionGenerator; + private CellGenerator bridgeGenerator; + private BiomeDataProvider seaProvider; + private BiomeDataProvider landProvider; + private BiomeDataProvider shoreProvider; + private BiomeDataProvider caveProvider; + private BiomeDataProvider islandProvider; + private BiomeDataProvider skylandProvider; private DimensionChunkGenerator iris; public GenLayerBiome(DimensionChunkGenerator iris, RNG rng) { super(iris, rng); this.iris = iris; - region = new CellGenerator(rng.nextParallelRNG(1188519)); - bridge = new CellGenerator(rng.nextParallelRNG(1541462)); - land = new CellGenerator(rng.nextParallelRNG(9045162)); - shore = new CellGenerator(rng.nextParallelRNG(2342812)); - sea = new CellGenerator(rng.nextParallelRNG(6135621)); + seaProvider = new BiomeDataProvider(this, InferredType.SEA, rng); + landProvider = new BiomeDataProvider(this, InferredType.LAND, rng); + shoreProvider = new BiomeDataProvider(this, InferredType.SHORE, rng); + caveProvider = new BiomeDataProvider(this, InferredType.CAVE, rng); + islandProvider = new BiomeDataProvider(this, InferredType.ISLAND, rng); + skylandProvider = new BiomeDataProvider(this, InferredType.SKYLAND, rng); + regionGenerator = new CellGenerator(rng.nextParallelRNG(1188519)); + bridgeGenerator = new CellGenerator(rng.nextParallelRNG(1541462)); } public IrisRegion getRegion(double bx, double bz) { - region.setShuffle(8); - region.setCellScale(0.33 / iris.getDimension().getRegionZoom()); + regionGenerator.setShuffle(8); + regionGenerator.setCellScale(0.33 / iris.getDimension().getRegionZoom()); double x = bx / iris.getDimension().getBiomeZoom(); double z = bz / iris.getDimension().getBiomeZoom(); - String regionId = iris.getDimension().getRegions().get(region.getIndex(x, z, iris.getDimension().getRegions().size())); + String regionId = iris.getDimension().getRegions().get(regionGenerator.getIndex(x, z, iris.getDimension().getRegions().size())); return Iris.data.getRegionLoader().load(regionId); } @@ -50,45 +60,80 @@ public class GenLayerBiome extends GenLayer return generateRegionData(bx, bz, rawX, rawZ, getRegion(bx, bz)); } - public boolean isSea(double bx, double bz, IrisRegion regionData) + public BiomeResult generateData(InferredType type, double bx, double bz, int rawX, int rawZ, IrisRegion regionData) { - bridge.setShuffle(0); - bridge.setCellScale(0.33 / iris.getDimension().getContinentZoom()); - double x = bx / iris.getDimension().getBiomeZoom(); - double z = bz / iris.getDimension().getBiomeZoom(); - return bridge.getIndex(x, z, 5) == 1; + return getProvider(type).generateData(bx, bz, rawX, rawZ, regionData); } - public BiomeResult generateRegionData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) + public BiomeDataProvider getProvider(InferredType type) { - if(isSea(bx, bz, regionData)) + if(type.equals(InferredType.SEA)) { - return generateSeaData(bx, bz, rawX, rawZ, regionData); + return seaProvider; + } + + else if(type.equals(InferredType.LAND)) + { + return landProvider; + } + + else if(type.equals(InferredType.SHORE)) + { + return shoreProvider; + } + + else if(type.equals(InferredType.CAVE)) + { + return caveProvider; + } + + else if(type.equals(InferredType.ISLAND)) + { + return islandProvider; + } + + else if(type.equals(InferredType.SKYLAND)) + { + return skylandProvider; } else { - return generateLandData(bx, bz, rawX, rawZ, regionData); + Iris.error("Cannot find a BiomeDataProvider for type " + type.name()); } + + return null; + } + + public BiomeResult generateRegionData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) + { + return generateData(getType(bx, bz, regionData), bx, bz, rawX, rawZ, regionData); + } + + public InferredType getType(double bx, double bz, IrisRegion regionData) + { + bridgeGenerator.setShuffle(0); + bridgeGenerator.setCellScale(0.33 / iris.getDimension().getContinentZoom()); + double x = bx / iris.getDimension().getBiomeZoom(); + double z = bz / iris.getDimension().getBiomeZoom(); + return bridgeGenerator.getIndex(x, z, 5) == 1 ? InferredType.SEA : InferredType.LAND; } public BiomeResult generateBiomeData(double bx, double bz, IrisRegion regionData, CellGenerator cell, KList biomes, InferredType inferredType) { + if(biomes.isEmpty()) + { + return new BiomeResult(null, 0); + } + double x = bx / iris.getDimension().getBiomeZoom(); double z = bz / iris.getDimension().getBiomeZoom(); - IrisBiome biome = Iris.data.getBiomeLoader().load(biomes.get(sea.getIndex(x, z, biomes.size()))); + IrisBiome biome = Iris.data.getBiomeLoader().load(biomes.get(cell.getIndex(x, z, biomes.size()))); biome.setInferredType(inferredType); return implode(bx, bz, regionData, cell, new BiomeResult(biome, cell.getDistance(x, z))); } - public BiomeResult generatePureSeaData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) - { - sea.setShuffle(42); - sea.setCellScale(0.56 / iris.getDimension().getSeaZoom()); - return generateBiomeData(bx, bz, regionData, sea, regionData.getSeaBiomes(), InferredType.SEA); - } - public BiomeResult generateImpureData(int rawX, int rawZ, InferredType type, IrisRegion regionData, BiomeResult pureResult) { for(IrisRegionRidge i : regionData.getRidgeBiomes()) @@ -110,35 +155,6 @@ public class GenLayerBiome extends GenLayer return pureResult; } - public BiomeResult generateSeaData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) - { - return generateImpureData(rawX, rawZ, InferredType.SEA, regionData, generatePureSeaData(bx, bz, rawX, rawZ, regionData)); - } - - public BiomeResult generatePureLandData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) - { - land.setShuffle(12); - land.setCellScale(0.6 / iris.getDimension().getLandZoom()); - return generateBiomeData(bx, bz, regionData, land, regionData.getLandBiomes(), InferredType.LAND); - } - - public BiomeResult generateLandData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) - { - return generateImpureData(rawX, rawZ, InferredType.LAND, regionData, generatePureLandData(bx, bz, rawX, rawZ, regionData)); - } - - public BiomeResult generatePureShoreData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) - { - shore.setShuffle(4); - shore.setCellScale(0.8 / iris.getDimension().getShoreZoom()); - return generateBiomeData(bx, bz, regionData, shore, regionData.getShoreBiomes(), InferredType.SHORE); - } - - public BiomeResult generateShoreData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) - { - return generateImpureData(rawX, rawZ, InferredType.SHORE, regionData, generatePureShoreData(bx, bz, rawX, rawZ, regionData)); - } - public BiomeResult implode(double bx, double bz, IrisRegion regionData, CellGenerator parentCell, BiomeResult parent) { return implode(bx, bz, regionData, parentCell, parent, 1); diff --git a/src/main/java/com/volmit/iris/layer/GenLayerCave.java b/src/main/java/com/volmit/iris/layer/GenLayerCave.java index 70396f7cb..16bbe0d95 100644 --- a/src/main/java/com/volmit/iris/layer/GenLayerCave.java +++ b/src/main/java/com/volmit/iris/layer/GenLayerCave.java @@ -54,15 +54,15 @@ public class GenLayerCave extends GenLayer double wx = wxx + (shuffle.noise(wxx, wzz) * shuffleDistance); double wz = wzz + (shuffle.noise(wzz, wxx) * shuffleDistance); double incline = 157; - double baseWidth = (9 * iris.getDimension().getCaveScale()); + double baseWidth = (14 * iris.getDimension().getCaveScale()); double distanceCheck = 0.0132 * baseWidth; - double distanceTake = 0.0032 * baseWidth; + double distanceTake = 0.0022 * baseWidth; double drop = (-i * 7) + 44 + iris.getDimension().getCaveShift(); double caveHeightNoise = incline * gincline.noise((wx + (10000 * i)), (wz - (10000 * i))); caveHeightNoise += shuffle.fitDoubleD(-1, 1, wxx - caveHeightNoise, wzz + caveHeightNoise) * 3; - int ceiling = 0; - int floor = 256; + int ceiling = -256; + int floor = 512; for(double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) { @@ -72,30 +72,51 @@ public class GenLayerCave extends GenLayer int caveHeight = (int) Math.round(caveHeightNoise - drop); int pu = (int) (caveHeight + tunnelHeight); int pd = (int) (caveHeight - tunnelHeight); - if(dig(x, pu, z, data)) + + if(data == null) { ceiling = pu > ceiling ? pu : ceiling; floor = pu < floor ? pu : floor; - } - - if(dig(x, pd, z, data)) - { ceiling = pd > ceiling ? pd : ceiling; floor = pd < floor ? pd : floor; - } - if(tunnelHeight == 1) - { - if(dig(x, (int) (caveHeight), z, data)) + if(tunnelHeight == 1) { ceiling = caveHeight > ceiling ? caveHeight : ceiling; floor = caveHeight < floor ? caveHeight : floor; } } + + else + { + if(dig(x, pu, z, data)) + { + ceiling = pu > ceiling ? pu : ceiling; + floor = pu < floor ? pu : floor; + } + + if(dig(x, pd, z, data)) + { + ceiling = pd > ceiling ? pd : ceiling; + floor = pd < floor ? pd : floor; + } + + if(tunnelHeight == 1) + { + if(dig(x, (int) (caveHeight), z, data)) + { + ceiling = caveHeight > ceiling ? caveHeight : ceiling; + floor = caveHeight < floor ? caveHeight : floor; + } + } + } } } - result.add(new CaveResult(floor, ceiling)); + if(floor >= 0 && ceiling <= 255) + { + result.add(new CaveResult(floor, ceiling)); + } } return result; diff --git a/src/main/java/com/volmit/iris/object/InferredType.java b/src/main/java/com/volmit/iris/object/InferredType.java index 579bf2452..bb339da6a 100644 --- a/src/main/java/com/volmit/iris/object/InferredType.java +++ b/src/main/java/com/volmit/iris/object/InferredType.java @@ -16,6 +16,12 @@ public enum InferredType @DontObfuscate CAVE, + @DontObfuscate + ISLAND, + + @DontObfuscate + SKYLAND, + @DontObfuscate DEFER; } diff --git a/src/main/java/com/volmit/iris/object/IrisObject.java b/src/main/java/com/volmit/iris/object/IrisObject.java index dfc1b28f9..7bc9a93b8 100644 --- a/src/main/java/com/volmit/iris/object/IrisObject.java +++ b/src/main/java/com/volmit/iris/object/IrisObject.java @@ -135,9 +135,12 @@ public class IrisObject extends IrisRegistrant int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), yf, xf, spinx, spiny, spinz).getBlockY() : yv; KMap heightmap = config.getSnow() > 0 ? new KMap<>() : null; - if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) + if(yv < 0) { - return; + if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) + { + return; + } } for(BlockVector g : blocks.k()) diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index 8f70ee317..4a2558358 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -39,6 +39,30 @@ public class IrisRegion extends IrisRegistrant @Desc("The varience of the shore height") private double shoreHeightZoom = 3.14; + @DontObfuscate + @Desc("How large land biomes are in this region") + private double landBiomeZoom = 1; + + @DontObfuscate + @Desc("How large shore biomes are in this region") + private double shoreBiomeZoom = 1; + + @DontObfuscate + @Desc("How large sea biomes are in this region") + private double seaBiomeZoom = 1; + + @DontObfuscate + @Desc("How large island biomes are in this region") + private double islandBiomeZoom = 1; + + @DontObfuscate + @Desc("How large cave biomes are in this region") + private double caveBiomeZoom = 1; + + @DontObfuscate + @Desc("How large skyland biomes are in this region") + private double skylandBiomeZoom = 1; + @DontObfuscate @Desc("The biome implosion ratio, how much to implode biomes into children (chance)") private double biomeImplosionRatio = 0.4; @@ -55,6 +79,18 @@ public class IrisRegion extends IrisRegistrant @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") private KList shoreBiomes = new KList<>(); + @DontObfuscate + @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") + private KList caveBiomes = new KList<>(); + + @DontObfuscate + @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") + private KList islandBiomes = new KList<>(); + + @DontObfuscate + @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") + private KList skylandBiomes = new KList<>(); + @DontObfuscate @Desc("Ridge biomes create a vein-like network like rivers through this region") private KList ridgeBiomes = new KList<>(); @@ -71,14 +107,39 @@ public class IrisRegion extends IrisRegistrant private transient CNG shoreHeightGenerator; private transient ReentrantLock lock = new ReentrantLock(); + public double getBiomeZoom(InferredType t) + { + switch(t) + { + case CAVE: + return caveBiomeZoom; + case ISLAND: + return islandBiomeZoom; + case LAND: + return landBiomeZoom; + case SEA: + return seaBiomeZoom; + case SHORE: + return shoreBiomeZoom; + case SKYLAND: + return skylandBiomeZoom; + default: + break; + } + + return 1; + } + public KList getRidgeBiomeKeys() { lock.lock(); + if(cacheRidge == null) { cacheRidge = new KList(); ridgeBiomes.forEach((i) -> cacheRidge.add(i.getBiome())); } + lock.unlock(); return cacheRidge; @@ -87,11 +148,13 @@ public class IrisRegion extends IrisRegistrant public KList getSpotBiomeKeys() { lock.lock(); + if(cacheSpot == null) { cacheSpot = new KList(); spotBiomes.forEach((i) -> cacheSpot.add(i.getBiome())); } + lock.unlock(); return cacheSpot; @@ -138,4 +201,39 @@ public class IrisRegion extends IrisRegistrant return b.v(); } + + public KList getBiomes(InferredType type) + { + if(type.equals(InferredType.LAND)) + { + return getLandBiomes(); + } + + else if(type.equals(InferredType.SEA)) + { + return getSeaBiomes(); + } + + else if(type.equals(InferredType.SHORE)) + { + return getShoreBiomes(); + } + + else if(type.equals(InferredType.CAVE)) + { + return getCaveBiomes(); + } + + else if(type.equals(InferredType.ISLAND)) + { + return getIslandBiomes(); + } + + else if(type.equals(InferredType.SKYLAND)) + { + return getSkylandBiomes(); + } + + return new KList<>(); + } } 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 fc2bc8459..27f31dd5a 100644 --- a/src/main/java/com/volmit/iris/object/atomics/AtomicSliver.java +++ b/src/main/java/com/volmit/iris/object/atomics/AtomicSliver.java @@ -10,6 +10,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.generator.ChunkGenerator.ChunkData; +import com.volmit.iris.object.IrisBiome; import com.volmit.iris.util.BlockDataTools; import com.volmit.iris.util.HeightMap; import com.volmit.iris.util.KMap; @@ -21,6 +22,7 @@ public class AtomicSliver { public static final BlockData AIR = BlockDataTools.getBlockData("AIR"); private KMap block; + private KMap truebiome; private KMap biome; private int highestBlock = 0; private int highestBiome = 0; @@ -33,6 +35,7 @@ public class AtomicSliver this.z = z; this.block = new KMap<>(); this.biome = new KMap<>(); + this.truebiome = new KMap<>(); } public Material getType(int h) @@ -78,12 +81,27 @@ public class AtomicSliver return getType(h).isSolid(); } + public Biome getBiome(int h) + { + return biome.containsKey(h) ? biome.get(h) : Biome.THE_VOID; + } + + public IrisBiome getTrueBiome(int h) + { + return truebiome.get(h); + } + public void set(int h, Biome d) { biome.put(h, d); highestBiome = h > highestBiome ? h : highestBiome; } + public void set(int h, IrisBiome d) + { + truebiome.put(h, d); + } + public void write(ChunkData d) { for(int i = 0; i <= highestBlock; i++) diff --git a/src/main/java/com/volmit/iris/util/CellGenerator.java b/src/main/java/com/volmit/iris/util/CellGenerator.java index 2309cd435..ec273d53f 100644 --- a/src/main/java/com/volmit/iris/util/CellGenerator.java +++ b/src/main/java/com/volmit/iris/util/CellGenerator.java @@ -50,11 +50,21 @@ public class CellGenerator public float getValue(double x, double z, int possibilities) { + if(possibilities == 1) + { + return 0; + } + return ((fn.GetCellular((float) ((x * cellScale) + (cng.noise(x, z) * shuffle)), (float) ((z * cellScale) + (cng.noise(z, x) * shuffle))) + 1f) / 2f) * (possibilities - 1); } public int getIndex(double x, double z, int possibilities) { + if(possibilities == 1) + { + return 0; + } + return (int) Math.round(getValue(x, z, possibilities)); } }