diff --git a/src/main/java/com/volmit/iris/v2/generator/IrisEngine.java b/src/main/java/com/volmit/iris/v2/generator/IrisEngine.java index 7e167d267..cdb9e34e0 100644 --- a/src/main/java/com/volmit/iris/v2/generator/IrisEngine.java +++ b/src/main/java/com/volmit/iris/v2/generator/IrisEngine.java @@ -69,29 +69,15 @@ public class IrisEngine extends BlockPopulator implements Engine Hunk biomes = vbiomes.synchronize(); Hunk blocks = vblocks.synchronize().listen((xx,y,zz,t) -> catchBlockUpdates(x+xx,y+getMinHeight(),z+zz, t)); - // Block 1 (does the following in parallel) - // - Initialize Parallax Plane - // - Generate Terrain & Carving - // - Fill baseline biomes MultiBurst.burst.burst( - () -> getFramework().getEngineParallax().generateParallaxArea(x, z), + () -> getFramework().getEngineParallax().generateParallaxArea(x, z), () -> getFramework().getBiomeActuator().actuate(x, z, biomes), - () -> getFramework().getTerrainActuator().actuate(x, z, blocks) + () -> getFramework().getTerrainActuator().actuate(x, z, blocks) ); - - // Block 2 (does the following in parallel AFTER BLOCK 1) - // - Generate caves (modifying existing terrain) - // - Generate ravines (modifying existing terrain) MultiBurst.burst.burst( () -> getFramework().getCaveModifier().modify(x, z, blocks), () -> getFramework().getRavineModifier().modify(x, z, blocks) ); - - // Block 3 (does the following in parallel AFTER BLOCK 2) - // - Decorate surfaces,shores,caves,ravines,carvings & sea surfaces - // - Add ores & other deposits - // - Post block modifications (remove holes / decorate walls etc) - // - Insert cross section of parallax (objects) into chunk MultiBurst.burst.burst( () -> getFramework().getDecorantActuator().actuate(x, z, blocks), () -> getFramework().getDepositModifier().modify(x, z, blocks), @@ -99,7 +85,6 @@ public class IrisEngine extends BlockPopulator implements Engine () -> getFramework().getEngineParallax().insertParallax(x, z, blocks) ); - // Clean up any unused objects / parallax regions (async) getFramework().recycle(); } diff --git a/src/main/java/com/volmit/iris/v2/scaffold/engine/Engine.java b/src/main/java/com/volmit/iris/v2/scaffold/engine/Engine.java index 821bb99a3..5878fce51 100644 --- a/src/main/java/com/volmit/iris/v2/scaffold/engine/Engine.java +++ b/src/main/java/com/volmit/iris/v2/scaffold/engine/Engine.java @@ -1,5 +1,6 @@ package com.volmit.iris.v2.scaffold.engine; +import com.volmit.iris.v2.scaffold.data.DataProvider; import org.bukkit.Chunk; import org.bukkit.World; import org.bukkit.block.Biome; @@ -11,7 +12,7 @@ import com.volmit.iris.object.IrisDimension; import com.volmit.iris.v2.scaffold.hunk.Hunk; import com.volmit.iris.v2.scaffold.parallax.ParallaxAccess; -public interface Engine +public interface Engine extends DataProvider { public void setParallelism(int parallelism); diff --git a/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineParallax.java b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineParallax.java index 05a582585..de533a700 100644 --- a/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineParallax.java +++ b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineParallax.java @@ -4,6 +4,7 @@ import java.lang.reflect.Parameter; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import com.volmit.iris.gen.ParallaxTerrainProvider; import com.volmit.iris.object.*; import com.volmit.iris.util.*; import com.volmit.iris.v2.generator.actuator.IrisTerrainActuator; @@ -134,6 +135,132 @@ public interface EngineParallax extends DataProvider, IObjectPlacer IrisBiome biome = getComplex().getTrueBiomeStream().get(x+8, z+8); generateParallaxSurface(rng, x, z, biome); generateParallaxMutations(rng, x, z); + generateStructures(rng, x>>4, z>>4, region, biome); + } + + default void generateStructures(RNG rng, int x, int z, IrisRegion region, IrisBiome biome) + { + int g = 30265; + for(IrisStructurePlacement k : region.getStructures()) + { + if(k == null) + { + continue; + } + + placeStructure(k, rng.nextParallelRNG(2228 * 2 * g++), x, z); + } + + for(IrisStructurePlacement k : biome.getStructures()) + { + if(k == null) + { + continue; + } + + placeStructure(k, rng.nextParallelRNG(-22228 * 4 * g++), x, z); + } + } + + default void placeStructure(IrisStructurePlacement structure, RNG rngno, int cx, int cz) + { + RNG rng = new RNG(getEngine().getWorld().getSeed()).nextParallelRNG(-88738456 + rngno.nextInt()); + RNG rnp = rng.nextParallelRNG(cx - (cz * cz << 3) + rngno.nextInt()); + int s = structure.gridSize(getEngine()) - (structure.getStructure(getEngine()).isMergeEdges() ? 1 : 0); + int sh = structure.gridHeight(getEngine()) - (structure.getStructure(getEngine()).isMergeEdges() ? 1 : 0); + KSet m = new KSet<>(); + + for(int i = cx << 4; i <= (cx << 4) + 15; i += 1) + { + if(Math.floorDiv(i, s) * s >> 4 < cx) + { + continue; + } + + for(int j = cz << 4; j <= (cz << 4) + 15; j += 1) + { + if(Math.floorDiv(j, s) * s >> 4 < cz) + { + continue; + } + + ChunkPosition p = new ChunkPosition(Math.floorDiv(i, s) * s, Math.floorDiv(j, s) * s); + + if(m.contains(p)) + { + continue; + } + + m.add(p); + + if(structure.getStructure(getEngine()).getMaxLayers() <= 1) + { + placeLayer(structure, rng, rnp, i, 0, j, s, sh); + continue; + } + + for(int k = 0; k < s * structure.getStructure(getEngine()).getMaxLayers(); k += Math.max(sh, 1)) + { + placeLayer(structure, rng, rnp, i, k, j, s, sh); + } + } + } + } + + default void placeLayer(IrisStructurePlacement structure, RNG rng, RNG rnp, int i, int k, int j, int s, int sh) + { + if(!hasStructure(structure, rng, i, k, j)) + { + return; + } + + int h = (structure.getHeight() == -1 ? 0 : structure.getHeight()) + (Math.floorDiv(k, sh) * sh); + TileResult t = structure.getStructure(getEngine()).getTile(rng, Math.floorDiv(i, s) * s, h, Math.floorDiv(j, s) * s); + + if(t != null) + { + IrisObject o = null; + + for(IrisRareObject l : t.getTile().getRareObjects()) + { + if(rnp.i(1, l.getRarity()) == 1) + { + o = structure.load(getEngine(), l.getObject()); + break; + } + } + + o = o != null ? o : structure.load(getEngine(), t.getTile().getObjects().get(rnp.nextInt(t.getTile().getObjects().size()))); + int id = rng.i(0, Integer.MAX_VALUE); + IrisObject oo = o; + o.place( + Math.floorDiv(i, s) * s, + structure.getHeight() == -1 ? -1 : h, + Math.floorDiv(j, s) * s, + this, + t.getPlacement(), + rng, + (b) -> { + getParallaxAccess().setObject(b.getX(), b.getY(), b.getZ(), oo.getLoadKey() + "@" + id); + ParallaxChunkMeta meta = getParallaxAccess().getMetaRW(b.getX() >> 4, b.getZ() >> 4); + meta.setObjects(true); + meta.setMaxObject(Math.max(b.getY(), meta.getMaxObject())); + meta.setMinObject(Math.min(b.getY(), Math.max(meta.getMinObject(), 0))); + }, + null, + getData() + ); + } + } + + default boolean hasStructure(IrisStructurePlacement structure, RNG random, double x, double y, double z) + { + if(structure.getChanceGenerator(new RNG(getEngine().getWorld().getSeed())).getIndex(x / structure.getZoom(), y / structure.getZoom(), z / structure.getZoom(), structure.getRarity()) == structure.getRarity() / 2) + { + return structure.getRatio() > 0 ? structure.getChanceGenerator(new RNG(getEngine().getWorld().getSeed())).getDistance(x / structure.getZoom(), z / structure.getZoom()) > structure.getRatio() : structure.getChanceGenerator(new RNG(getEngine().getWorld().getSeed())).getDistance(x / structure.getZoom(), z / structure.getZoom()) < Math.abs(structure.getRatio()); + } + + return false; } default void generateParallaxSurface(RNG rng, int x, int z, IrisBiome biome) {