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

@ -115,8 +115,9 @@ public class Iris extends JavaPlugin implements BoardProvider
{ {
IrisChunkGenerator g = (IrisChunkGenerator) world.getGenerator(); IrisChunkGenerator g = (IrisChunkGenerator) world.getGenerator();
int x = player.getLocation().getBlockX(); int x = player.getLocation().getBlockX();
int y = player.getLocation().getBlockY();
int z = player.getLocation().getBlockZ(); int z = player.getLocation().getBlockZ();
BiomeResult er = g.sampleTrueBiome(x, z); BiomeResult er = g.sampleTrueBiome(x, y, z);
IrisBiome b = er != null ? er.getBiome() : null; IrisBiome b = er != null ? er.getBiome() : null;
lines.add("&7&m-----------------"); lines.add("&7&m-----------------");
lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s " + Form.duration(g.getMetrics().getTotal().getAverage(), 1) + ""); lines.add(ChatColor.GREEN + "Speed" + ChatColor.GRAY + ": " + ChatColor.BOLD + "" + ChatColor.GRAY + Form.f(g.getMetrics().getPerSecond().getAverage(), 0) + "/s " + Form.duration(g.getMetrics().getTotal().getAverage(), 1) + "");

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.AtomicWorldData;
import com.volmit.iris.object.atomics.MasterLock; import com.volmit.iris.object.atomics.MasterLock;
import com.volmit.iris.util.BiomeMap; import com.volmit.iris.util.BiomeMap;
import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.ChunkPosition; import com.volmit.iris.util.ChunkPosition;
import com.volmit.iris.util.HeightMap; import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.IObjectPlacer; import com.volmit.iris.util.IObjectPlacer;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap; import com.volmit.iris.util.KMap;
import com.volmit.iris.util.RNG; 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++) 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++) 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++) 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 @Override
protected void onTick(int ticks) protected void onTick(int ticks)
{ {

View File

@ -4,6 +4,7 @@ import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.data.Bisected; import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.Bisected.Half; import org.bukkit.block.data.Bisected.Half;
import org.bukkit.block.data.BlockData;
import com.volmit.iris.layer.GenLayerCave; import com.volmit.iris.layer.GenLayerCave;
import com.volmit.iris.object.DecorationPart; 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.BiomeMap;
import com.volmit.iris.util.BiomeResult; import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.BlockDataTools; import com.volmit.iris.util.BlockDataTools;
import com.volmit.iris.util.CaveResult;
import com.volmit.iris.util.HeightMap; import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.KList; import com.volmit.iris.util.KList;
import com.volmit.iris.util.M; import com.volmit.iris.util.M;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
import org.bukkit.block.data.BlockData;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -46,6 +46,11 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
glCave = new GenLayerCave(this, rng.nextParallelRNG(238948)); 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 @Override
protected void onGenerateColumn(int cx, int cz, int rx, int rz, int x, int z, AtomicSliver sliver, BiomeMap biomeMap) 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; int depth = 0;
double noise = getNoiseHeight(rx, rz); double noise = getNoiseHeight(rx, rz);
int height = (int) Math.round(noise) + fluidHeight; int height = (int) Math.round(noise) + fluidHeight;
IrisRegion region = sampleRegion(rx, rz);
IrisBiome biome = sampleTrueBiome(rx, rz).getBiome(); IrisBiome biome = sampleTrueBiome(rx, rz).getBiome();
KList<BlockData> layers = biome.generateLayers(wx, wz, masterRandom, height, height - getFluidHeight()); 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<>(); KList<BlockData> seaLayers = biome.isSea() ? biome.generateSeaLayers(wx, wz, masterRandom, fluidHeight - height) : new KList<>();
cacheBiome(x, z, biome); 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++) for(int k = Math.max(height, fluidHeight); k < Math.max(height, fluidHeight) + 3; k++)
{ {
if(k < Math.max(height, fluidHeight) + 3) 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--) for(int k = Math.max(height, fluidHeight); k >= 0; k--)
{ {
if(k == 0) if(k == 0)
@ -105,18 +113,56 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
sliver.set(k, block); sliver.set(k, block);
// Decorate underwater
if(k == height && block.getMaterial().isSolid() && k < fluidHeight) if(k == height && block.getMaterial().isSolid() && k < fluidHeight)
{ {
decorateUnderwater(biome, sliver, wx, k, wz, rx, rz, block); decorateUnderwater(biome, sliver, wx, k, wz, rx, rz, block);
} }
// Decorate land
if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k > fluidHeight) if(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k > fluidHeight)
{ {
decorateLand(biome, sliver, wx, k, wz, rx, rz, block); 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) 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) private void decorateUnderwater(IrisBiome biome, AtomicSliver sliver, double wx, int y, double wz, int rx, int rz, BlockData block)
{ {
if(!getDimension().isDecorate()) if(!getDimension().isDecorate())
@ -290,39 +402,58 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
double sh = region.getShoreHeight(wx, wz); double sh = region.getShoreHeight(wx, wz);
IrisBiome current = sampleBiome(x, z).getBiome(); IrisBiome current = sampleBiome(x, z).getBiome();
// Stop shores from spawning on land
if(current.isShore() && height > sh) 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()) 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()) 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()) 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) 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); 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) public BiomeResult sampleTrueBiome(int x, int z)
{ {
if(!getDimension().getFocus().equals("")) if(!getDimension().getFocus().equals(""))
@ -338,10 +469,9 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
BiomeResult res = sampleTrueBiomeBase(x, z); BiomeResult res = sampleTrueBiomeBase(x, z);
IrisBiome current = res.getBiome(); IrisBiome current = res.getBiome();
// Stop oceans from spawning on the first level of beach
if(current.isSea() && height > getDimension().getFluidHeight() - sh) 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; return res;

View File

@ -1,10 +0,0 @@
package com.volmit.iris.layer;
import com.volmit.iris.object.InferredType;
public class BiomeData
{
private InferredType type;
private CellGenerator generator;
}

View File

@ -0,0 +1,37 @@
package com.volmit.iris.layer;
import com.volmit.iris.object.InferredType;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.util.BiomeResult;
import com.volmit.iris.util.CellGenerator;
import com.volmit.iris.util.RNG;
import lombok.Data;
@Data
public class BiomeDataProvider
{
private InferredType type;
private CellGenerator generator;
private GenLayerBiome layer;
public BiomeDataProvider(GenLayerBiome layer, InferredType type, RNG rng)
{
this.type = type;
this.layer = layer;
generator = new CellGenerator(rng.nextParallelRNG(4645079 + (type.ordinal() * 23845)));
}
public BiomeResult generatePureData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
getGenerator().setShuffle(12);
double zoom = (layer.getIris().getDimension().getBiomeZoom() * regionData.getBiomeZoom(getType())) * 3.15;
getGenerator().setCellScale(1D / zoom);
return layer.generateBiomeData(bx, bz, regionData, getGenerator(), regionData.getBiomes(getType()), getType());
}
public BiomeResult generateData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
return layer.generateImpureData(rawX, rawZ, getType(), regionData, generatePureData(bx, bz, rawX, rawZ, regionData));
}
}

