Cave Biomes

This commit is contained in:
Daniel Mills
2020-07-28 03:13:33 -04:00
parent 45dd039c53
commit bccb4e154d
12 changed files with 479 additions and 106 deletions

View File

@@ -16,9 +16,11 @@ import com.volmit.iris.object.atomics.AtomicSliverMap;
import com.volmit.iris.object.atomics.AtomicWorldData;
import com.volmit.iris.object.atomics.MasterLock;
import com.volmit.iris.util.BiomeMap;
import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.ChunkPosition;
import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.IObjectPlacer;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.RNG;
@@ -242,7 +244,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate((x * 16) + ro.nextInt(16), (z * 16) + ro.nextInt(16), ro, this);
k.generate((i * 16) + ro.nextInt(16), (j * 16) + ro.nextInt(16), ro, this);
}
}
@@ -250,7 +252,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate((x * 16) + ro.nextInt(16), (z * 16) + ro.nextInt(16), ro, this);
k.generate((i * 16) + ro.nextInt(16), (j * 16) + ro.nextInt(16), ro, this);
}
}
@@ -258,7 +260,30 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
{
for(int l = 0; l < ro.i(k.getMinPerChunk(), k.getMaxPerChunk()); l++)
{
k.generate((x * 16) + ro.nextInt(16), (z * 16) + ro.nextInt(16), ro, this);
k.generate((i * 16) + ro.nextInt(16), (j * 16) + ro.nextInt(16), ro, this);
}
}
if(getDimension().isCaves())
{
int bx = (i * 16) + ro.nextInt(16);
int bz = (j * 16) + ro.nextInt(16);
IrisBiome biome = sampleCaveBiome(bx, bz).getBiome();
if(biome == null)
{
return;
}
if(biome.getObjects().isEmpty())
{
return;
}
for(IrisObjectPlacement k : biome.getObjects())
{
placeCaveObject(k, i, j, random.nextParallelRNG((34 * ((i * 30) + (j * 30) + g++) * i * j) + i - j + 1869322));
}
}
});
@@ -279,6 +304,24 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
}
}
public void placeCaveObject(IrisObjectPlacement o, int x, int z, RNG rng)
{
for(int i = 0; i < o.getTriesForChunk(rng); i++)
{
rng = rng.nextParallelRNG((i * 3 + 8) - 23040);
int xx = (x * 16) + rng.nextInt(16);
int zz = (z * 16) + rng.nextInt(16);
KList<CaveResult> res = getCaves(xx, zz);
if(res.isEmpty())
{
continue;
}
o.getSchematic(rng).place(xx, res.get(rng.nextParallelRNG(29345 * (i + 234)).nextInt(res.size())).getFloor() + 2, zz, this, o, rng);
}
}
@Override
protected void onTick(int ticks)
{

View File

@@ -4,6 +4,7 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.Bisected.Half;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.layer.GenLayerCave;
import com.volmit.iris.object.DecorationPart;
@@ -15,13 +16,12 @@ import com.volmit.iris.object.atomics.AtomicSliver;
import com.volmit.iris.util.BiomeMap;
import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.BlockDataTools;
import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.M;
import com.volmit.iris.util.RNG;
import org.bukkit.block.data.BlockData;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -46,6 +46,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
glCave = new GenLayerCave(this, rng.nextParallelRNG(238948));
}
public KList<CaveResult> getCaves(int x, int z)
{
return glCave.genCaves(x, z, x & 15, z & 15, null);
}
@Override
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap)
{
@@ -60,11 +65,13 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
int depth = 0;
double noise = getNoiseHeight(rx, rz);
int height = (int) Math.round(noise) + fluidHeight;
IrisRegion region = sampleRegion(rx, rz);
IrisBiome biome = sampleTrueBiome(rx, rz).getBiome();
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height, height - getFluidHeight());
KList<BlockData> seaLayers = biome.isSea() ? biome.generateSeaLayers(wx, wz, masterRandom, fluidHeight - height) : new KList<>();
cacheBiome(x, z, biome);
// Set ground biome (color) to HEIGHT - HEIGHT+3
for(int k = Math.max(height, fluidHeight); k < Math.max(height, fluidHeight) + 3; k++)
{
if(k < Math.max(height, fluidHeight) + 3)
@@ -76,6 +83,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
}
}
// Set Biomes & Blocks from HEIGHT/FLUIDHEIGHT to 0
for(int k = Math.max(height, fluidHeight); k >= 0; k--)
{
if(k == 0)
@@ -105,18 +113,56 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
sliver.set(k, block);
// Decorate underwater
if(k == height && block.getMaterial().isSolid() && k < fluidHeight)
{
decorateUnderwater(biome, sliver, wx, k, wz, rx, rz, block);
}
// Decorate land
if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k > fluidHeight)
{
decorateLand(biome, sliver, wx, k, wz, rx, rz, block);
}
}
glCave.genCaves(rx, rz, x, z, sliver);
KList<CaveResult> caveResults = glCave.genCaves(rx, rz, x, z, sliver);
IrisBiome caveBiome = glBiome.generateData(InferredType.CAVE, wx, wz, rx, rz, region).getBiome();
if(caveBiome != null)
{
for(CaveResult i : caveResults)
{
for(int j = i.getFloor(); j <= i.getCeiling(); j++)
{
sliver.set(j, caveBiome);
sliver.set(j, caveBiome.getGroundBiome(masterRandom, rz, j, rx));
}
KList<BlockData> floor = caveBiome.generateLayers(wx, wz, rockRandom, i.getFloor() - 2, i.getFloor() - 2);
KList<BlockData> ceiling = caveBiome.generateLayers(wx + 256, wz + 256, rockRandom, height - i.getCeiling() - 2, height - i.getCeiling() - 2);
BlockData blockc = null;
for(int j = 0; j < floor.size(); j++)
{
if(j == 0)
{
blockc = floor.get(j);
}
sliver.set(i.getFloor() - j, floor.get(j));
}
for(int j = ceiling.size() - 1; j > 0; j--)
{
sliver.set(i.getCeiling() + j, ceiling.get(j));
}
if(blockc != null && !sliver.isSolid(i.getFloor() + 1))
{
decorateCave(caveBiome, sliver, wx, i.getFloor(), wz, rx, rz, blockc);
}
}
}
}
catch(Throwable e)
@@ -212,6 +258,72 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
}
}
private void decorateCave(IrisBiome biome, AtomicSliver sliver, double wx, int k, double wz, int rx, int rz, BlockData block)
{
if(!getDimension().isDecorate())
{
return;
}
int j = 0;
for(IrisBiomeDecorator i : biome.getDecorators())
{
BlockData d = i.getBlockData(getMasterRandom().nextParallelRNG(biome.hashCode() + j++), wx, wz);
if(d != null)
{
if(!canPlace(d.getMaterial(), block.getMaterial()))
{
continue;
}
if(d.getMaterial().equals(Material.CACTUS))
{
if(!block.getMaterial().equals(Material.SAND) && !block.getMaterial().equals(Material.RED_SAND))
{
sliver.set(k, BlockDataTools.getBlockData("SAND"));
}
}
if(d instanceof Bisected && k < 254)
{
Bisected t = ((Bisected) d.clone());
t.setHalf(Half.TOP);
Bisected b = ((Bisected) d.clone());
b.setHalf(Half.BOTTOM);
sliver.set(k + 1, b);
sliver.set(k + 2, t);
}
else
{
int stack = i.getHeight(getMasterRandom().nextParallelRNG(39456 + i.hashCode()), wx, wz);
if(stack == 1)
{
sliver.set(k + 1, d);
}
else if(k < 255 - stack)
{
for(int l = 0; l < stack; l++)
{
if(sliver.isSolid(k + l + 1))
{
break;
}
sliver.set(k + l + 1, d);
}
}
}
break;
}
}
}
private void decorateUnderwater(IrisBiome biome, AtomicSliver sliver, double wx, int y, double wz, int rx, int rz, BlockData block)
{
if(!getDimension().isDecorate())
@@ -290,39 +402,58 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
double sh = region.getShoreHeight(wx, wz);
IrisBiome current = sampleBiome(x, z).getBiome();
// Stop shores from spawning on land
if(current.isShore() && height > sh)
{
return glBiome.generateLandData(wx, wz, x, z, region);
return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region);
}
// Stop land & shore from spawning underwater
if(current.isShore() || current.isLand() && height <= getDimension().getFluidHeight())
{
return glBiome.generateSeaData(wx, wz, x, z, region);
return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region);
}
// Stop oceans from spawning on land
if(current.isSea() && height > getDimension().getFluidHeight())
{
return glBiome.generateLandData(wx, wz, x, z, region);
return glBiome.generateData(InferredType.LAND, wx, wz, x, z, region);
}
// Stop land from spawning underwater
if(height <= getDimension().getFluidHeight())
{
return glBiome.generateSeaData(wx, wz, x, z, region);
return glBiome.generateData(InferredType.SEA, wx, wz, x, z, region);
}
// Stop land from spawning where shores go
if(height <= getDimension().getFluidHeight() + sh)
{
return glBiome.generateShoreData(wx, wz, x, z, region);
return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region);
}
return glBiome.generateRegionData(wx, wz, x, z, region);
}
public BiomeResult sampleCaveBiome(int x, int z)
{
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
return glBiome.generateData(InferredType.CAVE, wx, wz, x, z, sampleRegion(x, z));
}
public BiomeResult sampleTrueBiome(int x, int y, int z)
{
if(y < getTerrainHeight(x, z))
{
double wx = getModifiedX(x, z);
double wz = getModifiedZ(x, z);
BiomeResult r = glBiome.generateData(InferredType.CAVE, wx, wz, x, z, sampleRegion(x, z));
if(r.getBiome() != null)
{
return r;
}
}
return sampleTrueBiome(x, z);
}
public BiomeResult sampleTrueBiome(int x, int z)
{
if(!getDimension().getFocus().equals(""))
@@ -338,10 +469,9 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
BiomeResult res = sampleTrueBiomeBase(x, z);
IrisBiome current = res.getBiome();
// Stop oceans from spawning on the first level of beach
if(current.isSea() && height > getDimension().getFluidHeight() - sh)
{
return glBiome.generateShoreData(wx, wz, x, z, region);
return glBiome.generateData(InferredType.SHORE, wx, wz, x, z, region);
}
return res;