mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-29 20:19:06 +00:00
Supercarves
This commit is contained in:
@@ -100,19 +100,7 @@ public abstract class ParallaxChunkGenerator extends TerrainChunkGenerator imple
|
||||
@Override
|
||||
public int getHighest(int x, int z, boolean ignoreFluid)
|
||||
{
|
||||
int h = (int) Math.round(ignoreFluid ? getTerrainHeight(x, z) : getTerrainWaterHeight(x, z));
|
||||
|
||||
if(getDimension().isCarving() && h >= getDimension().getCarvingMin())
|
||||
{
|
||||
while(getGlCarve().isCarved(x, h, z))
|
||||
{
|
||||
h--;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
return h;
|
||||
return getCarvedHeight(x, z, ignoreFluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -184,13 +184,13 @@ public abstract class PostBlockChunkGenerator extends ParallaxChunkGenerator imp
|
||||
@Override
|
||||
public int highestTerrainOrFluidBlock(int x, int z)
|
||||
{
|
||||
return getHighest(x, z, false);
|
||||
return (int) getTerrainWaterHeight(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int highestTerrainBlock(int x, int z)
|
||||
{
|
||||
return getHighest(x, z, true);
|
||||
return (int) getTerrainHeight(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -76,6 +76,36 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
glCarve = new GenLayerCarve(this, rng.nextParallelRNG(968346576));
|
||||
}
|
||||
|
||||
public int getCarvedHeight(int x, int z, boolean ignoreFluid)
|
||||
{
|
||||
if(ignoreFluid)
|
||||
{
|
||||
return getCache().getCarvedHeightIgnoreWater(x, z, () ->
|
||||
{
|
||||
int h = (int) Math.round(getTerrainHeight(x, z));
|
||||
h = getGlCarve().getSurfaceCarve(x, h, z);
|
||||
return h;
|
||||
});
|
||||
}
|
||||
|
||||
return getCache().getCarvedHeightIgnoreWater(x, z, () ->
|
||||
{
|
||||
int h = (int) Math.round(getTerrainWaterHeight(x, z));
|
||||
h = getGlCarve().getSurfaceCarve(x, h, z);
|
||||
return h;
|
||||
});
|
||||
}
|
||||
|
||||
public int getCarvedHeight(int x, int z)
|
||||
{
|
||||
return getCarvedHeight(x, z, false);
|
||||
}
|
||||
|
||||
public int getCarvedWaterHeight(int x, int z)
|
||||
{
|
||||
return getCarvedHeight(x, z, true);
|
||||
}
|
||||
|
||||
public KList<CaveResult> getCaves(int x, int z)
|
||||
{
|
||||
return glCave.genCaves(x, z, x & 15, z & 15, null);
|
||||
@@ -104,9 +134,10 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
int depth = 0;
|
||||
double noise = getTerrainHeight(rx, rz);
|
||||
int height = (int) Math.round(noise);
|
||||
boolean carvable = getDimension().isCarving() && height > getDimension().getCarvingMin();
|
||||
boolean carvable = getGlCarve().couldCarveBelow(rx, height, rz);
|
||||
IrisRegion region = sampleRegion(rx, rz);
|
||||
IrisBiome biome = sampleTrueBiome(rx, rz, noise);
|
||||
IrisBiome landBiome = null;
|
||||
|
||||
if(biome == null)
|
||||
{
|
||||
@@ -114,6 +145,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
}
|
||||
|
||||
KList<BlockData> layers = biome.generateLayers(rx, rz, masterRandom, height, height - getFluidHeight());
|
||||
KList<BlockData> cavernLayers = null;
|
||||
KList<BlockData> seaLayers = biome.isAquatic() || biome.isShore() ? biome.generateSeaLayers(rx, rz, masterRandom, fluidHeight - height) : new KList<>();
|
||||
boolean caverning = false;
|
||||
KList<Integer> cavernHeights = new KList<>();
|
||||
@@ -146,7 +178,12 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
{
|
||||
if(biomeMap != null)
|
||||
{
|
||||
sliver.set(k, biome.getDerivative());
|
||||
if(landBiome == null)
|
||||
{
|
||||
landBiome = glBiome.generateData(InferredType.LAND, x, z, x, z, region);
|
||||
}
|
||||
|
||||
sliver.set(k, landBiome.getDerivative());
|
||||
}
|
||||
|
||||
sliver.set(k, CAVE_AIR);
|
||||
@@ -189,9 +226,19 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
}
|
||||
|
||||
// Set Surface Material for cavern layer surfaces
|
||||
else if(layers.hasIndex(lastCavernHeight - k))
|
||||
else if(carvable && cavernHeights.isNotEmpty() && lastCavernHeight - k >= 0 && lastCavernHeight - k < 5)
|
||||
{
|
||||
block = layers.get(lastCavernHeight - k);
|
||||
if(landBiome == null)
|
||||
{
|
||||
landBiome = glBiome.generateData(InferredType.LAND, x, z, x, z, region);
|
||||
}
|
||||
|
||||
if(cavernLayers == null)
|
||||
{
|
||||
cavernLayers = landBiome.generateLayers(rx, rz, masterRandom, 5, height - getFluidHeight());
|
||||
}
|
||||
|
||||
block = cavernLayers.get(lastCavernHeight - k);
|
||||
}
|
||||
|
||||
// Set Surface Material for true surface
|
||||
@@ -213,7 +260,12 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
// Decorate Cavern surfaces, but not the true surface
|
||||
if((carvable && cavernSurface) && !(k == Math.max(height, fluidHeight) && block.getMaterial().isSolid() && k < 255 && k >= fluidHeight))
|
||||
{
|
||||
decorateLand(biome, sliver, wx, k, wz, rx, rz, block);
|
||||
if(landBiome == null)
|
||||
{
|
||||
landBiome = glBiome.generateData(InferredType.LAND, z, x, x, z, region);
|
||||
}
|
||||
|
||||
decorateLand(landBiome, sliver, wx, k, wz, rx, rz, block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +285,7 @@ public abstract class TerrainChunkGenerator extends ParallelChunkGenerator
|
||||
}
|
||||
|
||||
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);
|
||||
KList<BlockData> ceiling = caveBiome.generateLayers(wx + 256, wz + 256, rockRandom, (carvable ? getCarvedWaterHeight(rx, rz) : height) - i.getCeiling() - 2, (carvable ? getCarvedWaterHeight(rx, rz) : height) - i.getCeiling() - 2);
|
||||
BlockData blockc = null;
|
||||
for(int j = 0; j < floor.size(); j++)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@ public class AtomicMulticache
|
||||
private int hit = 0;
|
||||
private int miss = 0;
|
||||
private final KMap<Long, Double> height;
|
||||
private final KMap<Long, Integer> carvedHeight;
|
||||
private final KMap<Long, Integer> carvedHeightIgnoreWater;
|
||||
private final KMap<Long, IrisBiome> biome;
|
||||
private final KMap<Long, IrisBiome> rawBiome;
|
||||
private final KMap<Long, IrisRegion> region;
|
||||
@@ -25,6 +27,8 @@ public class AtomicMulticache
|
||||
x = new AtomicInteger(0);
|
||||
z = new AtomicInteger(0);
|
||||
height = new KMap<Long, Double>();
|
||||
carvedHeight = new KMap<Long, Integer>();
|
||||
carvedHeightIgnoreWater = new KMap<Long, Integer>();
|
||||
biome = new KMap<Long, IrisBiome>();
|
||||
rawBiome = new KMap<Long, IrisBiome>();
|
||||
region = new KMap<Long, IrisRegion>();
|
||||
@@ -52,6 +56,16 @@ public class AtomicMulticache
|
||||
height.clear();
|
||||
}
|
||||
|
||||
if(carvedHeight.size() > getLimit())
|
||||
{
|
||||
carvedHeight.clear();
|
||||
}
|
||||
|
||||
if(carvedHeightIgnoreWater.size() > getLimit())
|
||||
{
|
||||
carvedHeightIgnoreWater.clear();
|
||||
}
|
||||
|
||||
if(biome.size() > getLimit())
|
||||
{
|
||||
biome.clear();
|
||||
@@ -99,6 +113,56 @@ public class AtomicMulticache
|
||||
return r;
|
||||
}
|
||||
|
||||
public int getCarvedHeight(int x, int z, Supplier<Integer> g)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return -57841;
|
||||
}
|
||||
|
||||
long pos = pos(x, z);
|
||||
Integer r = carvedHeight.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
carvedHeight.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public int getCarvedHeightIgnoreWater(int x, int z, Supplier<Integer> g)
|
||||
{
|
||||
if(broken)
|
||||
{
|
||||
return -57841;
|
||||
}
|
||||
|
||||
long pos = pos(x, z);
|
||||
Integer r = carvedHeightIgnoreWater.get(pos);
|
||||
|
||||
if(r == null)
|
||||
{
|
||||
miss++;
|
||||
r = g.get();
|
||||
carvedHeightIgnoreWater.put(pos, r);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
hit++;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public IrisRegion getRegion(int x, int z, Supplier<IrisRegion> g)
|
||||
{
|
||||
long pos = pos(x, z);
|
||||
|
||||
@@ -370,6 +370,11 @@ public class AtomicSliver
|
||||
BlockData b = block.get(i);
|
||||
if(b != null)
|
||||
{
|
||||
if(b.getMaterial().equals(Material.AIR))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
currentData.setBlock(x, i, z, b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,79 @@
|
||||
package com.volmit.iris.gen.layer;
|
||||
|
||||
import com.volmit.iris.gen.DimensionChunkGenerator;
|
||||
import com.volmit.iris.noise.CellGenerator;
|
||||
import com.volmit.iris.object.IrisCarveLayer;
|
||||
import com.volmit.iris.util.GenLayer;
|
||||
import com.volmit.iris.util.IrisInterpolation;
|
||||
import com.volmit.iris.util.M;
|
||||
import com.volmit.iris.util.RNG;
|
||||
|
||||
public class GenLayerCarve extends GenLayer
|
||||
{
|
||||
private CellGenerator cell;
|
||||
private boolean couldCarve;
|
||||
private int minimum;
|
||||
private int maximum;
|
||||
|
||||
public GenLayerCarve(DimensionChunkGenerator iris, RNG rng)
|
||||
{
|
||||
super(iris, rng);
|
||||
cell = new CellGenerator(rng.nextParallelRNG(-135486678));
|
||||
|
||||
couldCarve = iris.getDimension().isCarving() && iris.getDimension().getCarveLayers().isNotEmpty();
|
||||
minimum = 512;
|
||||
maximum = -256;
|
||||
|
||||
for(IrisCarveLayer i : iris.getDimension().getCarveLayers())
|
||||
{
|
||||
minimum = i.getMinHeight() < minimum ? i.getMinHeight() : minimum;
|
||||
maximum = i.getMaxHeight() > maximum ? i.getMaxHeight() : maximum;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean couldCarve(int x, int y, int z)
|
||||
{
|
||||
return couldCarve && y >= minimum && y <= maximum;
|
||||
}
|
||||
|
||||
public boolean couldCarveBelow(int x, int y, int z)
|
||||
{
|
||||
return couldCarve && y <= maximum;
|
||||
}
|
||||
|
||||
public int getSurfaceCarve(int x, int y, int z)
|
||||
{
|
||||
if(couldCarveBelow(x, y, z))
|
||||
{
|
||||
int h = y;
|
||||
|
||||
while(isCarved(x, h, z))
|
||||
{
|
||||
if(h <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
h--;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
public boolean isCarved(int xc, int y, int zc)
|
||||
{
|
||||
if(y > iris.getDimension().getCarvingMax() || y < iris.getDimension().getCarvingMin())
|
||||
if(!couldCarve(xc, y, zc))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
double x = ((double) xc / iris.getDimension().getCarvingZoom());
|
||||
double z = ((double) zc / iris.getDimension().getCarvingZoom());
|
||||
double x = ((double) xc);
|
||||
double z = ((double) zc);
|
||||
|
||||
double opacity = Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(iris.getDimension().getCarvingMin(), iris.getDimension().getCarvingMax(), y)), 4);
|
||||
|
||||
if(cell.getDistance(x - (Math.cos(y / iris.getDimension().getCarvingRippleThickness()) + 0.5D) / 2D, y / iris.getDimension().getCarvingSliverThickness(), z + (Math.sin(y / iris.getDimension().getCarvingRippleThickness()) + 0.5D) / 2D) < opacity * iris.getDimension().getCarvingEnvelope())
|
||||
for(IrisCarveLayer i : iris.getDimension().getCarveLayers())
|
||||
{
|
||||
return true;
|
||||
if(i.isCarved(rng, x, y, z))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -59,13 +59,10 @@ public class PostSlabber extends IrisPostBlockFilter
|
||||
return;
|
||||
}
|
||||
|
||||
if(isAirOrWater(x, h + 2, z, currentPostX, currentPostZ, currentData))
|
||||
if(isAirOrWater(x, h + 1, z, currentPostX, currentPostZ, currentData))
|
||||
{
|
||||
queue(() ->
|
||||
{
|
||||
setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData);
|
||||
updateHeight(x, z, h + 1);
|
||||
});
|
||||
setPostBlock(x, h + 1, z, d, currentPostX, currentPostZ, currentData);
|
||||
updateHeight(x, z, h + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,17 +45,8 @@ public class PostWallPatcher extends IrisPostBlockFilter
|
||||
|
||||
if(ha < h - 2 || hb < h - 2 || hc < h - 2 || hd < h - 2)
|
||||
{
|
||||
boolean brokeGround = false;
|
||||
int max = Math.abs(Math.max(h - ha, Math.max(h - hb, Math.max(h - hc, h - hd))));
|
||||
BlockData s = gen.sampleTrueBiome(x, z).getSlab().get(rng, x, h, z);
|
||||
|
||||
if(s != null)
|
||||
{
|
||||
if(!s.getMaterial().equals(AIR))
|
||||
{
|
||||
setPostBlock(x, h + 1, z, s, currentPostX, currentPostZ, currentData);
|
||||
updateHeight(x, z, h + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = h; i > h - max; i--)
|
||||
{
|
||||
@@ -63,17 +54,18 @@ public class PostWallPatcher extends IrisPostBlockFilter
|
||||
|
||||
if(d != null)
|
||||
{
|
||||
if(d.getMaterial().equals(AIR))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isAirOrWater(x, i, z, currentPostX, currentPostZ, currentData))
|
||||
{
|
||||
if(brokeGround)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
setPostBlock(x, i, z, d, currentPostX, currentPostZ, currentData);
|
||||
brokeGround = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,21 +36,20 @@ public class PostWaterlogger extends IrisPostBlockFilter
|
||||
if(b instanceof Waterlogged)
|
||||
{
|
||||
Waterlogged ww = (Waterlogged) b;
|
||||
|
||||
if(ww.isWaterlogged())
|
||||
boolean w = false;
|
||||
if(isWaterOrWaterlogged(x, h + 1, z, currentPostX, currentPostZ, currentData))
|
||||
{
|
||||
return;
|
||||
w = true;
|
||||
}
|
||||
|
||||
if(isWaterOrWaterlogged(x, h + 1, z, currentPostX, currentPostZ, currentData) && !ww.isWaterlogged())
|
||||
else if((isWaterOrWaterlogged(x + 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x - 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z + 1, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z - 1, currentPostX, currentPostZ, currentData)))
|
||||
{
|
||||
ww.setWaterlogged(true);
|
||||
setPostBlock(x, h, z, ww, currentPostX, currentPostZ, currentData);
|
||||
w = true;
|
||||
}
|
||||
|
||||
else if(!ww.isWaterlogged() && (isWaterOrWaterlogged(x + 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x - 1, h, z, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z + 1, currentPostX, currentPostZ, currentData) || isWaterOrWaterlogged(x, h, z - 1, currentPostX, currentPostZ, currentData)))
|
||||
if(w != ww.isWaterlogged())
|
||||
{
|
||||
ww.setWaterlogged(true);
|
||||
ww.setWaterlogged(w);
|
||||
setPostBlock(x, h, z, ww, currentPostX, currentPostZ, currentData);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user