diff --git a/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java b/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java index 33b762530..ffe98ef8c 100644 --- a/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java +++ b/src/main/java/com/volmit/iris/gen/TerrainChunkGenerator.java @@ -114,7 +114,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator } KList layers = biome.generateLayers(rx, rz, masterRandom, height, height - getFluidHeight()); - KList seaLayers = biome.isSea() || biome.isShore() ? biome.generateSeaLayers(rx, rz, masterRandom, fluidHeight - height) : new KList<>(); + KList seaLayers = biome.isAquatic() || biome.isShore() ? biome.generateSeaLayers(rx, rz, masterRandom, fluidHeight - height) : new KList<>(); boolean caverning = false; KList cavernHeights = new KList<>(); int lastCavernHeight = -1; @@ -510,34 +510,33 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator double wz = getModifiedZ(x, z); IrisRegion region = sampleRegion(x, z); double sh = region.getShoreHeight(wx, wz); + double shMax = getFluidHeight() + (sh / 2); + double shMin = getFluidHeight() - (sh / 2); IrisBiome current = sampleBiome(x, z); + InferredType aquaticType = current.isAquatic() ? (current.isSea() ? InferredType.SEA : current.isRiver() ? InferredType.RIVER : InferredType.LAKE) : InferredType.SEA; + boolean sea = height <= getFluidHeight(); + boolean shore = height >= shMin && height <= shMax; + boolean land = height > getFluidHeight(); - if(current.isShore() && height > sh) + // Remove rivers, lakes & sea from land + if(current.isAquatic() && land) { - return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region); + current = glBiome.generateData(InferredType.LAND, wx, wz, x, z, region); } - if(current.isShore() || current.isLand() && height <= getDimension().getFluidHeight()) + // Remove land from underwater + if(current.isLand() && sea) { - return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region); + current = glBiome.generateData(aquaticType, wx, wz, x, z, region); } - if(current.isSea() && height > getDimension().getFluidHeight()) + // Add shores to land + if(shore) { - return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region); + current = glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region); } - if(height <= getDimension().getFluidHeight()) - { - return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region); - } - - if(height <= getDimension().getFluidHeight() + sh) - { - return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region); - } - - return glBiome.generateRegionData(wx, wz, x, z, region); + return current; } public IrisBiome sampleCaveBiome(int x, int z) @@ -586,22 +585,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator return focus(); } - return getCache().getBiome(x, z, () -> - { - double wx = getModifiedX(x, z); - double wz = getModifiedZ(x, z); - IrisRegion region = sampleRegion(x, z); - int height = (int) Math.round(noise); - double sh = region.getShoreHeight(wx, wz); - IrisBiome current = sampleTrueBiomeBase(x, z, height); - - if(current.isSea() && height > getDimension().getFluidHeight() - sh) - { - return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region); - } - - return current; - }); + return getCache().getBiome(x, z, () -> sampleTrueBiomeBase(x, z, (int) Math.round(noise))); } @Override diff --git a/src/main/java/com/volmit/iris/gen/atomics/AtomicSliver.java b/src/main/java/com/volmit/iris/gen/atomics/AtomicSliver.java index e1971063a..df6d18590 100644 --- a/src/main/java/com/volmit/iris/gen/atomics/AtomicSliver.java +++ b/src/main/java/com/volmit/iris/gen/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.Iris; import com.volmit.iris.object.IrisBiome; import com.volmit.iris.util.B; import com.volmit.iris.util.HeightMap; @@ -118,6 +119,7 @@ public class AtomicSliver { return; } + setSilently(h, d); modified = true; lock.lock(); @@ -134,6 +136,7 @@ public class AtomicSliver if(d == null) { + Iris.warn("Null set at " + h + " of " + x + " " + z); return; } @@ -361,14 +364,16 @@ public class AtomicSliver return; } lock.lock(); - for(int i = 0; i < 256; i++) + + for(int i : block.keySet()) { - if(block.get(i) != null && !block.get(i).equals(AIR)) + BlockData b = block.get(i); + if(b != null) { - BlockData b = block.get(i); currentData.setBlock(x, i, z, b); } } + lock.unlock(); } diff --git a/src/main/java/com/volmit/iris/gen/layer/GenLayerBiome.java b/src/main/java/com/volmit/iris/gen/layer/GenLayerBiome.java index a037d24fa..d241c0968 100644 --- a/src/main/java/com/volmit/iris/gen/layer/GenLayerBiome.java +++ b/src/main/java/com/volmit/iris/gen/layer/GenLayerBiome.java @@ -22,20 +22,28 @@ public class GenLayerBiome extends GenLayer { private CNG regionGenerator; private CNG bridgeGenerator; + private RNG lakeRandom; + private RNG riverRandom; private BiomeDataProvider seaProvider; private BiomeDataProvider landProvider; private BiomeDataProvider shoreProvider; private BiomeDataProvider caveProvider; + private BiomeDataProvider riverProvider; + private BiomeDataProvider lakeProvider; private DimensionChunkGenerator iris; public GenLayerBiome(DimensionChunkGenerator iris, RNG rng) { super(iris, rng); this.iris = iris; + riverRandom = iris.getMasterRandom().nextParallelRNG(-324778); + lakeRandom = iris.getMasterRandom().nextParallelRNG(-868778); 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); + riverProvider = new BiomeDataProvider(this, InferredType.RIVER, rng); + lakeProvider = new BiomeDataProvider(this, InferredType.LAKE, rng); regionGenerator = iris.getDimension().getRegionStyle().create(rng.nextParallelRNG(1188519)).bake().scale(1D / iris.getDimension().getRegionZoom()); bridgeGenerator = iris.getDimension().getContinentalStyle().create(rng.nextParallelRNG(1541462)).bake().scale(1D / iris.getDimension().getContinentZoom()); } @@ -86,6 +94,16 @@ public class GenLayerBiome extends GenLayer return caveProvider; } + else if(type.equals(InferredType.RIVER)) + { + return riverProvider; + } + + else if(type.equals(InferredType.LAKE)) + { + return lakeProvider; + } + else { Iris.error("Cannot find a BiomeDataProvider for type " + type.name()); @@ -99,12 +117,13 @@ public class GenLayerBiome extends GenLayer return generateData(getType(bx, bz, regionData), bx, bz, rawX, rawZ, regionData); } - public InferredType getType(double bx, double bz, IrisRegion regionData) + public InferredType getType(double bx, double bz, IrisRegion region) { double x = bx; double z = bz; double c = iris.getDimension().getLandChance(); InferredType bridge; + if(c >= 1) { bridge = InferredType.LAND; @@ -117,6 +136,16 @@ public class GenLayerBiome extends GenLayer bridge = bridgeGenerator.fitDouble(0, 1, x, z) < c ? InferredType.LAND : InferredType.SEA; + if(bridge.equals(InferredType.LAND) && region.isLake(lakeRandom, x, z)) + { + bridge = InferredType.LAKE; + } + + if(bridge.equals(InferredType.LAND) && region.isRiver(riverRandom, x, z)) + { + bridge = InferredType.RIVER; + } + return bridge; } diff --git a/src/main/java/com/volmit/iris/gen/post/PostFloatingNibDeleter.java b/src/main/java/com/volmit/iris/gen/post/PostFloatingNibDeleter.java index 68698e4e7..92d389ba0 100644 --- a/src/main/java/com/volmit/iris/gen/post/PostFloatingNibDeleter.java +++ b/src/main/java/com/volmit/iris/gen/post/PostFloatingNibDeleter.java @@ -35,7 +35,7 @@ public class PostFloatingNibDeleter extends IrisPostBlockFilter { return; } - + int ha = highestTerrainBlock(x + 1, z); int hb = highestTerrainBlock(x, z + 1); int hc = highestTerrainBlock(x - 1, z); diff --git a/src/main/java/com/volmit/iris/object/InferredType.java b/src/main/java/com/volmit/iris/object/InferredType.java index 579bf2452..7e6401bd8 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 + RIVER, + + @DontObfuscate + LAKE, + @DontObfuscate DEFER; } diff --git a/src/main/java/com/volmit/iris/object/IrisBiome.java b/src/main/java/com/volmit/iris/object/IrisBiome.java index 1d0e0f61d..0d30afa7a 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiome.java +++ b/src/main/java/com/volmit/iris/object/IrisBiome.java @@ -438,6 +438,29 @@ public class IrisBiome extends IrisRegistrant implements IRare return inferredType.equals(InferredType.SEA); } + public boolean isLake() + { + if(inferredType == null) + { + return false; + } + return inferredType.equals(InferredType.LAKE); + } + + public boolean isRiver() + { + if(inferredType == null) + { + return false; + } + return inferredType.equals(InferredType.RIVER); + } + + public boolean isAquatic() + { + return isSea() || isLake() || isRiver(); + } + public boolean isShore() { if(inferredType == null) diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index 356fb789f..0f87c132c 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -101,6 +101,14 @@ public class IrisDimension extends IrisRegistrant @Desc("The placement style of biomes") private IrisGeneratorStyle caveBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @DontObfuscate + @Desc("The placement style of biomes") + private IrisGeneratorStyle riverBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + + @DontObfuscate + @Desc("The placement style of biomes") + private IrisGeneratorStyle lakeBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); + @DontObfuscate @Desc("The placement style of biomes") private IrisGeneratorStyle islandBiomeStyle = NoiseStyle.CELLULAR_IRIS_DOUBLE.style(); @@ -755,6 +763,10 @@ public class IrisDimension extends IrisRegistrant { case CAVE: return caveBiomeStyle; + case LAKE: + return lakeBiomeStyle; + case RIVER: + return riverBiomeStyle; case LAND: return landBiomeStyle; case SEA: diff --git a/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java b/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java index f375cb736..8fb91dbcf 100644 --- a/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java +++ b/src/main/java/com/volmit/iris/object/IrisGeneratorStyle.java @@ -15,7 +15,6 @@ import lombok.Data; @Data public class IrisGeneratorStyle { - @Required @DontObfuscate @Desc("The chance is 1 in CHANCE per interval") @@ -53,6 +52,12 @@ public class IrisGeneratorStyle this.style = s; } + public IrisGeneratorStyle zoomed(double z) + { + this.zoom = z; + return this; + } + public CNG create(RNG rng) { return cng.aquire(() -> diff --git a/src/main/java/com/volmit/iris/object/IrisObject.java b/src/main/java/com/volmit/iris/object/IrisObject.java index 2f67fb530..e9d271084 100644 --- a/src/main/java/com/volmit/iris/object/IrisObject.java +++ b/src/main/java/com/volmit/iris/object/IrisObject.java @@ -322,7 +322,7 @@ public class IrisObject extends IrisRegistrant return -1; } - if(config.isBore() && !config.getMode().equals(ObjectPlaceMode.PAINT)) + if(config.isBore()) { for(int i = x - Math.floorDiv(w, 2); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0); i++) { @@ -330,10 +330,7 @@ public class IrisObject extends IrisRegistrant { for(int k = z - Math.floorDiv(d, 2); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0); k++) { - if(!B.isAir(placer.get(i, j, k))) - { - placer.set(i, j, k, AIR); - } + placer.set(i, j, k, AIR); } } } diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index 95a41436c..470ef614d 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -46,7 +46,7 @@ public class IrisRegion extends IrisRegistrant implements IRare @Desc("Place text on terrain") @ArrayType(min = 1, type = IrisTextPlacement.class) private KList text = new KList<>(); - + @ArrayType(min = 1, type = IrisBlockDrops.class) @DontObfuscate @Desc("Define custom block drops for this region") @@ -87,6 +87,16 @@ public class IrisRegion extends IrisRegistrant implements IRare @Desc("How large shore biomes are in this region") private double shoreBiomeZoom = 1; + @MinNumber(0.0001) + @DontObfuscate + @Desc("How large lake biomes are in this region") + private double lakeBiomeZoom = 1; + + @MinNumber(0.0001) + @DontObfuscate + @Desc("How large river biomes are in this region") + private double riverBiomeZoom = 1; + @MinNumber(0.0001) @DontObfuscate @Desc("How large sea biomes are in this region") @@ -129,6 +139,18 @@ public class IrisRegion extends IrisRegistrant implements IRare @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<>(); + @RegistryListBiome + @ArrayType(min = 1, type = String.class) + @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 riverBiomes = new KList<>(); + + @RegistryListBiome + @ArrayType(min = 1, type = String.class) + @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 lakeBiomes = new KList<>(); + @RegistryListBiome @ArrayType(min = 1, type = String.class) @DontObfuscate @@ -149,13 +171,99 @@ public class IrisRegion extends IrisRegistrant implements IRare @Desc("Define regional deposit generators that add onto the global deposit generators") private KList deposits = new KList<>(); + @DontObfuscate + @Desc("The style of rivers") + private IrisGeneratorStyle riverStyle = NoiseStyle.VASCULAR_THIN.style().zoomed(7.77); + + @DontObfuscate + @Desc("The style of lakes") + private IrisGeneratorStyle lakeStyle = NoiseStyle.CELLULAR_IRIS_THICK.style(); + + @DontObfuscate + @Desc("The style of river chances") + private IrisGeneratorStyle riverChanceStyle = NoiseStyle.SIMPLEX.style().zoomed(4); + + @DontObfuscate + @Desc("Generate lakes in this region") + private boolean lakes = true; + + @DontObfuscate + @Desc("Generate rivers in this region") + private boolean rivers = true; + + @MinNumber(1) + @DontObfuscate + @Desc("Generate lakes in this region") + private int lakeRarity = 22; + + @MinNumber(1) + @DontObfuscate + @Desc("Generate rivers in this region") + private int riverRarity = 3; + + @MinNumber(0) + @MaxNumber(1) + @DontObfuscate + @Desc("Generate rivers in this region") + private double riverThickness = 0.1; + private transient AtomicCache> cacheRidge = new AtomicCache<>(); private transient AtomicCache> cacheSpot = new AtomicCache<>(); private transient AtomicCache shoreHeightGenerator = new AtomicCache<>(); private transient AtomicCache> realLandBiomes = new AtomicCache<>(); + private transient AtomicCache> realLakeBiomes = new AtomicCache<>(); + private transient AtomicCache> realRiverBiomes = new AtomicCache<>(); private transient AtomicCache> realSeaBiomes = new AtomicCache<>(); private transient AtomicCache> realShoreBiomes = new AtomicCache<>(); private transient AtomicCache> realCaveBiomes = new AtomicCache<>(); + private transient AtomicCache lakeGen = new AtomicCache<>(); + private transient AtomicCache riverGen = new AtomicCache<>(); + private transient AtomicCache riverChanceGen = new AtomicCache<>(); + + public boolean isRiver(RNG rng, double x, double z) + { + if(!isRivers()) + { + return false; + } + + if(getRiverBiomes().isEmpty()) + { + return false; + } + + if(getRiverChanceGen().aquire(() -> getRiverChanceStyle().create(rng)).fit(1, getRiverRarity(), x, z) != 1) + { + return false; + } + + if(getRiverGen().aquire(() -> getRiverStyle().create(rng)).fitDouble(0, 1, x, z) < getRiverThickness()) + { + return true; + } + + return false; + } + + public boolean isLake(RNG rng, double x, double z) + { + if(!isLakes()) + { + return false; + } + + if(getLakeBiomes().isEmpty()) + { + return false; + } + + if(getLakeGen().aquire(() -> getLakeStyle().create(rng)).fit(1, getLakeRarity(), x, z) == 1) + { + return true; + } + + return false; + } public double getBiomeZoom(InferredType t) { @@ -163,6 +271,10 @@ public class IrisRegion extends IrisRegistrant implements IRare { case CAVE: return caveBiomeZoom; + case LAKE: + return lakeBiomeZoom; + case RIVER: + return riverBiomeZoom; case LAND: return landBiomeZoom; case SEA: @@ -263,6 +375,16 @@ public class IrisRegion extends IrisRegistrant implements IRare return getRealCaveBiomes(g); } + else if(type.equals(InferredType.LAKE)) + { + return getRealLakeBiomes(g); + } + + else if(type.equals(InferredType.RIVER)) + { + return getRealRiverBiomes(g); + } + return new KList<>(); } @@ -281,6 +403,36 @@ public class IrisRegion extends IrisRegistrant implements IRare }); } + public KList getRealLakeBiomes(ContextualChunkGenerator g) + { + return realLakeBiomes.aquire(() -> + { + KList realLakeBiomes = new KList<>(); + + for(String i : getLakeBiomes()) + { + realLakeBiomes.add((g == null ? Iris.globaldata : g.getData()).getBiomeLoader().load(i)); + } + + return realLakeBiomes; + }); + } + + public KList getRealRiverBiomes(ContextualChunkGenerator g) + { + return realRiverBiomes.aquire(() -> + { + KList realRiverBiomes = new KList<>(); + + for(String i : getRiverBiomes()) + { + realRiverBiomes.add((g == null ? Iris.globaldata : g.getData()).getBiomeLoader().load(i)); + } + + return realRiverBiomes; + }); + } + public KList getRealShoreBiomes(ContextualChunkGenerator g) { return realShoreBiomes.aquire(() -> diff --git a/src/main/java/com/volmit/iris/object/IrisStructurePlacement.java b/src/main/java/com/volmit/iris/object/IrisStructurePlacement.java index 4003222f6..13ae6704c 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructurePlacement.java +++ b/src/main/java/com/volmit/iris/object/IrisStructurePlacement.java @@ -130,11 +130,6 @@ public class IrisStructurePlacement if(t != null) { - if(height >= 0) - { - t.getPlacement().setBore(true); - } - IrisObject o = null; for(IrisRareObject l : t.getTile().getRareObjects()) diff --git a/src/main/java/com/volmit/iris/object/IrisStructureTile.java b/src/main/java/com/volmit/iris/object/IrisStructureTile.java index 9296b6273..4aa1811e4 100644 --- a/src/main/java/com/volmit/iris/object/IrisStructureTile.java +++ b/src/main/java/com/volmit/iris/object/IrisStructureTile.java @@ -26,7 +26,7 @@ public class IrisStructureTile @DontObfuscate @Desc("The place mode for this tile") - private ObjectPlaceMode placeMode = ObjectPlaceMode.PAINT; + private ObjectPlaceMode placeMode = ObjectPlaceMode.CENTER_HEIGHT; @Required @DontObfuscate