9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-26 18:49:06 +00:00

Remove Caves, Carving & Ravines

This commit is contained in:
cyberpwn
2021-08-27 04:48:00 -04:00
parent a51f5fefc4
commit 3dcfacfeed
16 changed files with 11 additions and 1286 deletions

View File

@@ -23,7 +23,6 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.modifier.IrisCaveModifier;
import com.volmit.iris.engine.object.biome.InferredType;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.common.CaveResult;
@@ -310,33 +309,8 @@ public class IrisComplex implements DataProvider {
trueHeightStream = ProceduralStream.of((x, z) -> {
int rx = (int) Math.round(engine.modifyX(x));
int rz = (int) Math.round(engine.modifyZ(z));
int heightf = (int) Math.round(getHeightStream().get(rx, rz));
int m = heightf;
if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
m--;
while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
m--;
}
}
if (engine.getDimension().isCaves()) {
KList<CaveResult> caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null);
boolean again = true;
while (again) {
again = false;
for (CaveResult i : caves) {
if (i.getCeiling() > m && i.getFloor() < m) {
m = i.getFloor();
again = true;
}
}
}
}
return m;
// TODO CAVE STUFF
return (int) Math.round(getHeightStream().get(rx, rz));
}, Interpolated.INT).cache2D(cacheSize);
trueHeightStreamNoFeatures = ProceduralStream.of((x, z) -> {
@@ -344,30 +318,7 @@ public class IrisComplex implements DataProvider {
int rz = (int) Math.round(engine.modifyZ(z));
int heightf = (int) Math.round(getHeightStreamNoFeatures().get(rx, rz));
int m = heightf;
if (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
m--;
while (engine.getDimension().isCarved(getData(), rx, m, rz, ((IrisTerrainNormalActuator) engine.getTerrainActuator()).getRng(), heightf)) {
m--;
}
}
if (engine.getDimension().isCaves()) {
KList<CaveResult> caves = ((IrisCaveModifier) engine.getCaveModifier()).genCaves(rx, rz, 0, 0, null);
boolean again = true;
while (again) {
again = false;
for (CaveResult i : caves) {
if (i.getCeiling() > m && i.getFloor() < m) {
m = i.getFloor();
again = true;
}
}
}
}
// TODO CAVE STUFF
return m;
}, Interpolated.INT).cache2D(cacheSize);
baseBiomeIDStream = trueBiomeStream.convertAware2D((b, x, z) -> {

View File

@@ -30,10 +30,8 @@ import com.volmit.iris.engine.actuator.IrisTerrainNormalActuator;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.*;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.modifier.IrisCaveModifier;
import com.volmit.iris.engine.modifier.IrisDepositModifier;
import com.volmit.iris.engine.modifier.IrisPostModifier;
import com.volmit.iris.engine.modifier.IrisRavineModifier;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomePaletteLayer;
import com.volmit.iris.engine.object.decoration.IrisDecorator;
@@ -97,8 +95,6 @@ public class IrisEngine implements Engine {
private EngineActuator<BlockData> decorantActuator;
private EngineActuator<Biome> biomeActuator;
private EngineModifier<BlockData> depositModifier;
private EngineModifier<BlockData> caveModifier;
private EngineModifier<BlockData> ravineModifier;
private EngineModifier<BlockData> postModifier;
private final AtomicCache<IrisEngineData> engineData = new AtomicCache<>();
private final AtomicBoolean cleaning;
@@ -145,8 +141,6 @@ public class IrisEngine implements Engine {
decorantActuator.close();
biomeActuator.close();
depositModifier.close();
ravineModifier.close();
caveModifier.close();
postModifier.close();
effects.close();
}
@@ -162,8 +156,6 @@ public class IrisEngine implements Engine {
decorantActuator = new IrisDecorantActuator(this);
biomeActuator = new IrisBiomeActuator(this);
depositModifier = new IrisDepositModifier(this);
ravineModifier = new IrisRavineModifier(this);
caveModifier = new IrisCaveModifier(this);
postModifier = new IrisPostModifier(this);
effects = new IrisEngineEffects(this);
J.a(this::computeBiomeMaxes);
@@ -341,8 +333,6 @@ public class IrisEngine implements Engine {
getDecorantActuator().close();
getBiomeActuator().close();
getDepositModifier().close();
getRavineModifier().close();
getCaveModifier().close();
getPostModifier().close();
getMantle().close();
getComplex().close();
@@ -419,16 +409,10 @@ public class IrisEngine implements Engine {
getMantle().generateMatter(x >> 4, z >> 4, multicore);
getTerrainActuator().actuate(x, z, vblocks, multicore);
getBiomeActuator().actuate(x, z, vbiomes, multicore);
burst().burst(multicore,
() -> getCaveModifier().modify(x, z, vblocks, multicore),
() -> getDecorantActuator().actuate(x, z, blocks, multicore),
() -> getRavineModifier().modify(x, z, vblocks, multicore)
);
getDecorantActuator().actuate(x, z, blocks, multicore);
getPostModifier().modify(x, z, vblocks, multicore);
burst().burst(multicore,
() -> getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore),
() -> getDepositModifier().modify(x, z, vblocks, multicore)
);
getMantle().insertMatter(x >> 4, z >> 4, BlockData.class, blocks, multicore);
getDepositModifier().modify(x, z, vblocks, multicore);
}
getMetrics().getTotal().put(p.getMilliseconds());
generated.incrementAndGet();

View File

@@ -23,7 +23,6 @@ import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedActuator;
import com.volmit.iris.engine.framework.EngineDecorator;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.carve.IrisCaveLayer;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.RNG;
@@ -38,7 +37,6 @@ import java.util.function.Predicate;
public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
private static final Predicate<BlockData> PREDICATE_SOLID = (b) -> b != null && !b.getMaterial().isAir() && !b.getMaterial().equals(Material.WATER) && !b.getMaterial().equals(Material.LAVA);
private final BiPredicate<BlockData, Integer> PREDICATE_CAVELIQUID;
private final RNG rng;
@Getter
private final EngineDecorator surfaceDecorator;
@@ -61,22 +59,6 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
seaSurfaceDecorator = new IrisSeaSurfaceDecorator(getEngine());
shoreLineDecorator = new IrisShoreLineDecorator(getEngine());
seaFloorDecorator = new IrisSeaFloorDecorator(getEngine());
PREDICATE_CAVELIQUID = (b, y) -> {
for (IrisCaveLayer layer : getEngine().getDimension().getCaveLayers()) {
if (!layer.getFluid().hasFluid(getData())) {
continue;
}
if (layer.getFluid().isInverseHeight() && y >= layer.getFluid().getFluidHeight()) {
if (b.matches(layer.getFluid().getFluid(getData()))) return true;
} else if (!layer.getFluid().isInverseHeight() && y <= layer.getFluid().getFluidHeight()) {
if (b.matches(layer.getFluid().getFluid(getData()))) return true;
}
}
return false;
};
}
@BlockCoordinates
@@ -97,9 +79,8 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
int realZ;
IrisBiome biome, cave;
for (int j = 0; j < output.getDepth(); j++) {
boolean solid, liquid;
boolean solid;
int emptyFor = 0;
int liquidFor = 0;
int lastSolid = 0;
realZ = (int) Math.round(modZ(z + j));
height = (int) Math.round(getComplex().getHeightStream().get(realX, realZ));
@@ -133,24 +114,16 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
if (cave != null && cave.getDecorators().isNotEmpty()) {
for (int k = height; k > 0; k--) {
solid = PREDICATE_SOLID.test(output.get(finalI, k, j));
liquid = PREDICATE_CAVELIQUID.test(output.get(finalI, k + 1, j), k + 1);
if (solid) {
if (emptyFor > 0) {
if (liquid) {
getSeaFloorDecorator().decorate(finalI, j, realX, realZ, output, cave, k + 1, liquidFor + lastSolid - emptyFor + 1);
getSeaSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k + liquidFor + 1, emptyFor - liquidFor + lastSolid);
} else {
getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid);
getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor);
}
getSurfaceDecorator().decorate(finalI, j, realX, realZ, output, cave, k, lastSolid);
getCeilingDecorator().decorate(finalI, j, realX, realZ, output, cave, lastSolid - 1, emptyFor);
emptyFor = 0;
liquidFor = 0;
}
lastSolid = k;
} else {
emptyFor++;
if (liquid) liquidFor++;
}
}
}

View File

@@ -38,14 +38,12 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
private static final BlockData CAVE_AIR = Material.CAVE_AIR.createBlockData();
@Getter
private final RNG rng;
private final boolean carving;
@Getter
private int lastBedrock = -1;
public IrisTerrainNormalActuator(Engine engine) {
super(engine, "Terrain");
rng = new RNG(engine.getWorld().seed());
carving = getDimension().isCarving() && getDimension().getCarveLayers().isNotEmpty();
}
@BlockCoordinates
@@ -109,14 +107,6 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
}
}
if (carving && getDimension().isCarved(getData(), realX, i, realZ, rng, he)) {
continue;
}
if (getDimension().getCaverns() != null && getDimension().getCaverns().isCavern(rng, realX, i, realZ, he, getData())) {
continue;
}
if (i > he && i <= hf) {
fdepth = hf - i;

View File

@@ -100,10 +100,6 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
EngineActuator<Biome> getBiomeActuator();
EngineModifier<BlockData> getCaveModifier();
EngineModifier<BlockData> getRavineModifier();
EngineModifier<BlockData> getDepositModifier();
EngineModifier<BlockData> getPostModifier();

View File

@@ -1,254 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.modifier;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.carve.IrisCaveLayer;
import com.volmit.iris.engine.object.common.CaveResult;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.FastNoiseDouble;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
import java.util.function.Function;
public class IrisCaveModifier extends EngineAssignedModifier<BlockData> {
public static final BlockData CAVE_AIR = B.get("CAVE_AIR");
public static final BlockData AIR = B.get("AIR");
private static final KList<CaveResult> EMPTY = new KList<>();
private final FastNoiseDouble gg;
private final RNG rng;
public IrisCaveModifier(Engine engine) {
super(engine, "Cave");
rng = new RNG(engine.getWorld().seed() + 28934555);
gg = new FastNoiseDouble(324895L * rng.nextParallelRNG(49678).imax());
}
@Override
public void onModify(int x, int z, Hunk<BlockData> a, boolean multicore) {
if (!getDimension().isCaves()) {
return;
}
PrecisionStopwatch p = PrecisionStopwatch.start();
BurstExecutor e = burst().burst(multicore);
for (int i = 0; i < a.getWidth(); i++) {
int finalI = i;
e.queue(() -> modifySliver(x, z, finalI, a));
}
e.complete();
getEngine().getMetrics().getCave().put(p.getMilliseconds());
}
public void modifySliver(int x, int z, int finalI, Hunk<BlockData> a) {
for (int j = 0; j < a.getDepth(); j++) {
KList<CaveResult> caves = genCaves(x + finalI, z + j, finalI, j, a);
int he = (int) Math.round(getComplex().getHeightStream().get(x + finalI, z + j));
if (caves != null && caves.isNotEmpty()) {
IrisBiome cave = getComplex().getCaveBiomeStream().get(x + finalI, z + j);
if (cave == null) {
continue;
}
for (CaveResult cl : caves) {
if (cl.getFloor() < 0 || cl.getFloor() > getEngine().getHeight() || cl.getCeiling() > getEngine().getHeight() || cl.getCeiling() < 0) {
continue;
}
KList<BlockData> floor = cave.generateLayers(getDimension(), x + finalI, z + j, rng, cl.getFloor(), cl.getFloor(), getData(), getComplex());
KList<BlockData> ceiling = cave.generateLayers(getDimension(), x + finalI + 656, z + j - 656, rng,
he - cl.getCeiling(),
he - cl.getCeiling(), getData(), getComplex());
for (int g = 0; g < floor.size(); g++) {
a.set(finalI, cl.getFloor() - g, j, floor.get(g));
}
for (int g = ceiling.size() - 1; g > 0; g--) {
a.set(finalI, cl.getCeiling() + g, j, ceiling.get(g));
}
}
}
}
}
public KList<CaveResult> genCaves(double wxx, double wzz) {
return genCaves(wxx, wzz, 0, 0, null);
}
public KList<CaveResult> genCaves(double wxx, double wzz, int x, int z, Hunk<BlockData> data) {
if (!getDimension().isCaves()) {
return EMPTY;
}
KList<CaveResult> result = new KList<>();
gg.setNoiseType(FastNoiseDouble.NoiseType.Cellular);
gg.setCellularReturnType(FastNoiseDouble.CellularReturnType.Distance2Sub);
gg.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural);
for (int i = 0; i < getDimension().getCaveLayers().size(); i++) {
IrisCaveLayer layer = getDimension().getCaveLayers().get(i);
generateCave(result, wxx, wzz, x, z, data, layer, i);
}
return result;
}
public void generateCave(KList<CaveResult> result, double wxx, double wzz, int x, int z, Hunk<BlockData> data, IrisCaveLayer layer, int seed) {
double scale = layer.getCaveZoom();
Function<Integer, BlockData> fluid = (height) ->
{
if (!layer.getFluid().hasFluid(getData())) {
return CAVE_AIR;
}
if (layer.getFluid().isInverseHeight() && height >= layer.getFluid().getFluidHeight()) {
return layer.getFluid().getFluid(getData());
} else if (!layer.getFluid().isInverseHeight() && height <= layer.getFluid().getFluidHeight()) {
return layer.getFluid().getFluid(getData());
}
return CAVE_AIR;
};
int surface = (int) Math.round(getComplex().getHeightStream().get(wxx, wzz));
double wx = wxx + layer.getHorizontalSlope().get(rng, getData(), wxx, wzz);
double wz = wzz + layer.getHorizontalSlope().get(rng, getData(), -wzz, -wxx);
double baseWidth = (14 * scale);
double distanceCheck = 0.0132 * baseWidth;
double distanceTake = 0.0022 * baseWidth;
double caveHeightNoise = layer.getVerticalSlope().get(rng, getData(), wxx, wzz);
if (caveHeightNoise > 259 || caveHeightNoise < -1) {
return;
}
// TODO: WARNING HEIGHT
int ceiling = -256;
int floor = 512;
for (double tunnelHeight = 1; tunnelHeight <= baseWidth; tunnelHeight++) {
double distance = (gg.GetCellular(((wx + (10000 * seed)) / layer.getCaveZoom()), ((wz - (10000 * seed)) / layer.getCaveZoom())) + 1D) / 2D;
if (distance < distanceCheck - (tunnelHeight * distanceTake)) {
int caveHeight = (int) Math.round(caveHeightNoise);
int pu = (int) (caveHeight + tunnelHeight);
int pd = (int) (caveHeight - tunnelHeight);
if (pd > surface + 1) {
continue;
}
if (!layer.isCanBreakSurface() && pu > surface - 3) {
continue;
}
if ((pu > 255 && pd > 255) || (pu < 0 && pd < 0)) {
continue;
}
if (data == null) {
ceiling = Math.max(pu, ceiling);
floor = Math.min(pu, floor);
ceiling = Math.max(pd, ceiling);
floor = Math.min(pd, floor);
if (tunnelHeight == 1) {
ceiling = Math.max(caveHeight, ceiling);
floor = Math.min(caveHeight, floor);
}
} else {
if (dig(x, pu, z, data, fluid)) {
ceiling = Math.max(pu, ceiling);
floor = Math.min(pu, floor);
}
if (dig(x, pd, z, data, fluid)) {
ceiling = Math.max(pd, ceiling);
floor = Math.min(pd, floor);
}
if (tunnelHeight == 1) {
if (dig(x, caveHeight, z, data, fluid)) {
ceiling = Math.max(caveHeight, ceiling);
floor = Math.min(caveHeight, floor);
}
}
}
}
}
if (floor >= 0 && ceiling <= 255) {
result.add(new CaveResult(floor, ceiling));
}
}
private Material mat(int x, int y, int z, Hunk<BlockData> data) {
BlockData d = data.get(Math.max(x, 0), Math.max(y, 0), Math.max(z, 0));
if (d != null) {
return d.getMaterial();
}
return Material.CAVE_AIR;
}
public boolean dig(int x, int y, int z, Hunk<BlockData> data, Function<Integer, BlockData> caveFluid) {
Material a = mat(x, y, z, data);
Material c = mat(x, y + 1, z, data);
Material d = mat(x, y + 2, z, data);
Material e = mat(x, y + 3, z, data);
Material f = mat(x, y - 1, z, data);
BlockData b = caveFluid.apply(y);
BlockData b2 = caveFluid.apply(y + 1);
if (can(a) && canAir(c, b) && canAir(f, b) && canWater(d) && canWater(e)) {
data.set(x, y, z, b);
data.set(x, y + 1, z, b2);
return true;
}
return false;
}
public boolean canAir(Material m, BlockData caveFluid) {
return (m.isSolid() ||
(B.isDecorant(m.createBlockData())) || m.equals(Material.AIR)
|| m.equals(caveFluid.getMaterial()) ||
m.equals(B.getMaterial("CAVE_AIR")))
&& !m.equals(Material.BEDROCK);
}
public boolean canWater(Material m) {
return !m.equals(Material.WATER);
}
public boolean can(Material m) {
return m.isSolid() && !m.equals(Material.BEDROCK);
}
}

