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 241f15f58..ff68bc7db 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 @@ -20,6 +20,21 @@ public interface Engine public EngineFramework getFramework(); + default void save() + { + getParallax().saveAll(); + } + + default void saveNow() + { + getParallax().saveAllNOW(); + } + + default String getName() + { + return getDimension().getName(); + } + public void generate(int x, int z, Hunk blocks, Hunk biomes); public default int getHeight() diff --git a/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineCompound.java b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineCompound.java index 50f6d9e5d..9b8db1c61 100644 --- a/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineCompound.java +++ b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineCompound.java @@ -6,8 +6,9 @@ import com.volmit.iris.v2.scaffold.parallel.MultiBurst; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.event.Listener; -public interface EngineCompound +public interface EngineCompound extends Listener { public void generate(int x, int z, Hunk blocks, Hunk biomes); @@ -22,4 +23,22 @@ public interface EngineCompound public EngineData getEngineMetadata(); public void saveEngineMetadata(); + + public default void save() + { + saveEngineMetadata(); + for(int i = 0; i < getSize(); i++) + { + getEngine(i).save(); + } + } + + public default void saveNOW() + { + saveEngineMetadata(); + for(int i = 0; i < getSize(); i++) + { + getEngine(i).saveNow(); + } + } } diff --git a/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineFramework.java b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineFramework.java index dcd805081..fd118517b 100644 --- a/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineFramework.java +++ b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineFramework.java @@ -1,15 +1,25 @@ package com.volmit.iris.v2.scaffold.engine; +import com.volmit.iris.manager.IrisDataManager; import com.volmit.iris.v2.generator.IrisComplex; import com.volmit.iris.v2.generator.IrisEngine; +import com.volmit.iris.v2.scaffold.data.DataProvider; +import com.volmit.iris.v2.scaffold.parallax.ParallaxAccess; +import com.volmit.iris.v2.scaffold.parallax.ParallaxWorld; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; -public interface EngineFramework +public interface EngineFramework extends DataProvider { public Engine getEngine(); public IrisComplex getComplex(); + + public EngineParallax getEngineParallax(); + + default IrisDataManager getData() { + return getComplex().getData(); + } public EngineActuator getTerrainActuator(); 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 new file mode 100644 index 000000000..bc5049443 --- /dev/null +++ b/src/main/java/com/volmit/iris/v2/scaffold/engine/EngineParallax.java @@ -0,0 +1,301 @@ +package com.volmit.iris.v2.scaffold.engine; + +import com.volmit.iris.Iris; +import com.volmit.iris.gen.ContextualTerrainProvider; +import com.volmit.iris.manager.IrisDataManager; +import com.volmit.iris.object.*; +import com.volmit.iris.util.*; +import com.volmit.iris.v2.generator.IrisComplex; +import com.volmit.iris.v2.generator.IrisEngine; +import com.volmit.iris.v2.scaffold.cache.Cache; +import com.volmit.iris.v2.scaffold.data.DataProvider; +import com.volmit.iris.v2.scaffold.hunk.Hunk; +import com.volmit.iris.v2.scaffold.parallax.ParallaxAccess; +import com.volmit.iris.v2.scaffold.parallel.BurstExecutor; +import com.volmit.iris.v2.scaffold.parallel.MultiBurst; +import org.bukkit.block.data.BlockData; +import org.bukkit.util.BlockVector; + +import java.util.concurrent.atomic.AtomicInteger; + +public interface EngineParallax extends DataProvider, IObjectPlacer +{ + public static final BlockData AIR = B.get("AIR"); + + public Engine getEngine(); + + public int getParallaxSize(); + + default EngineFramework getFramework() + { + return getEngine().getFramework(); + } + + default ParallaxAccess getParallaxAccess() + { + return getEngine().getParallax(); + } + + default IrisDataManager getData() + { + return getEngine().getData(); + } + + default IrisComplex getComplex() + { + return getEngine().getFramework().getComplex(); + } + + default KList getAllRegions() + { + KList r = new KList<>(); + + for(String i : getEngine().getDimension().getRegions()) + { + r.add(getEngine().getData().getRegionLoader().load(i)); + } + + return r; + } + + default KList getAllBiomes() + { + KList r = new KList<>(); + + for(IrisRegion i : getAllRegions()) + { + r.addAll(i.getAllBiomes(this)); + } + + return r; + } + + default void insertParallax(int x, int z, Hunk data) + { + data.compute3D(getEngine().getParallelism(), (xx,yy,zz,h)->{ + for(int i = x+xx; i < x+xx+ h.getWidth(); i++) + { + for(int j= z+zz; j < z+zz + h.getDepth(); j++) + { + for(int k= yy; k < yy+h.getHeight(); k++) + { + BlockData d = getParallaxAccess().getBlock(i, k, j); + + if(d != null) + { + h.set(i - (x-xx), k-yy, j - (z+zz), d); + } + } + } + } + }); + } + + default void generateParallaxArea(int x, int z) + { + int s = (int) Math.ceil(getParallaxSize() / 2D); + for(int i = -s; i <= s; i++) + { + for(int j = -s; j <= s; j++) + { + generateParallaxLayer((i*16)+x, (j*16)+z); + } + } + + getParallaxAccess().setChunkGenerated(x>>4, z>>4); + } + + default void generateParallaxLayer(int x, int z) + { + if(getParallaxAccess().isParallaxGenerated(x >> 4, z >> 4)) + { + return; + } + + getParallaxAccess().setParallaxGenerated(x>>4, z>>4); + RNG rng = new RNG(Cache.key(x, z)).nextParallelRNG(getEngine().getTarget().getWorld().getSeed()); + generateParallaxSurface(rng, x, z); + } + + default void generateParallaxSurface(RNG rng, int x, int z) { + IrisBiome biome = getComplex().getTrueBiomeStream().get(x + 8, z + 8); + + for (IrisObjectPlacement i : biome.getSurfaceObjects()) + { + if(rng.chance(i.getChance())) + { + place(rng, x, z, i); + } + } + } + + default void place(RNG rng, int x, int z, IrisObjectPlacement objectPlacement) + { + for(int i = 0; i < objectPlacement.getDensity(); i++) + { + objectPlacement.getSchematic(getComplex(), rng).place(rng.i(x, x+16), rng.i(z, z+16), this, objectPlacement, rng, getData()); + } + } + + default int computeParallaxSize() + { + Iris.verbose("Calculating the Parallax Size in Parallel"); + AtomicInteger xg = new AtomicInteger(0); + AtomicInteger zg = new AtomicInteger(); + xg.set(0); + zg.set(0); + + KSet objects = new KSet<>(); + KList r = getAllRegions(); + KList b = getAllBiomes(); + + for(IrisBiome i : b) + { + for(IrisObjectPlacement j : i.getObjects()) + { + objects.addAll(j.getPlace()); + } + } + + IrisLock t = new IrisLock("t"); + Iris.verbose("Checking sizes for " + Form.f(objects.size()) + " referenced objects."); + BurstExecutor e = MultiBurst.burst.burst(objects.size()); + for(String i : objects) + { + e.queue(() -> { + try + { + BlockVector bv = IrisObject.sampleSize(getData().getObjectLoader().findFile(i)); + synchronized (xg) + { + xg.getAndSet(Math.max(bv.getBlockX(), xg.get())); + } + + synchronized (zg) + { + zg.getAndSet(Math.max(bv.getBlockZ(), zg.get())); + } + } + + catch(Throwable ignored) + { + + } + }); + } + + e.complete(); + + int x = xg.get(); + int z = zg.get(); + + for(IrisDepositGenerator i : getEngine().getDimension().getDeposits()) + { + int max = i.getMaxDimension(); + x = Math.max(max, x); + z = Math.max(max, z); + } + + for(IrisTextPlacement i : getEngine().getDimension().getText()) + { + int max = i.maxDimension(); + x = Math.max(max, x); + z = Math.max(max, z); + } + + for(IrisRegion v : r) + { + for(IrisDepositGenerator i : v.getDeposits()) + { + int max = i.getMaxDimension(); + x = Math.max(max, x); + z = Math.max(max, z); + } + + for(IrisTextPlacement i : v.getText()) + { + int max = i.maxDimension(); + x = Math.max(max, x); + z = Math.max(max, z); + } + } + + for(IrisBiome v : b) + { + for(IrisDepositGenerator i : v.getDeposits()) + { + int max = i.getMaxDimension(); + x = Math.max(max, x); + z = Math.max(max, z); + } + + for(IrisTextPlacement i : v.getText()) + { + int max = i.maxDimension(); + x = Math.max(max, x); + z = Math.max(max, z); + } + } + + x = (Math.max(x, 16) + 16) >> 4; + z = (Math.max(z, 16) + 16) >> 4; + x = x % 2 == 0 ? x + 1 : x; + z = z % 2 == 0 ? z + 1 : z; + x = Math.max(x, z); + z = x; + Iris.verbose(getEngine().getDimension().getName() + " Parallax Size: " + x + ", " + z); + return x; + } + + @Override + default int getHighest(int x, int z) { + return getHighest(x,z,false); + } + + @Override + default int getHighest(int x, int z, boolean ignoreFluid) { + return (int) Math.round(ignoreFluid ? getComplex().getHeightStream().get(x, z) : getComplex().getHeightFluidStream().get(x, z)); + } + + @Override + default void set(int x, int y, int z, BlockData d) { + getParallaxAccess().setBlock(x,y,z,d); + } + + @Override + default BlockData get(int x, int y, int z) { + BlockData block = getParallaxAccess().getBlock(x,y,z); + + if(block == null) + { + return AIR; + } + + return block; + } + + @Override + default boolean isPreventingDecay() { + return getEngine().getDimension().isPreventLeafDecay(); + } + + @Override + default boolean isSolid(int x, int y, int z) { + return B.isSolid(get(x,y,z)); + } + + @Override + default boolean isUnderwater(int x, int z) { + return getHighest(x, z, true) <= getFluidHeight(); + } + + @Override + default int getFluidHeight() { + return getEngine().getDimension().getFluidHeight(); + } + + @Override + default boolean isDebugSmartBore() { + return getEngine().getDimension().isDebugSmartBore(); + } +}