View File

@ -13,34 +13,44 @@ import com.volmit.iris.util.GenLayer;
import com.volmit.iris.util.KList; import com.volmit.iris.util.KList;
import com.volmit.iris.util.RNG; import com.volmit.iris.util.RNG;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = false)
public class GenLayerBiome extends GenLayer public class GenLayerBiome extends GenLayer
{ {
private CellGenerator region; private CellGenerator regionGenerator;
private CellGenerator bridge; private CellGenerator bridgeGenerator;
private CellGenerator land; private BiomeDataProvider seaProvider;
private CellGenerator shore; private BiomeDataProvider landProvider;
private CellGenerator sea; private BiomeDataProvider shoreProvider;
private BiomeDataProvider caveProvider;
private BiomeDataProvider islandProvider;
private BiomeDataProvider skylandProvider;
private DimensionChunkGenerator iris; private DimensionChunkGenerator iris;
public GenLayerBiome(DimensionChunkGenerator iris, RNG rng) public GenLayerBiome(DimensionChunkGenerator iris, RNG rng)
{ {
super(iris, rng); super(iris, rng);
this.iris = iris; this.iris = iris;
region = new CellGenerator(rng.nextParallelRNG(1188519)); seaProvider = new BiomeDataProvider(this, InferredType.SEA, rng);
bridge = new CellGenerator(rng.nextParallelRNG(1541462)); landProvider = new BiomeDataProvider(this, InferredType.LAND, rng);
land = new CellGenerator(rng.nextParallelRNG(9045162)); shoreProvider = new BiomeDataProvider(this, InferredType.SHORE, rng);
shore = new CellGenerator(rng.nextParallelRNG(2342812)); caveProvider = new BiomeDataProvider(this, InferredType.CAVE, rng);
sea = new CellGenerator(rng.nextParallelRNG(6135621)); islandProvider = new BiomeDataProvider(this, InferredType.ISLAND, rng);
skylandProvider = new BiomeDataProvider(this, InferredType.SKYLAND, rng);
regionGenerator = new CellGenerator(rng.nextParallelRNG(1188519));
bridgeGenerator = new CellGenerator(rng.nextParallelRNG(1541462));
} }
public IrisRegion getRegion(double bx, double bz) public IrisRegion getRegion(double bx, double bz)
{ {
region.setShuffle(8); regionGenerator.setShuffle(8);
region.setCellScale(0.33 / iris.getDimension().getRegionZoom()); regionGenerator.setCellScale(0.33 / iris.getDimension().getRegionZoom());
double x = bx / iris.getDimension().getBiomeZoom(); double x = bx / iris.getDimension().getBiomeZoom();
double z = bz / iris.getDimension().getBiomeZoom(); double z = bz / iris.getDimension().getBiomeZoom();
String regionId = iris.getDimension().getRegions().get(region.getIndex(x, z, iris.getDimension().getRegions().size())); String regionId = iris.getDimension().getRegions().get(regionGenerator.getIndex(x, z, iris.getDimension().getRegions().size()));
return Iris.data.getRegionLoader().load(regionId); return Iris.data.getRegionLoader().load(regionId);
} }
@ -50,45 +60,80 @@ public class GenLayerBiome extends GenLayer
return generateRegionData(bx, bz, rawX, rawZ, getRegion(bx, bz)); return generateRegionData(bx, bz, rawX, rawZ, getRegion(bx, bz));
} }
public boolean isSea(double bx, double bz, IrisRegion regionData) public BiomeResult generateData(InferredType type, double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{ {
bridge.setShuffle(0); return getProvider(type).generateData(bx, bz, rawX, rawZ, regionData);
bridge.setCellScale(0.33 / iris.getDimension().getContinentZoom());
double x = bx / iris.getDimension().getBiomeZoom();
double z = bz / iris.getDimension().getBiomeZoom();
return bridge.getIndex(x, z, 5) == 1;
} }
public BiomeResult generateRegionData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData) public BiomeDataProvider getProvider(InferredType type)
{ {
if(isSea(bx, bz, regionData)) if(type.equals(InferredType.SEA))
{ {
return generateSeaData(bx, bz, rawX, rawZ, regionData); return seaProvider;
}
else if(type.equals(InferredType.LAND))
{
return landProvider;
}
else if(type.equals(InferredType.SHORE))
{
return shoreProvider;
}
else if(type.equals(InferredType.CAVE))
{
return caveProvider;
}
else if(type.equals(InferredType.ISLAND))
{
return islandProvider;
}
else if(type.equals(InferredType.SKYLAND))
{
return skylandProvider;
} }
else else
{ {
return generateLandData(bx, bz, rawX, rawZ, regionData); Iris.error("Cannot find a BiomeDataProvider for type " + type.name());
} }
return null;
}
public BiomeResult generateRegionData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
return generateData(getType(bx, bz, regionData), bx, bz, rawX, rawZ, regionData);
}
public InferredType getType(double bx, double bz, IrisRegion regionData)
{
bridgeGenerator.setShuffle(0);
bridgeGenerator.setCellScale(0.33 / iris.getDimension().getContinentZoom());
double x = bx / iris.getDimension().getBiomeZoom();
double z = bz / iris.getDimension().getBiomeZoom();
return bridgeGenerator.getIndex(x, z, 5) == 1 ? InferredType.SEA : InferredType.LAND;
} }
public BiomeResult generateBiomeData(double bx, double bz, IrisRegion regionData, CellGenerator cell, KList<String> biomes, InferredType inferredType) public BiomeResult generateBiomeData(double bx, double bz, IrisRegion regionData, CellGenerator cell, KList<String> biomes, InferredType inferredType)
{ {
if(biomes.isEmpty())
{
return new BiomeResult(null, 0);
}
double x = bx / iris.getDimension().getBiomeZoom(); double x = bx / iris.getDimension().getBiomeZoom();
double z = bz / iris.getDimension().getBiomeZoom(); double z = bz / iris.getDimension().getBiomeZoom();
IrisBiome biome = Iris.data.getBiomeLoader().load(biomes.get(sea.getIndex(x, z, biomes.size()))); IrisBiome biome = Iris.data.getBiomeLoader().load(biomes.get(cell.getIndex(x, z, biomes.size())));
biome.setInferredType(inferredType); biome.setInferredType(inferredType);
return implode(bx, bz, regionData, cell, new BiomeResult(biome, cell.getDistance(x, z))); return implode(bx, bz, regionData, cell, new BiomeResult(biome, cell.getDistance(x, z)));
} }
public BiomeResult generatePureSeaData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
sea.setShuffle(42);
sea.setCellScale(0.56 / iris.getDimension().getSeaZoom());
return generateBiomeData(bx, bz, regionData, sea, regionData.getSeaBiomes(), InferredType.SEA);
}
public BiomeResult generateImpureData(int rawX, int rawZ, InferredType type, IrisRegion regionData, BiomeResult pureResult) public BiomeResult generateImpureData(int rawX, int rawZ, InferredType type, IrisRegion regionData, BiomeResult pureResult)
{ {
for(IrisRegionRidge i : regionData.getRidgeBiomes()) for(IrisRegionRidge i : regionData.getRidgeBiomes())
@ -110,35 +155,6 @@ public class GenLayerBiome extends GenLayer
return pureResult; return pureResult;
} }
public BiomeResult generateSeaData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
return generateImpureData(rawX, rawZ, InferredType.SEA, regionData, generatePureSeaData(bx, bz, rawX, rawZ, regionData));
}
public BiomeResult generatePureLandData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
land.setShuffle(12);
land.setCellScale(0.6 / iris.getDimension().getLandZoom());
return generateBiomeData(bx, bz, regionData, land, regionData.getLandBiomes(), InferredType.LAND);
}
public BiomeResult generateLandData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
return generateImpureData(rawX, rawZ, InferredType.LAND, regionData, generatePureLandData(bx, bz, rawX, rawZ, regionData));
}
public BiomeResult generatePureShoreData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
shore.setShuffle(4);
shore.setCellScale(0.8 / iris.getDimension().getShoreZoom());
return generateBiomeData(bx, bz, regionData, shore, regionData.getShoreBiomes(), InferredType.SHORE);
}
public BiomeResult generateShoreData(double bx, double bz, int rawX, int rawZ, IrisRegion regionData)
{
return generateImpureData(rawX, rawZ, InferredType.SHORE, regionData, generatePureShoreData(bx, bz, rawX, rawZ, regionData));
}
public BiomeResult implode(double bx, double bz, IrisRegion regionData, CellGenerator parentCell, BiomeResult parent) public BiomeResult implode(double bx, double bz, IrisRegion regionData, CellGenerator parentCell, BiomeResult parent)
{ {
return implode(bx, bz, regionData, parentCell, parent, 1); return implode(bx, bz, regionData, parentCell, parent, 1);

View File

@ -54,15 +54,15 @@ public class GenLayerCave extends GenLayer
double wx = wxx + (shuffle.noise(wxx, wzz) * shuffleDistance); double wx = wxx + (shuffle.noise(wxx, wzz) * shuffleDistance);
double wz = wzz + (shuffle.noise(wzz, wxx) * shuffleDistance); double wz = wzz + (shuffle.noise(wzz, wxx) * shuffleDistance);
double incline = 157; double incline = 157;
double baseWidth = (9 * iris.getDimension().getCaveScale()); double baseWidth = (14 * iris.getDimension().getCaveScale());
double distanceCheck = 0.0132 * baseWidth; double distanceCheck = 0.0132 * baseWidth;
double distanceTake = 0.0032 * baseWidth; double distanceTake = 0.0022 * baseWidth;
double drop = (-i * 7) + 44 + iris.getDimension().getCaveShift(); double drop = (-i * 7) + 44 + iris.getDimension().getCaveShift();
double caveHeightNoise = incline * gincline.noise((wx + (10000 * i)), (wz - (10000 * i))); double caveHeightNoise = incline * gincline.noise((wx + (10000 * i)), (wz - (10000 * i)));
caveHeightNoise += shuffle.fitDoubleD(-1, 1, wxx - caveHeightNoise, wzz + caveHeightNoise) * 3; caveHeightNoise += shuffle.fitDoubleD(-1, 1, wxx - caveHeightNoise, wzz + caveHeightNoise) * 3;
int ceiling = 0; int ceiling = -256;
int floor = 256; int floor = 512;
for(double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) for(double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++)
{ {
@ -72,30 +72,51 @@ public class GenLayerCave extends GenLayer
int caveHeight = (int) Math.round(caveHeightNoise - drop); int caveHeight = (int) Math.round(caveHeightNoise - drop);
int pu = (int) (caveHeight + tunnelHeight); int pu = (int) (caveHeight + tunnelHeight);
int pd = (int) (caveHeight - tunnelHeight); int pd = (int) (caveHeight - tunnelHeight);
if(dig(x, pu, z, data))
if(data == null)
{ {
ceiling = pu > ceiling ? pu : ceiling; ceiling = pu > ceiling ? pu : ceiling;
floor = pu < floor ? pu : floor; floor = pu < floor ? pu : floor;
}
if(dig(x, pd, z, data))
{
ceiling = pd > ceiling ? pd : ceiling; ceiling = pd > ceiling ? pd : ceiling;
floor = pd < floor ? pd : floor; floor = pd < floor ? pd : floor;
}
if(tunnelHeight == 1) if(tunnelHeight == 1)
{
if(dig(x, (int) (caveHeight), z, data))
{ {
ceiling = caveHeight > ceiling ? caveHeight : ceiling; ceiling = caveHeight > ceiling ? caveHeight : ceiling;
floor = caveHeight < floor ? caveHeight : floor; floor = caveHeight < floor ? caveHeight : floor;
} }
} }
else
{
if(dig(x, pu, z, data))
{
ceiling = pu > ceiling ? pu : ceiling;
floor = pu < floor ? pu : floor;
}
if(dig(x, pd, z, data))
{
ceiling = pd > ceiling ? pd : ceiling;
floor = pd < floor ? pd : floor;
}
if(tunnelHeight == 1)
{
if(dig(x, (int) (caveHeight), z, data))
{
ceiling = caveHeight > ceiling ? caveHeight : ceiling;
floor = caveHeight < floor ? caveHeight : floor;
}
}
}
} }
} }
result.add(new CaveResult(floor, ceiling)); if(floor >= 0 && ceiling <= 255)
{
result.add(new CaveResult(floor, ceiling));
}
} }
return result; return result;