View File

@@ -231,189 +231,6 @@ public class IrisPostModifier extends EngineAssignedModifier<BlockData> {
setPostBlock(x, h + 1, z, AIR, currentPostX, currentPostZ, currentData);
}
}
if (getDimension().isPostProcessCaves()) {
IrisBiome cave = getComplex().getCaveBiomeStream().get(x, z);
if (cave != null) {
for (CaveResult i : ((IrisCaveModifier) getEngine().getCaveModifier()).genCaves(x, z, 0, 0, null)) {
if (i.getCeiling() >= currentData.getMax2DParallelism() || i.getFloor() < 0) {
continue;
}
int f = i.getFloor();
int fa = nearestCaveFloor(f, x + 1, z, currentPostX, currentPostZ, currentData);
int fb = nearestCaveFloor(f, x, z + 1, currentPostX, currentPostZ, currentData);
int fc = nearestCaveFloor(f, x - 1, z, currentPostX, currentPostZ, currentData);
int fd = nearestCaveFloor(f, x, z - 1, currentPostX, currentPostZ, currentData);
int c = i.getCeiling();
int ca = nearestCaveCeiling(c, x + 1, z, currentPostX, currentPostZ, currentData);
int cb = nearestCaveCeiling(c, x, z + 1, currentPostX, currentPostZ, currentData);
int cc = nearestCaveCeiling(c, x - 1, z, currentPostX, currentPostZ, currentData);
int cd = nearestCaveCeiling(c, x, z - 1, currentPostX, currentPostZ, currentData);
// Cave Nibs
g = 0;
g += fa == f - 1 ? 1 : 0;
g += fb == f - 1 ? 1 : 0;
g += fc == f - 1 ? 1 : 0;
g += fd == f - 1 ? 1 : 0;
if (g >= 4) {
BlockData bc = getPostBlock(x, f, z, currentPostX, currentPostZ, currentData);
b = getPostBlock(x, f + 1, z, currentPostX, currentPostZ, currentData);
Material m = bc.getMaterial();
if (m.isSolid()) {
setPostBlock(x, f, z, b, currentPostX, currentPostZ, currentData);
h--;
}
} else {
// Cave Potholes
g = 0;
g += fa == f + 1 ? 1 : 0;
g += fb == f + 1 ? 1 : 0;
g += fc == f + 1 ? 1 : 0;
g += fd == f + 1 ? 1 : 0;
if (g >= 4) {
BlockData ba = getPostBlock(x, fa, z, currentPostX, currentPostZ, currentData);
BlockData bb = getPostBlock(x, fb, z, currentPostX, currentPostZ, currentData);
BlockData bc = getPostBlock(x, fc, z, currentPostX, currentPostZ, currentData);
BlockData bd = getPostBlock(x, fd, z, currentPostX, currentPostZ, currentData);
g = 0;
g = B.isSolid(ba) ? g + 1 : g;
g = B.isSolid(bb) ? g + 1 : g;
g = B.isSolid(bc) ? g + 1 : g;
g = B.isSolid(bd) ? g + 1 : g;
if (g >= 4) {
setPostBlock(x, f + 1, z, getPostBlock(x, f, z, currentPostX, currentPostZ, currentData), currentPostX, currentPostZ, currentData);
h++;
}
}
}
if (getDimension().isPostProcessingSlabs()) {
//@builder
if ((fa == f + 1 && isSolidNonSlab(x + 1, fa, z, currentPostX, currentPostZ, currentData))
|| (fb == f + 1 && isSolidNonSlab(x, fb, z + 1, currentPostX, currentPostZ, currentData))
|| (fc == f + 1 && isSolidNonSlab(x - 1, fc, z, currentPostX, currentPostZ, currentData))
|| (fd == f + 1 && isSolidNonSlab(x, fd, z - 1, currentPostX, currentPostZ, currentData)))
//@done
{
BlockData d = cave.getSlab().get(rng, x, f, z, getData());
if (d != null) {
boolean cancel = B.isAir(d);
if (d.getMaterial().equals(Material.SNOW) && f + 1 <= getDimension().getFluidHeight()) {
cancel = true;
}
if (isSnowLayer(x, f, z, currentPostX, currentPostZ, currentData)) {
cancel = true;
}
if (!cancel && isAirOrWater(x, f + 1, z, currentPostX, currentPostZ, currentData)) {
setPostBlock(x, f + 1, z, d, currentPostX, currentPostZ, currentData);
}
}
}
//@builder
if ((ca == c - 1 && isSolidNonSlab(x + 1, ca, z, currentPostX, currentPostZ, currentData))
|| (cb == c - 1 && isSolidNonSlab(x, cb, z + 1, currentPostX, currentPostZ, currentData))
|| (cc == c - 1 && isSolidNonSlab(x - 1, cc, z, currentPostX, currentPostZ, currentData))
|| (cd == c - 1 && isSolidNonSlab(x, cd, z - 1, currentPostX, currentPostZ, currentData)))
//@done
{
BlockData d = cave.getSlab().get(rng, x, c, z, getData());
if (d != null) {
boolean cancel = B.isAir(d);
if (!(d instanceof Slab)) {
cancel = true;
}
if (isSnowLayer(x, c, z, currentPostX, currentPostZ, currentData)) {
cancel = true;
}
if (!cancel && isAirOrWater(x, c, z, currentPostX, currentPostZ, currentData)) {
try {
Slab slab = (Slab) d.clone();
slab.setType(Slab.Type.TOP);
setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData);
} catch (Throwable e) {
Iris.reportError(e);
try {
Slab slab = (Slab) d.clone();
synchronized (slab) {
slab.setType(Slab.Type.TOP);
setPostBlock(x, c, z, slab, currentPostX, currentPostZ, currentData);
}
} catch (Throwable ee) {
Iris.reportError(ee);
}
}
}
}
}
}
}
}
}
}
private int nearestCaveFloor(int floor, int x, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
if (floor >= currentData.getHeight()) {
return currentData.getHeight() - 1;
}
if (B.isAir(getPostBlock(x, floor, z, currentPostX, currentPostZ, currentData))) {
if (B.isAir(getPostBlock(x, floor - 1, z, currentPostX, currentPostZ, currentData))) {
return floor - 2;
}
return floor - 1;
} else {
if (!B.isAir(getPostBlock(x, floor + 1, z, currentPostX, currentPostZ, currentData))) {
if (!B.isAir(getPostBlock(x, floor + 2, z, currentPostX, currentPostZ, currentData))) {
return floor + 2;
}
return floor + 1;
}
return floor;
}
}
private int nearestCaveCeiling(int ceiling, int x, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {
if (ceiling >= currentData.getHeight()) {
return currentData.getHeight() - 1;
}
if (B.isAir(getPostBlock(x, ceiling, z, currentPostX, currentPostZ, currentData))) {
if (B.isAir(getPostBlock(x, ceiling + 1, z, currentPostX, currentPostZ, currentData))) {
return ceiling + 2;
}
return ceiling + 1;
} else {
if (!B.isAir(getPostBlock(x, ceiling - 1, z, currentPostX, currentPostZ, currentData))) {
if (!B.isAir(getPostBlock(x, ceiling - 2, z, currentPostX, currentPostZ, currentData))) {
return ceiling - 2;
}
return ceiling - 1;
}
return ceiling;
}
}
public boolean isAir(int x, int y, int z, int currentPostX, int currentPostZ, Hunk<BlockData> currentData) {

View File

@@ -1,286 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.modifier;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineAssignedModifier;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.math.BlockPosition;
import com.volmit.iris.util.math.MathHelper;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import org.bukkit.Material;
import org.bukkit.block.data.BlockData;
@SuppressWarnings("ALL")
public class IrisRavineModifier extends EngineAssignedModifier<BlockData> {
private static final BlockData CAVE_AIR = B.get("CAVE_AIR");
private static final BlockData LAVA = B.get("LAVA");
private final CNG cng;
private final RNG rng;
public IrisRavineModifier(Engine engine) {
super(engine, "Ravine");
rng = new RNG(getEngine().getWorld().seed()).nextParallelRNG(29596878);
cng = NoiseStyle.IRIS_THICK.create(rng);
}
@Override
public void onModify(int x, int z, Hunk<BlockData> output, boolean multicore) {
if (!getDimension().isRavines()) {
return;
}
PrecisionStopwatch p = PrecisionStopwatch.start();
generateRavines(rng, Math.floorDiv(x, 16), Math.floorDiv(z, 16), output);
getEngine().getMetrics().getRavine().put(p.getMilliseconds());
}
private void set(Hunk<BlockData> pos, int x, int y, int z, BlockData b) {
pos.set(x, y, z, b);
}
private BlockData get(Hunk<BlockData> pos, int x, int y, int z) {
BlockData bb = pos.get(x, y, z);
if (bb == null) {
bb = CAVE_AIR;
}
return bb;
}
private BlockData getSurfaceBlock(int n6, int i, RNG rmg) {
return getComplex().getTrueBiomeStream().get(n6, i).getSurfaceBlock(n6, i, rmg, getData());
}
private final float[] ravineCache = new float[1024];
private void doRavine(long seed, int tx, int tz, Position2 pos, double sx, double sy, double sz, float f, float f2, float f3, @SuppressWarnings("SameParameterValue") int n3, @SuppressWarnings("SameParameterValue") int n4, @SuppressWarnings("SameParameterValue") double d4, RNG bbx, Hunk<BlockData> terrain) {
int n5;
RNG random = new RNG(seed);
double x = tx * 16 + 8;
double z = tz * 16 + 8;
float f4 = 0.0f;
float f5 = 0.0f;
if (n4 <= 0) {
n5 = 8 * 16 - 16;
n4 = n5 - random.nextInt(n5 / 4);
}
n5 = 0;
if (n3 == -1) {
n3 = n4 / 2;
n5 = 1;
}
float f6 = 1.0f;
// TODO: WARNING HEIGHT
for (int i = 0; i < 256; ++i) {
if (i == 0 || random.nextInt(getDimension().getRavineRibRarity()) == 0) {
f6 = 1.0f + random.nextFloat() * random.nextFloat() * 1.0f;
}
this.ravineCache[i] = f6 * f6;
}
while (n3 < n4) {
double d7 = 1.5 + (double) (MathHelper.sin((float) n3 * 3.1415927f / (float) n4) * f * 1.0f);
double d8 = d7 * d4;
d7 *= (double) random.nextFloat() * 0.25 + 0.75;
d8 *= (double) random.nextFloat() * 0.25 + 0.75;
float f7 = MathHelper.cos(f3);
float f8 = MathHelper.sin(f3);
sx = sx + (double) (MathHelper.cos(f2) * f7);
sy += f8;
sz += MathHelper.sin(f2) * f7;
f3 *= 0.7f;
f3 += f5 * 0.05f;
f2 += f4 * 0.05f;
f5 *= 0.8f;
f4 *= 0.5f;
f5 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2.0f;
f4 += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4.0f;
if (n5 != 0 || random.nextInt(4) != 0) {
double d9 = sx - x;
double d10 = sz - z;
double d11 = n4 - n3;
double d12 = f + 2.0f + 16.0f;
if (d9 * d9 + d10 * d10 - d11 * d11 > d12 * d12) {
return;
}
if (sx >= x - 16.0 - d7 * 2.0 && sz >= z - 16.0 - d7 * 2.0 && sx <= x + 16.0 + d7 * 2.0 && sz <= z + 16.0 + d7 * 2.0) {
int n6;
int n7 = MathHelper.floor(sx - d7) - tx * 16 - 1;
int n8 = MathHelper.floor(sx + d7) - tx * 16 + 1;
int n9 = MathHelper.floor(sy - d8) - 1;
int n10 = MathHelper.floor(sy + d8) + 1;
int n11 = MathHelper.floor(sz - d7) - tz * 16 - 1;
int n12 = MathHelper.floor(sz + d7) - tz * 16 + 1;
if (n7 < 0) {
n7 = 0;
}
if (n8 > 16) {
n8 = 16;
}
if (n9 < 1) {
n9 = 1;
}
if (n10 > 248) {
n10 = 248;
}
if (n11 < 0) {
n11 = 0;
}
if (n12 > 16) {
n12 = 16;
}
boolean bl = false;
for (int i = n7; !bl && i < n8; ++i) {
for (n6 = n11; !bl && n6 < n12; ++n6) {
for (int j = n10 + 1; !bl && j >= n9 - 1; --j) {
// TODO: WARNING HEIGHT
if (j < 0 || j >= 256) {
continue;
}
BlockData bb = get(terrain, i, j, n6);
if (B.isWater(bb)) {
bl = true;
}
if (j == n9 - 1 || i == n7 || i == n8 - 1 || n6 == n11 || n6 == n12 - 1) {
continue;
}
j = n9;
}
}
}
if (!bl) {
BlockPosition bps = new BlockPosition(0, 0, 0);
for (n6 = n7; n6 < n8; ++n6) {
double d13 = ((double) (n6 + tx * 16) + 0.5 - sx) / d7;
for (int i = n11; i < n12; ++i) {
double d14 = ((double) (i + tz * 16) + 0.5 - sz) / d7;
boolean bl2 = false;
if (d13 * d13 + d14 * d14 >= 1.0) {
continue;
}
for (int j = n10; j > n9; --j) {
double d15 = ((double) (j - 1) + 0.5 - sy) / d8;
if ((d13 * d13 + d14 * d14) * (double) this.ravineCache[j - 1] + d15 * d15 / 6.0 >= 1.0) {
continue;
}
BlockData blockData = get(terrain, n6, j, i);
if (isSurface(blockData)) {
bl2 = true;
}
if (j - 1 < 10) {
set(terrain, n6, j, i, LAVA);
continue;
}
set(terrain, n6, j, i, CAVE_AIR);
if (!bl2 || !isDirt(get(terrain, n6, j - 1, i))) {
continue;
}
cSet(bps, n6 + tx * 16, 0, i + tz * 16);
set(terrain, n6, j - 1, i, getSurfaceBlock(n6, i, rng));
}
}
}
if (n5 != 0) {
break;
}
}
}
}
++n3;
}
}
private BlockPosition cSet(BlockPosition bb, double var0, @SuppressWarnings("SameParameterValue") double var2, double var4) {
bb.setX(MathHelper.floor(var0));
bb.setY(MathHelper.floor(var2));
bb.setZ(MathHelper.floor(var4));
return bb;
}
private boolean isDirt(BlockData d) {
//@builder
Material m = d.getMaterial();
return m.equals(Material.DIRT) ||
m.equals(Material.COARSE_DIRT) ||
m.equals(Material.SAND);
//@done
}
private boolean isSurface(BlockData d) {
//@builder
Material m = d.getMaterial();
return m.equals(Material.GRASS_BLOCK) ||
m.equals(Material.DIRT) ||
m.equals(Material.COARSE_DIRT) ||
m.equals(Material.PODZOL) ||
m.equals(Material.SAND);
//@done
}
public void genRavines(int n, int n2, Position2 chunkSnapshot, RNG bbb, Hunk<BlockData> terrain) {
RNG b = this.rng.nextParallelRNG(21949666);
RNG bx = this.rng.nextParallelRNG(6676121);
long l = b.nextLong();
long l2 = b.nextLong();
for (int i = n - 8; i <= n + 8; ++i) {
for (int j = n2 - 8; j <= n2 + 8; ++j) {
long l3 = (long) i * l;
long l4 = (long) j * l2;
bx = this.rng.nextParallelRNG((int) (l3 ^ l4 ^ 6676121));
doRavines(i, j, n, n2, chunkSnapshot, bx, terrain);
}
}
}
private void doRavines(int tx, int tz, int sx, int sz, Position2 chunkSnapshot, RNG b, Hunk<BlockData> terrain) {
if (b.nextInt(getDimension().getRavineRarity()) != 0) {
return;
}
double x = tx * 16 + b.nextInt(16);
double d2 = b.nextInt(b.nextInt(40) + 8) + 20;
double z = tz * 16 + b.nextInt(16);
int n5 = 1;
for (int i = 0; i < n5; ++i) {
float f = b.nextFloat() * 3.1415927f * 2.0f;
float f2 = (b.nextFloat() - 0.5f) * 2.0f / 8.0f;
float f3 = (b.nextFloat() * 2.0f + b.nextFloat()) * 2.0f;
this.doRavine(b.nextLong(), sx, sz, chunkSnapshot, x, d2, z, f3, f, f2, 0, 0, 3.0, b, terrain);
}
}
public void generateRavines(RNG nextParallelRNG, int x, int z, Hunk<BlockData> terrain) {
genRavines(x, z, new Position2(x, z), nextParallelRNG.nextParallelRNG(x).nextParallelRNG(z), terrain);
}
}

View File

@@ -1,112 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carve;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MaxNumber;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.util.interpolation.IrisInterpolation;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.stream.ProceduralStream;
import com.volmit.iris.util.stream.interpolation.Interpolated;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Translate objects")
@Data
public class IrisCarveLayer {
@Required
@Desc("The 4d slope this carve layer follows")
private IrisGeneratorStyle style = new IrisGeneratorStyle();
@MaxNumber(512)
@MinNumber(-128)
@Desc("The max height")
private int maxHeight = 220;
@MinNumber(0.0)
@MaxNumber(1.0)
@Desc("The full percentage means the 4D opacity of this carver will decay from 100% to 0% at the min & max vertical ranges. Setting the percent to 1.0 will make a very drastic & charp change at the edge of the vertical min & max. Where as 0.15 means only 15% of the vertical range will actually be 100% opacity.")
private double fullPercent = 0.5;
@MaxNumber(512)
@MinNumber(-128)
@Desc("The min height")
private int minHeight = 147;
@MaxNumber(1)
@MinNumber(0)
@Desc("The threshold used as: \n\ncarved = noise(x,y,z) > threshold")
private double threshold = 0.5;
private final transient AtomicCache<ProceduralStream<Boolean>> streamCache = new AtomicCache<>();
private final transient AtomicCache<ProceduralStream<Double>> rawStreamCache = new AtomicCache<>();
private final transient AtomicCache<CNG> cng = new AtomicCache<>();
public boolean isCarved(RNG rng, IrisData data, double x, double y, double z) {
if (y > getMaxHeight() || y < getMinHeight()) {
return false;
}
double opacity = Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(getMinHeight(), getMaxHeight(), y)), 4);
return getCng(rng, data).fitDouble(0D, 1D, x, y, z) * opacity > getThreshold();
}
public ProceduralStream<Boolean> stream(RNG rng, IrisData data) {
return streamCache.aquire(() -> ProceduralStream.of((x, y, z) -> isCarved(rng, data, x, y, z), Interpolated.BOOLEAN));
}
public ProceduralStream<Double> rawStream(RNG rng, IrisData data) {
return rawStreamCache.aquire(() -> ProceduralStream.of((x, y, z) -> {
return getCng(rng, data).fitDouble(0D, 1D, x, y, z) * Math.pow(IrisInterpolation.sinCenter(M.lerpInverse(getMinHeight(), getMaxHeight(), y)), 4);
}, Interpolated.DOUBLE));
}
public CNG getCng(RNG rng, IrisData data) {
return cng.aquire(() -> getStyle().create(rng.nextParallelRNG(-2340 * getMaxHeight() * getMinHeight()), data));
}
public boolean isCarved2(RNG rng, IrisData data, double x, double y, double z) {
if (y > getMaxHeight() || y < getMinHeight()) {
return false;
}
double innerRange = fullPercent * (maxHeight - minHeight);
double opacity = 1D;
if (y <= minHeight + innerRange) {
opacity = IrisInterpolation.bezier(M.lerpInverse(getMinHeight(), minHeight + innerRange, y));
} else if (y >= maxHeight - innerRange) {
opacity = IrisInterpolation.bezier(1D - M.lerpInverse(maxHeight - innerRange, getMaxHeight(), y));
}
return cng.aquire(() -> getStyle().create(rng.nextParallelRNG(-2340 * getMaxHeight() * getMinHeight()), data)).fitDouble(0D, 1D, x, y, z) * opacity > getThreshold();
}
}

