diff --git a/src/main/java/ninja/bytecode/iris/generator/TerrainChunkGenerator.java b/src/main/java/ninja/bytecode/iris/generator/TerrainChunkGenerator.java index 90f9f8b5d..6bea72950 100644 --- a/src/main/java/ninja/bytecode/iris/generator/TerrainChunkGenerator.java +++ b/src/main/java/ninja/bytecode/iris/generator/TerrainChunkGenerator.java @@ -58,7 +58,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator double noise = getNoiseHeight(rx, rz); int height = (int) Math.round(noise) + fluidHeight; IrisBiome biome = sampleTrueBiome(rx, rz).getBiome(); - KList layers = biome.generateLayers(wx, wz, masterRandom, height); + 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); diff --git a/src/main/java/ninja/bytecode/iris/object/IrisBiome.java b/src/main/java/ninja/bytecode/iris/object/IrisBiome.java index 9d156c3b6..b9a020807 100644 --- a/src/main/java/ninja/bytecode/iris/object/IrisBiome.java +++ b/src/main/java/ninja/bytecode/iris/object/IrisBiome.java @@ -28,6 +28,9 @@ public class IrisBiome extends IrisRegistrant @Desc("This zooms in the biome colors if multiple derivatives are chosen") private double biomeZoom = 1; + @Desc("Layers no longer descend from the surface block, they descend from the max possible height the biome can produce (constant) creating mesa like layers.") + private boolean lockLayers = false; + @Desc("The rarity of this biome (integer)") private int rarity = 1; @@ -68,6 +71,8 @@ public class IrisBiome extends IrisRegistrant private transient CellGenerator childrenCell; private transient InferredType inferredType; private transient CNG biomeGenerator; + private transient int maxHeight = Integer.MIN_VALUE; + private transient KList fullLayerSpec; private transient KList layerHeightGenerators; private transient KList layerSeaHeightGenerators; private transient KList layerSurfaceGenerators; @@ -111,8 +116,13 @@ public class IrisBiome extends IrisRegistrant return childrenCell; } - public KList generateLayers(double wx, double wz, RNG random, int maxDepth) + public KList generateLayers(double wx, double wz, RNG random, int maxDepth, int height) { + if(isLockLayers()) + { + return generateLockedLayers(wx, wz, random, maxDepth, height); + } + KList data = new KList<>(); if(maxDepth <= 0) @@ -157,6 +167,74 @@ public class IrisBiome extends IrisRegistrant return data; } + public KList generateLockedLayers(double wx, double wz, RNG random, int maxDepth, int height) + { + KList data = new KList<>(); + KList real = new KList<>(); + + if(maxDepth <= 0) + { + return data; + } + + for(int i = 0; i < layers.size(); i++) + { + CNG hgen = getLayerHeightGenerators(random).get(i); + int d = hgen.fit(layers.get(i).getMinHeight(), layers.get(i).getMaxHeight(), wx / layers.get(i).getTerrainZoom(), wz / layers.get(i).getTerrainZoom()); + + if(d < 0) + { + continue; + } + + for(int j = 0; j < d; j++) + { + try + { + data.add(getLayers().get(i).get(random.nextParallelRNG(i + j), (wx + j) / layers.get(i).getTerrainZoom(), j, (wz - j) / layers.get(i).getTerrainZoom())); + } + + catch(Throwable e) + { + L.ex(e); + } + } + } + + if(data.isEmpty()) + { + return real; + } + + for(int i = 0; i < maxDepth; i++) + { + int offset = (getMaxHeight() - height) - i; + int index = offset % data.size(); + real.add(data.get(index < 0 ? 0 : index)); + } + + return real; + } + + private int getMaxHeight() + { + if(maxHeight == Integer.MIN_VALUE) + { + lock.lock(); + + maxHeight = 0; + + for(IrisBiomeGeneratorLink i : getGenerators()) + { + maxHeight += i.getMax(); + } + + lock.unlock(); + } + + return maxHeight; + } + public IrisBiome infer(InferredType t, InferredType type) { setInferredType(t.equals(InferredType.DEFER) ? type : t); diff --git a/src/main/java/ninja/bytecode/iris/object/IrisGenerator.java b/src/main/java/ninja/bytecode/iris/object/IrisGenerator.java index 230053448..c01e7c310 100644 --- a/src/main/java/ninja/bytecode/iris/object/IrisGenerator.java +++ b/src/main/java/ninja/bytecode/iris/object/IrisGenerator.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import ninja.bytecode.iris.Iris; import ninja.bytecode.iris.util.Desc; +import ninja.bytecode.iris.util.IrisInterpolation; import ninja.bytecode.shuriken.collections.KList; @Desc("Represents a composite generator of noise gens") @@ -32,14 +33,28 @@ public class IrisGenerator extends IrisRegistrant @Desc("The interpolation distance scale (blocks) when two biomes use different heights but this same generator") private double interpolationScale = 7; + @Desc("Cliff Height Max. Disable with 0 for min and max") + private double cliffHeightMax = 0; + + @Desc("Cliff Height Min. Disable with 0 for min and max") + private double cliffHeightMin = 0; + @Desc("The list of noise gens this gen contains.") private KList composite = new KList(); + @Desc("The noise gen for cliff height.") + private IrisNoiseGenerator cliffHeightGenerator = new IrisNoiseGenerator(); + public double getMax() { return opacity; } + public boolean hasCliffs() + { + return cliffHeightMax > 0; + } + public double getHeight(double rx, double rz, long superSeed) { if(composite.isEmpty()) @@ -65,7 +80,19 @@ public class IrisGenerator extends IrisRegistrant Iris.warn("Nan value on gen: " + getLoadKey() + ": H = " + h + " TP = " + tp + " OPACITY = " + opacity + " ZOOM = " + zoom); } - return v; + return hasCliffs() ? cliff(rx, rz, v, superSeed + 294596) : v; } + public double getCliffHeight(double rx, double rz, double superSeed) + { + int hc = hashCode(); + double h = cliffHeightGenerator.getNoise((long) (seed + superSeed + hc), (rx + offsetX) / zoom, (rz + offsetZ) / zoom); + return IrisInterpolation.lerp(cliffHeightMin, cliffHeightMax, h); + } + + public double cliff(double rx, double rz, double v, double superSeed) + { + double cliffHeight = getCliffHeight(rx, rz, superSeed - 34857); + return (Math.round((v * 255D) / cliffHeight) * cliffHeight) / 255D; + } }