View File

@ -16,6 +16,12 @@ public enum InferredType
@DontObfuscate @DontObfuscate
CAVE, CAVE,
@DontObfuscate
ISLAND,
@DontObfuscate
SKYLAND,
@DontObfuscate @DontObfuscate
DEFER; DEFER;
} }

View File

@ -135,9 +135,12 @@ public class IrisObject extends IrisRegistrant
int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), yf, xf, spinx, spiny, spinz).getBlockY() : yv; int y = yv < 0 ? placer.getHighest(x, z, config.isUnderwater()) + config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), yf, xf, spinx, spiny, spinz).getBlockY() : yv;
KMap<ChunkPosition, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null; KMap<ChunkPosition, Integer> heightmap = config.getSnow() > 0 ? new KMap<>() : null;
if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) if(yv < 0)
{ {
return; if(!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z))
{
return;
}
} }
for(BlockVector g : blocks.k()) for(BlockVector g : blocks.k())

View File

@ -39,6 +39,30 @@ public class IrisRegion extends IrisRegistrant
@Desc("The varience of the shore height") @Desc("The varience of the shore height")
private double shoreHeightZoom = 3.14; private double shoreHeightZoom = 3.14;
@DontObfuscate
@Desc("How large land biomes are in this region")
private double landBiomeZoom = 1;
@DontObfuscate
@Desc("How large shore biomes are in this region")
private double shoreBiomeZoom = 1;
@DontObfuscate
@Desc("How large sea biomes are in this region")
private double seaBiomeZoom = 1;
@DontObfuscate
@Desc("How large island biomes are in this region")
private double islandBiomeZoom = 1;
@DontObfuscate
@Desc("How large cave biomes are in this region")
private double caveBiomeZoom = 1;
@DontObfuscate
@Desc("How large skyland biomes are in this region")
private double skylandBiomeZoom = 1;
@DontObfuscate @DontObfuscate
@Desc("The biome implosion ratio, how much to implode biomes into children (chance)") @Desc("The biome implosion ratio, how much to implode biomes into children (chance)")
private double biomeImplosionRatio = 0.4; private double biomeImplosionRatio = 0.4;
@ -55,6 +79,18 @@ public class IrisRegion extends IrisRegistrant
@Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.") @Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.")
private KList<String> shoreBiomes = new KList<>(); private KList<String> shoreBiomes = new KList<>();
@DontObfuscate
@Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.")
private KList<String> caveBiomes = new KList<>();
@DontObfuscate
@Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.")
private KList<String> islandBiomes = new KList<>();
@DontObfuscate
@Desc("A list of root-level biomes in this region. Don't specify child biomes of other biomes here. Just the root parents.")
private KList<String> skylandBiomes = new KList<>();
@DontObfuscate @DontObfuscate
@Desc("Ridge biomes create a vein-like network like rivers through this region") @Desc("Ridge biomes create a vein-like network like rivers through this region")
private KList<IrisRegionRidge> ridgeBiomes = new KList<>(); private KList<IrisRegionRidge> ridgeBiomes = new KList<>();
@ -71,14 +107,39 @@ public class IrisRegion extends IrisRegistrant
private transient CNG shoreHeightGenerator; private transient CNG shoreHeightGenerator;
private transient ReentrantLock lock = new ReentrantLock(); private transient ReentrantLock lock = new ReentrantLock();
public double getBiomeZoom(InferredType t)
{
switch(t)
{
case CAVE:
return caveBiomeZoom;
case ISLAND:
return islandBiomeZoom;
case LAND:
return landBiomeZoom;
case SEA:
return seaBiomeZoom;
case SHORE:
return shoreBiomeZoom;
case SKYLAND:
return skylandBiomeZoom;
default:
break;
}
return 1;
}
public KList<String> getRidgeBiomeKeys() public KList<String> getRidgeBiomeKeys()
{ {
lock.lock(); lock.lock();
if(cacheRidge == null) if(cacheRidge == null)
{ {
cacheRidge = new KList<String>(); cacheRidge = new KList<String>();
ridgeBiomes.forEach((i) -> cacheRidge.add(i.getBiome())); ridgeBiomes.forEach((i) -> cacheRidge.add(i.getBiome()));
} }
lock.unlock(); lock.unlock();
return cacheRidge; return cacheRidge;
@ -87,11 +148,13 @@ public class IrisRegion extends IrisRegistrant
public KList<String> getSpotBiomeKeys() public KList<String> getSpotBiomeKeys()
{ {
lock.lock(); lock.lock();
if(cacheSpot == null) if(cacheSpot == null)
{ {
cacheSpot = new KList<String>(); cacheSpot = new KList<String>();
spotBiomes.forEach((i) -> cacheSpot.add(i.getBiome())); spotBiomes.forEach((i) -> cacheSpot.add(i.getBiome()));
} }
lock.unlock(); lock.unlock();
return cacheSpot; return cacheSpot;
@ -138,4 +201,39 @@ public class IrisRegion extends IrisRegistrant
return b.v(); return b.v();
} }
public KList<String> getBiomes(InferredType type)
{
if(type.equals(InferredType.LAND))
{
return getLandBiomes();
}
else if(type.equals(InferredType.SEA))
{
return getSeaBiomes();
}
else if(type.equals(InferredType.SHORE))
{
return getShoreBiomes();
}
else if(type.equals(InferredType.CAVE))
{
return getCaveBiomes();
}
else if(type.equals(InferredType.ISLAND))
{
return getIslandBiomes();
}
else if(type.equals(InferredType.SKYLAND))
{
return getSkylandBiomes();
}
return new KList<>();
}
} }