View File

@@ -1,72 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carve;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MaxNumber;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.block.IrisBlockData;
import com.volmit.iris.util.data.B;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.block.data.BlockData;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Translate objects")
@Data
public class IrisCaveFluid {
@Required
@MaxNumber(255)
@MinNumber(0)
@Desc("The fluid height of the cave")
private int fluidHeight = 35;
@Desc("Insead of fluidHeight & below being fluid, turning inverse height on will simply spawn fluid in this cave layer from min(max_height, cave_height) to the fluid height. Basically, fluid will spawn above the fluidHeight value instead of below the fluidHeight.")
private boolean inverseHeight = false;
@Required
@Desc("The fluid type that should spawn here")
private IrisBlockData fluidType = new IrisBlockData("CAVE_AIR");
private final transient AtomicCache<BlockData> fluidData = new AtomicCache<>();
public boolean hasFluid(IrisData rdata) {
return !B.isAir(getFluid(rdata));
}
public BlockData getFluid(IrisData rdata) {
return fluidData.aquire(() ->
{
BlockData b = getFluidType().getBlockData(rdata);
if (b != null) {
return b;
}
return B.get("CAVE_AIR");
});
}
}

View File

@@ -1,58 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carve;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.noise.IrisShapedGeneratorStyle;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Translate objects")
@Data
public class IrisCaveLayer {
@Required
@Desc("The vertical slope this cave layer follows")
private IrisShapedGeneratorStyle verticalSlope = new IrisShapedGeneratorStyle();
@Required
@Desc("The horizontal slope this cave layer follows")
private IrisShapedGeneratorStyle horizontalSlope = new IrisShapedGeneratorStyle();
@Desc("If defined, a cave fluid will fill this cave below (or above) the specified fluidHeight in this object.")
private IrisCaveFluid fluid = new IrisCaveFluid();
@MinNumber(0.001)
@Desc("The cave zoom. Higher values makes caves spread out further and branch less often, but are thicker.")
private double caveZoom = 1D;
@MinNumber(0.001)
@Desc("The cave thickness.")
private double caveThickness = 1D;
@Desc("If set to true, this cave layer can break the surface")
private boolean canBreakSurface = false;
}

