diff --git a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java index 3c8c9dc21..36b50ee35 100644 --- a/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java +++ b/src/main/java/com/volmit/iris/engine/actuator/IrisTerrainNormalActuator.java @@ -18,9 +18,11 @@ package com.volmit.iris.engine.actuator; +import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.EngineAssignedActuator; import com.volmit.iris.engine.object.biome.IrisBiome; +import com.volmit.iris.engine.object.noise.IrisShapedGeneratorStyle; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.hunk.Hunk; @@ -40,11 +42,14 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator private final boolean carving; @Getter private int lastBedrock = -1; + private IrisShapedGeneratorStyle domain; public IrisTerrainNormalActuator(Engine engine) { super(engine, "Terrain"); rng = new RNG(engine.getWorld().seed()); carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty(); + domain = getDimension().getVerticalDomain(); + domain = domain.isFlat() ? null : domain; } @BlockCoordinates @@ -69,6 +74,75 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator getEngine().getMetrics().getTerrain().put(p.getMilliseconds()); } + public void generateGround(int realX, int realZ, int xf, int zf, Hunk h, int surface, int bottom, int height, int fluidOrHeight, IrisBiome biome) + { + if(surface == bottom || surface-1 == bottom) + { + return; + } + + KList blocks = null; + KList fblocks = null; + int depth,fdepth; + + for (int i = surface; i >= bottom; i--) { + if (i >= h.getHeight()) { + continue; + } + + if (i == 0) { + if (getDimension().isBedrock()) { + h.set(xf, i, zf, BEDROCK); + lastBedrock = i; + continue; + } + } + + if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, height)) { + continue; + } + + if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, height, getData())) { + continue; + } + + if (i > height && i <= fluidOrHeight) { + fdepth = fluidOrHeight - i; + + if (fblocks == null) { + fblocks = biome.generateSeaLayers(realX, realZ, rng, fluidOrHeight - height, getData()); + } + + if (fblocks.hasIndex(fdepth)) { + h.set(xf, i, zf, fblocks.get(fdepth)); + continue; + } + + h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ)); + continue; + } + + if (i <= height) { + depth = surface - i; + if (blocks == null) { + blocks = biome.generateLayers(realX, realZ, rng, surface - bottom, surface, getData(), getComplex()); + } + + if (blocks.hasIndex(depth)) { + h.set(xf, i, zf, blocks.get(depth)); + continue; + } + + h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); + } + } + } + + private int fluidOrHeight(int height) + { + return Math.max(getDimension().getFluidHeight(), height); + } + /** * This is calling 1/16th of a chunk x/z slice. It is a plane from sky to bedrock 1 thick in the x direction. * @@ -79,73 +153,63 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator */ @BlockCoordinates public void terrainSliver(int x, int z, int xf, Hunk h) { - int i, depth, realX, realZ, hf, he, b, fdepth; + int i, j, k, realX, realZ, hf, he; IrisBiome biome; - KList blocks, fblocks; - for (int zf = 0; zf < h.getDepth(); zf++) { + for (i = 0; i < h.getDepth(); i++) { realX = (int) modX(xf + x); - realZ = (int) modZ(zf + z); - he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ))); - hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he)); - biome = getComplex().getTrueBiomeStream().get(realX, realZ); - blocks = null; - fblocks = null; + realZ = (int) modZ(i + z); - if (hf < 0) { - continue; + if(domain != null) + { + int[] heights = new int[h.getHeight()]; + IrisBiome[] biomes = new IrisBiome[h.getHeight()]; + int maximum = 0; + + for(j = 0; j < h.getHeight(); j++) + { + double ox = domain.get(rng, getData(), j - 12345); + double oz = domain.get(rng, getData(), j + 54321); + biomes[j] = getComplex().getTrueBiomeStream().get(realX+ox, realZ+oz); + heights[j] = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX+ox, realZ+oz))); + maximum = Math.max(maximum, heights[j]); + } + + for(j = maximum; j >= 0; j--) { + if(fluidOrHeight(heights[j]) < j) + { + continue; + } + + int hi = j; + int lo = 0; + + for(k = j; k >= 0; k--) + { + if(fluidOrHeight(heights[k]) < k) + { + break; + } + + lo = k; + j = k-1; + } + + generateGround(realX, realZ, xf, i, h, hi, lo, heights[hi], fluidOrHeight(heights[hi]), biomes[hi]); + } } - for (i = hf; i >= 0; i--) { - if (i >= h.getHeight()) { + else + { + biome = getComplex().getTrueBiomeStream().get(realX, realZ); + he = (int) Math.round(Math.min(h.getHeight(), getComplex().getHeightStream().get(realX, realZ))); + hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he)); + + if (hf < 0) { continue; } - if (i == 0) { - if (getDimension().isBedrock()) { - h.set(xf, i, zf, BEDROCK); - lastBedrock = i; - continue; - } - } - - if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, he)) { - continue; - } - - if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, he, getData())) { - continue; - } - - if (i > he && i <= hf) { - fdepth = hf - i; - - if (fblocks == null) { - fblocks = biome.generateSeaLayers(realX, realZ, rng, hf - he, getData()); - } - - if (fblocks.hasIndex(fdepth)) { - h.set(xf, i, zf, fblocks.get(fdepth)); - continue; - } - - h.set(xf, i, zf, getComplex().getFluidStream().get(realX, +realZ)); - continue; - } - - if (i <= he) { - depth = he - i; - if (blocks == null) { - blocks = biome.generateLayers(realX, realZ, rng, he, he, getData(), getComplex()); - } - - if (blocks.hasIndex(depth)) { - h.set(xf, i, zf, blocks.get(depth)); - continue; - } - - h.set(xf, i, zf, getComplex().getRockStream().get(realX, realZ)); - } + generateGround(realX, realZ, xf, i, h, hf, 0, he, hf, biome); } } }