View File

@ -10,6 +10,7 @@ import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.generator.ChunkGenerator.ChunkData; import org.bukkit.generator.ChunkGenerator.ChunkData;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.util.BlockDataTools; import com.volmit.iris.util.BlockDataTools;
import com.volmit.iris.util.HeightMap; import com.volmit.iris.util.HeightMap;
import com.volmit.iris.util.KMap; import com.volmit.iris.util.KMap;
@ -21,6 +22,7 @@ public class AtomicSliver
{ {
public static final BlockData AIR = BlockDataTools.getBlockData("AIR"); public static final BlockData AIR = BlockDataTools.getBlockData("AIR");
private KMap<Integer, BlockData> block; private KMap<Integer, BlockData> block;
private KMap<Integer, IrisBiome> truebiome;
private KMap<Integer, Biome> biome; private KMap<Integer, Biome> biome;
private int highestBlock = 0; private int highestBlock = 0;
private int highestBiome = 0; private int highestBiome = 0;
@ -33,6 +35,7 @@ public class AtomicSliver
this.z = z; this.z = z;
this.block = new KMap<>(); this.block = new KMap<>();
this.biome = new KMap<>(); this.biome = new KMap<>();
this.truebiome = new KMap<>();
} }
public Material getType(int h) public Material getType(int h)
@ -78,12 +81,27 @@ public class AtomicSliver
return getType(h).isSolid(); return getType(h).isSolid();
} }
public Biome getBiome(int h)
{
return biome.containsKey(h) ? biome.get(h) : Biome.THE_VOID;
}
public IrisBiome getTrueBiome(int h)
{
return truebiome.get(h);
}
public void set(int h, Biome d) public void set(int h, Biome d)
{ {
biome.put(h, d); biome.put(h, d);
highestBiome = h > highestBiome ? h : highestBiome; highestBiome = h > highestBiome ? h : highestBiome;
} }
public void set(int h, IrisBiome d)
{
truebiome.put(h, d);
}
public void write(ChunkData d) public void write(ChunkData d)
{ {
for(int i = 0; i <= highestBlock; i++) for(int i = 0; i <= highestBlock; i++)

View File

@ -50,11 +50,21 @@ public class CellGenerator
public float getValue(double x, double z, int possibilities) public float getValue(double x, double z, int possibilities)
{ {
if(possibilities == 1)
{
return 0;
}
return ((fn.GetCellular((float) ((x * cellScale) + (cng.noise(x, z) * shuffle)), (float) ((z * cellScale) + (cng.noise(z, x) * shuffle))) + 1f) / 2f) * (possibilities - 1); return ((fn.GetCellular((float) ((x * cellScale) + (cng.noise(x, z) * shuffle)), (float) ((z * cellScale) + (cng.noise(z, x) * shuffle))) + 1f) / 2f) * (possibilities - 1);
} }
public int getIndex(double x, double z, int possibilities) public int getIndex(double x, double z, int possibilities)
{ {
if(possibilities == 1)
{
return 0;
}
return (int) Math.round(getValue(x, z, possibilities)); return (int) Math.round(getValue(x, z, possibilities));
} }
} }