diff --git a/src/main/java/com/volmit/iris/gen/TopographicTerrainProvider.java b/src/main/java/com/volmit/iris/gen/TopographicTerrainProvider.java index a640abb1c..2708fa7ee 100644 --- a/src/main/java/com/volmit/iris/gen/TopographicTerrainProvider.java +++ b/src/main/java/com/volmit/iris/gen/TopographicTerrainProvider.java @@ -419,6 +419,12 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider else { int stack = i.getHeight(rng.nextParallelRNG((int) (39456 + (10000 * i.getChance()) + i.getStackMax() + i.getStackMin() + i.getZoom())), rx, rz, getData()); + FastBlockData top = null; + + if(stack > 1 && i.getTopPalette().hasElements()) + { + top = i.getBlockData(biome, rng.nextParallelRNG(38887 + biome.getRarity() + biome.getName().length() + j++), rx, rz, getData()); + } if(stack == 1) { @@ -429,7 +435,7 @@ public abstract class TopographicTerrainProvider extends ParallelTerrainProvider { for(int l = 0; l < stack; l++) { - sliver.set(k + l + 1, d); + sliver.set(k + l + 1, l == stack - 1 && top != null ? top : d); } } } diff --git a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java index ccc0e509f..450e30927 100644 --- a/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java +++ b/src/main/java/com/volmit/iris/object/IrisBiomeDecorator.java @@ -87,10 +87,16 @@ public class IrisBiomeDecorator @Desc("The palette of blocks to pick from when this decorator needs to place.") private KList palette = new KList().qadd(new IrisBlockData("grass")); + @ArrayType(min = 1, type = IrisBlockData.class) + @DontObfuscate + @Desc("The palette of blocks used at the very top of a 'stackMax' of higher than 1. For example, bamboo tops.") + private KList topPalette = new KList(); + private final transient AtomicCache layerGenerator = new AtomicCache<>(); private final transient AtomicCache varianceGenerator = new AtomicCache<>(); private final transient AtomicCache heightGenerator = new AtomicCache<>(); private final transient AtomicCache> blockData = new AtomicCache<>(); + private final transient AtomicCache> blockDataTops = new AtomicCache<>(); public int getHeight(RNG rng, double x, double z, IrisDataManager data) { @@ -150,6 +156,29 @@ public class IrisBiomeDecorator return null; } + public FastBlockData getBlockDataForTop(IrisBiome b, RNG rng, double x, double z, IrisDataManager data) + { + if(getBlockDataTops(data).isEmpty()) + { + return null; + } + + double xx = x / getZoom(); + double zz = z / getZoom(); + + if(getGenerator(rng, data).fitDouble(0D, 1D, xx, zz) <= chance) + { + if(getBlockData(data).size() == 1) + { + return getBlockDataTops(data).get(0); + } + + return getVarianceGenerator(rng, data).fit(getBlockDataTops(data), xx, zz); + } + + return null; + } + public KList getBlockData(IrisDataManager data) { return blockData.aquire(() -> @@ -167,4 +196,22 @@ public class IrisBiomeDecorator return blockData; }); } + + public KList getBlockDataTops(IrisDataManager data) + { + return blockDataTops.aquire(() -> + { + KList blockDataTops = new KList<>(); + for(IrisBlockData i : topPalette) + { + FastBlockData bx = i.getBlockData(data); + if(bx != null) + { + blockDataTops.add(bx); + } + } + + return blockDataTops; + }); + } }