View File

@@ -1,69 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carve;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MaxNumber;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.common.IRare;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.stream.ProceduralStream;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Represents a cavern zone")
@Data
public class IrisCavernZone implements IRare {
@Desc("Use carving in this zone if defined")
private IrisCarveLayer carver = null;
@Desc("Use worley styled caves if defined")
private IrisGeneratorStyle worley = null;
@MinNumber(1)
@MaxNumber(100)
@Desc("The rarity of this zone")
private int rarity = 1;
private transient AtomicCache<ProceduralStream<Boolean>> carveCache = new AtomicCache<>();
public boolean isCarved(RNG rng, IrisData data, double xx, double yy, double zz) {
if (carver != null) {
return carver.isCarved(rng, data, xx, yy, zz);
}
return false;
}
public double getCarved(RNG rng, IrisData data, double xx, double yy, double zz) {
if (carver != null) {
return carver.rawStream(rng, data).get(xx, yy, zz) / (carver.getThreshold() * 2);
}
return -1;
}
}

View File

@@ -1,96 +0,0 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.engine.object.carve;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.ArrayType;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.noise.IrisGeneratorStyle;
import com.volmit.iris.engine.object.noise.IrisInterpolator3D;
import com.volmit.iris.engine.object.noise.NoiseStyle;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.stream.ProceduralStream;
import com.volmit.iris.util.stream.interpolation.Interpolated;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Represents a cavern system")
@Data
public class IrisCaverns {
@ArrayType(type = IrisCavernZone.class, min = 1)
@Desc("Define different cavern zones")
private KList<IrisCavernZone> zones = new KList<>();
@Desc("The 3D interpolator to connect caverns")
private IrisInterpolator3D interpolator = new IrisInterpolator3D();
@Desc("Defines how cavern zones are placed in the world")
private IrisGeneratorStyle zoneStyle = new IrisGeneratorStyle(NoiseStyle.CELLULAR);
@Desc("Threshold defined")
private double bottomBleed = 16;
@Desc("Threshold defined")
private double topBleed = 16;
@Desc("If set to true (default) iris will interpolate the noise before checking if it meets the threshold.")
private boolean preThresholdInterpolation = true;
private transient AtomicCache<ProceduralStream<IrisCavernZone>> zonesRarity = new AtomicCache<>();
private transient AtomicCache<ProceduralStream<Double>> streamCache = new AtomicCache<>();
public IrisCavernZone getZone(double x, double y, double z, RNG rng, IrisData data) {
return zonesRarity.aquire(() -> zoneStyle.create(rng, data)
.stream().selectRarity(getZones())).get(x, y, z);
}
private double threshold(double y) {
return 0.5;
}
public ProceduralStream<Double> stream(RNG rng, IrisData data) {
if (preThresholdInterpolation) {
return streamCache.aquire(() -> ProceduralStream.of((xx, yy, zz)
-> (getZone(xx, yy, zz, rng, data)
.getCarved(rng, data, xx, yy, zz)), Interpolated.DOUBLE)
.cache3D(65535));
}
return streamCache.aquire(() -> ProceduralStream.of((xx, yy, zz)
-> (getZone(xx, yy, zz, rng, data)
.isCarved(rng, data, xx, yy, zz) ? 1D : 0D), Interpolated.DOUBLE)
.cache3D(65535));
}
public boolean isCavern(RNG rng, double x, double y, double z, double height, IrisData data) {
if (zones.isEmpty()) {
return false;
}
return getInterpolator().interpolate(x, y, z, (xx, yy, zz)
-> stream(rng, data).get(xx, yy, zz)) > threshold(height);
}
}

