mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-03 06:16:19 +00:00
add some options for customizing caves
This commit is contained in:
@@ -35,6 +35,7 @@ import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.mantle.MantleChunk;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.matter.Matter;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import lombok.Data;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.Vector;
|
||||
@@ -71,6 +72,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
||||
private static Set<IrisPosition> getBallooned(Set<IrisPosition> vset, double radius) {
|
||||
Set<IrisPosition> returnset = new HashSet<>();
|
||||
int ceilrad = (int) Math.ceil(radius);
|
||||
double r2 = Math.pow(radius, 2);
|
||||
|
||||
for (IrisPosition v : vset) {
|
||||
int tipx = v.getX();
|
||||
@@ -80,7 +82,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
||||
for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
|
||||
for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) {
|
||||
for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
|
||||
if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= radius) {
|
||||
if (hypot(loopx - tipx, loopy - tipy, loopz - tipz) <= r2) {
|
||||
returnset.add(new IrisPosition(loopx, loopy, loopz));
|
||||
}
|
||||
}
|
||||
@@ -113,7 +115,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
||||
for (double d : pars) {
|
||||
sum += Math.pow(d, 2);
|
||||
}
|
||||
return Math.sqrt(sum);
|
||||
return sum;
|
||||
}
|
||||
|
||||
private static double lengthSq(double x, double y, double z) {
|
||||
@@ -453,6 +455,62 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setLineConsumer(List<IrisPosition> vectors, double radius, boolean filled, Function3<Integer, Integer, Integer, T> data) {
|
||||
Set<IrisPosition> vset = cleanup(vectors);
|
||||
vset = getBallooned(vset, radius);
|
||||
|
||||
if (!filled) {
|
||||
vset = getHollowed(vset);
|
||||
}
|
||||
|
||||
setConsumer(vset, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set lines for points
|
||||
*
|
||||
* @param vectors the points
|
||||
* @param radius the radius
|
||||
* @param filled hollow or filled?
|
||||
* @param data the data to set
|
||||
* @param <T> the type of data to apply to the mantle
|
||||
*/
|
||||
public <T> void setNoiseMasked(List<IrisPosition> vectors, double radius, double threshold, CNG shape, Set<IrisPosition> masks, boolean filled, Function3<Integer, Integer, Integer, T> data) {
|
||||
Set<IrisPosition> vset = cleanup(vectors);
|
||||
vset = masks == null ? getBallooned(vset, radius) : getMasked(vset, masks, radius);
|
||||
vset.removeIf(p -> shape.noise(p.getX(), p.getY(), p.getZ()) < threshold);
|
||||
|
||||
if (!filled) {
|
||||
vset = getHollowed(vset);
|
||||
}
|
||||
|
||||
setConsumer(vset, data);
|
||||
}
|
||||
|
||||
private static Set<IrisPosition> getMasked(Set<IrisPosition> vectors, Set<IrisPosition> masks, double radius) {
|
||||
Set<IrisPosition> vset = new KSet<>();
|
||||
int ceil = (int) Math.ceil(radius);
|
||||
double r2 = Math.pow(radius, 2);
|
||||
|
||||
for (IrisPosition v : vectors) {
|
||||
int tipX = v.getX();
|
||||
int tipY = v.getY();
|
||||
int tipZ = v.getZ();
|
||||
|
||||
for (int x = -ceil; x <= ceil; x++) {
|
||||
for (int y = -ceil; y <= ceil; y++) {
|
||||
for (int z = -ceil; z <= ceil; z++) {
|
||||
if (hypot(x, y, z) > r2 || !masks.contains(new IrisPosition(x, y, z)))
|
||||
continue;
|
||||
vset.add(new IrisPosition(tipX + x, tipY + y, tipZ + z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vset;
|
||||
}
|
||||
|
||||
private static Set<IrisPosition> cleanup(List<IrisPosition> vectors) {
|
||||
Set<IrisPosition> vset = new KSet<>();
|
||||
|
||||
for (int i = 0; vectors.size() != 0 && i < vectors.size() - 1; i++) {
|
||||
@@ -504,13 +562,7 @@ public class MantleWriter implements IObjectPlacer, AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
vset = getBallooned(vset, radius);
|
||||
|
||||
if (!filled) {
|
||||
vset = getHollowed(vset);
|
||||
}
|
||||
|
||||
setConsumer(vset, data);
|
||||
return vset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,9 +25,11 @@ import com.volmit.iris.engine.mantle.MantleWriter;
|
||||
import com.volmit.iris.engine.object.annotations.Desc;
|
||||
import com.volmit.iris.engine.object.annotations.RegistryListResource;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.json.JSONObject;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.matter.MatterCavern;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import com.volmit.iris.util.plugin.VolmitSender;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@@ -55,6 +57,9 @@ public class IrisCave extends IrisRegistrant {
|
||||
@Desc("Limit the worm from ever getting higher or lower than this range")
|
||||
private IrisRange verticalRange = new IrisRange(3, 255);
|
||||
|
||||
@Desc("Shape of the caves")
|
||||
private IrisCaveShape shape = new IrisCaveShape();
|
||||
|
||||
@Override
|
||||
public String getFolderName() {
|
||||
return "caves";
|
||||
@@ -96,8 +101,10 @@ public class IrisCave extends IrisRegistrant {
|
||||
MatterCavern c = new MatterCavern(true, customBiome, (byte) 0);
|
||||
MatterCavern w = new MatterCavern(true, customBiome, (byte) 1);
|
||||
|
||||
writer.setLineConsumer(points,
|
||||
girth, true,
|
||||
CNG cng = shape.getNoise(rng, engine);
|
||||
KSet<IrisPosition> mask = shape.getMasked(rng, engine);
|
||||
writer.setNoiseMasked(points,
|
||||
girth, cng.noise(x, y, z), cng, mask, true,
|
||||
(xf, yf, zf) -> yf <= h ? w : c);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.annotations.Desc;
|
||||
import com.volmit.iris.engine.object.annotations.RegistryListResource;
|
||||
import com.volmit.iris.engine.object.annotations.Snippet;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.collection.KSet;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.noise.CNG;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Snippet("cave-shape")
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Desc("Cave Shape")
|
||||
@Data
|
||||
public class IrisCaveShape {
|
||||
private transient final KMap<IrisPosition, KSet<IrisPosition>> cache = new KMap<>();
|
||||
|
||||
@Desc("Noise used for the shape of the cave")
|
||||
private IrisGeneratorStyle noise = new IrisGeneratorStyle();
|
||||
@RegistryListResource(IrisObject.class)
|
||||
@Desc("Object used as mask for the shape of the cave")
|
||||
private String object = null;
|
||||
@Desc("Rotation to apply to objects before using them as mask")
|
||||
private IrisObjectRotation objectRotation = new IrisObjectRotation();
|
||||
|
||||
public CNG getNoise(RNG rng, Engine engine) {
|
||||
return noise.create(rng, engine.getData());
|
||||
}
|
||||
|
||||
public KSet<IrisPosition> getMasked(RNG rng, Engine engine) {
|
||||
if (object == null) return null;
|
||||
return cache.computeIfAbsent(new IrisPosition(
|
||||
rng.i(0, 360),
|
||||
rng.i(0, 360),
|
||||
rng.i(0, 360)),
|
||||
pos -> {
|
||||
var rotated = new KSet<IrisPosition>();
|
||||
engine.getData().getObjectLoader().load(object).getBlocks().forEach((vector, data) -> {
|
||||
if (data.getMaterial().isAir()) return;
|
||||
rotated.add(new IrisPosition(objectRotation.rotate(vector, pos.getX(), pos.getY(), pos.getZ())));
|
||||
});
|
||||
return rotated;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.volmit.iris.util.matter.IrisMatter;
|
||||
import com.volmit.iris.util.matter.Matter;
|
||||
import com.volmit.iris.util.matter.MatterSlice;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -111,9 +112,11 @@ public class MantleChunk {
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws InterruptedException {
|
||||
@SneakyThrows
|
||||
public void close() {
|
||||
closed.set(true);
|
||||
ref.acquire(Integer.MAX_VALUE);
|
||||
ref.release(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public boolean inUse() {
|
||||
@@ -123,6 +126,10 @@ public class MantleChunk {
|
||||
public MantleChunk use() {
|
||||
if (closed.get()) throw new IllegalStateException("Chunk is closed!");
|
||||
ref.acquireUninterruptibly();
|
||||
if (closed.get()) {
|
||||
ref.release();
|
||||
throw new IllegalStateException("Chunk is closed!");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -213,6 +220,7 @@ public class MantleChunk {
|
||||
* @throws IOException shit happens
|
||||
*/
|
||||
public void write(DataOutputStream dos) throws IOException {
|
||||
close();
|
||||
dos.writeByte(x);
|
||||
dos.writeByte(z);
|
||||
dos.writeByte(sections.length());
|
||||
|
||||
Reference in New Issue
Block a user