View File

@@ -28,10 +28,6 @@ import com.volmit.iris.engine.object.biome.IrisBiome;
import com.volmit.iris.engine.object.biome.IrisBiomeCustom;
import com.volmit.iris.engine.object.block.IrisBlockDrops;
import com.volmit.iris.engine.object.block.IrisMaterialPalette;
import com.volmit.iris.engine.object.carve.IrisCarveLayer;
import com.volmit.iris.engine.object.carve.IrisCaveFluid;
import com.volmit.iris.engine.object.carve.IrisCaveLayer;
import com.volmit.iris.engine.object.carve.IrisCaverns;
import com.volmit.iris.engine.object.deposits.IrisDepositGenerator;
import com.volmit.iris.engine.object.feature.IrisFeaturePositional;
import com.volmit.iris.engine.object.feature.IrisFeaturePotential;
@@ -117,9 +113,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Tree growth override settings")
private IrisTreeSettings treeSettings = new IrisTreeSettings();
@Desc("Define iris cavern zones")
private IrisCaverns caverns = new IrisCaverns();
@Desc("Upon joining this world, Iris will send a resource pack request to the client. If they have previously selected yes, it will auto-switch depending on which dimension they go to.")
private String resourcePack = "";
@@ -182,9 +175,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Carve terrain or not")
private boolean carving = true;
@Desc("If defined, If air is defined below the area, this fluid will always place")
private IrisCaveFluid forceFluid = new IrisCaveFluid();
@Desc("Generate decorations or not")
private boolean decorate = true;
@@ -297,14 +287,6 @@ public class IrisDimension extends IrisRegistrant {
@Desc("Overlay additional noise on top of the interoplated terrain.")
private KList<IrisShapedGeneratorStyle> overlayNoise = new KList<>();
@ArrayType(min = 1, type = IrisCaveLayer.class)
@Desc("Define cave layers")
private KList<IrisCaveLayer> caveLayers = new KList<>();
@ArrayType(min = 1, type = IrisCarveLayer.class)
@Desc("Define carve layers")
private KList<IrisCarveLayer> carveLayers = new KList<>();
@Desc("If true, the spawner system has infinite energy. This is NOT recommended because it would allow for mobs to keep spawning over and over without a rate limit")
private boolean infiniteEnergy = false;
@@ -363,18 +345,6 @@ public class IrisDimension extends IrisRegistrant {
return rad.aquire(() -> Math.toRadians(dimensionAngleDeg));
}
public boolean isCarved(IrisData data, int x, int y, int z, RNG rng, int terrainHeight) {
if (isCarving() && terrainHeight > getFluidHeight() || y < terrainHeight) {
for (IrisCarveLayer j : getCarveLayers()) {
if (j.isCarved(rng, data, x, y, z)) {
return true;
}
}
}
return false;
}
public Environment getEnvironment() {
return environment;
}

View File

@@ -22,7 +22,6 @@ import com.volmit.iris.Iris;
import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.modifier.IrisCaveModifier;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
@@ -88,15 +87,7 @@ public class IrisEntitySpawn implements IRare {
IrisComplex comp = gen.getComplex();
IrisBiome cave = comp.getCaveBiomeStream().get(x, z);
KList<Location> r = new KList<>();
if (cave != null) {
for (CaveResult i : ((IrisCaveModifier) gen.getCaveModifier()).genCaves(x, z)) {
if (i.getCeiling() >= gen.getHeight() || i.getFloor() < 0 || i.getCeiling() - 2 <= i.getFloor()) {
continue;
}
r.add(new Location(c.getWorld(), x, i.getFloor(), z));
}
}
r.add( new Location(c.getWorld(), x, hf + 1, z)); // TODO CAVE HEIGHT
yield r.getRandom(rng);
}

View File

@@ -265,7 +265,7 @@ public class IrisRegion extends IrisRegistrant implements IRare {
return 1;
}
public CNG getShoreHeightGenerator() {
return shoreHeightGenerator.aquire(() ->
CNG.signature(new RNG((long) (getName().length() + getLandBiomeZoom() + getLandBiomes().size() + 3458612))));