mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
Carver go brrrr
This commit is contained in:
@@ -35,7 +35,7 @@ val versionObj = Version("2", "0", "0", true)
|
||||
version = versionObj
|
||||
|
||||
dependencies {
|
||||
val gaeaVersion = "1.14.4"
|
||||
val gaeaVersion = "1.15.0"
|
||||
compileOnly(name = "Gaea-${gaeaVersion}", group = "")
|
||||
testImplementation(name = "Gaea-${gaeaVersion}", group = "")
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1,85 +0,0 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.math.FastNoiseLite;
|
||||
import org.polydev.gaea.world.carving.Carver;
|
||||
import org.polydev.gaea.world.carving.CarvingData;
|
||||
import org.polydev.gaea.world.carving.Worm;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class SimplexCarver extends Carver {
|
||||
private final FastNoiseLite noise;
|
||||
private final FastNoiseLite height;
|
||||
private final FastNoiseLite column;
|
||||
private final FastNoiseLite hasCaves;
|
||||
private final double root2inverse = 1D / FastMath.sqrt(2);
|
||||
|
||||
public SimplexCarver(int minY, int maxY) {
|
||||
super(minY, maxY);
|
||||
noise = new FastNoiseLite(2403);
|
||||
noise.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
noise.setFractalType(FastNoiseLite.FractalType.FBm);
|
||||
noise.setFractalOctaves(3);
|
||||
noise.setFrequency(0.02f);
|
||||
|
||||
height = new FastNoiseLite(2404);
|
||||
height.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
height.setFrequency(0.01f);
|
||||
|
||||
column = new FastNoiseLite(2404);
|
||||
column.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
column.setFractalType(FastNoiseLite.FractalType.FBm);
|
||||
column.setFractalOctaves(5);
|
||||
column.setFrequency(0.05f);
|
||||
|
||||
hasCaves = new FastNoiseLite(2405);
|
||||
hasCaves.setNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
hasCaves.setFrequency(0.005f);
|
||||
}
|
||||
|
||||
private static double acot(double x) {
|
||||
return FastMath.PI / 2 - FastMath.atan(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarvingData carve(int chunkX, int chunkZ, World w) {
|
||||
CarvingData c = new CarvingData(chunkX, chunkZ);
|
||||
int ox = chunkX << 4;
|
||||
int oz = chunkZ << 4;
|
||||
for(int x = ox; x < ox + 16; x++) {
|
||||
for(int z = oz; z < oz + 16; z++) {
|
||||
double heightNoise = height.getNoise(x, z);
|
||||
double mainNoise = noise.getNoise(x, z) * 2;
|
||||
double columnNoise = FastMath.pow(FastMath.max(column.getNoise(x, z), 0) * 2, 3);
|
||||
double hc = (acot(16 * (hasCaves.getNoise(x, z) - 0.2)) / FastMath.PI) - 0.1;
|
||||
CarvingData.CarvingType type = CarvingData.CarvingType.BOTTOM;
|
||||
double simplex = (FastMath.pow(mainNoise + root2inverse, 3) / 2 + columnNoise) * hc;
|
||||
for(int y = 0; y < 64; y++) {
|
||||
double finalNoise = (-0.05 * FastMath.abs(y - (heightNoise * 16 + 24)) + 1 - simplex) * hc;
|
||||
if(finalNoise > 0.5) {
|
||||
c.carve(x - ox, y, z - oz, type);
|
||||
double finalNoiseUp = (-0.05 * FastMath.abs((y + 1) - (heightNoise * 16 + 24)) + 1 - simplex) * hc;
|
||||
if(finalNoiseUp > 0.5) {
|
||||
type = CarvingData.CarvingType.CENTER;
|
||||
} else type = CarvingData.CarvingType.TOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Worm getWorm(long l, Vector vector) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkCarved(World world, int i, int i1, Random random) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,13 @@ import com.dfsek.terra.config.templates.CarverTemplate;
|
||||
import net.jafama.FastMath;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.polydev.gaea.biome.Biome;
|
||||
import org.polydev.gaea.generation.GenerationPhase;
|
||||
import org.polydev.gaea.math.MathUtil;
|
||||
import org.polydev.gaea.math.Range;
|
||||
import org.polydev.gaea.util.FastRandom;
|
||||
import org.polydev.gaea.util.GlueList;
|
||||
import org.polydev.gaea.world.carving.Carver;
|
||||
import org.polydev.gaea.world.carving.CarvingData;
|
||||
import org.polydev.gaea.world.carving.Worm;
|
||||
import parsii.eval.Expression;
|
||||
import parsii.eval.Parser;
|
||||
@@ -24,6 +24,7 @@ import parsii.tokenizer.ParseException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class UserDefinedCarver extends Carver {
|
||||
private final double[] start; // 0, 1, 2 = x, y, z.
|
||||
@@ -82,11 +83,11 @@ public class UserDefinedCarver extends Carver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarvingData carve(int chunkX, int chunkZ, World w) {
|
||||
CarvingData data = new CarvingData(chunkX, chunkZ);
|
||||
public void carve(int chunkX, int chunkZ, World w, BiConsumer<Vector, CarvingType> consumer) {
|
||||
int carvingRadius = getCarvingRadius();
|
||||
TerraBiomeGrid grid = TerraWorld.getWorld(w).getGrid();
|
||||
for(int x = chunkX - carvingRadius; x <= chunkX + carvingRadius; x++) {
|
||||
z:
|
||||
for(int z = chunkZ - carvingRadius; z <= chunkZ + carvingRadius; z++) {
|
||||
if(isChunkCarved(w, x, z, new FastRandom(MathUtil.hashToLong(this.getClass().getName() + "_" + x + "&" + z)))) {
|
||||
long seed = MathUtil.getCarverChunkSeed(x, z, w.getSeed());
|
||||
@@ -94,24 +95,20 @@ public class UserDefinedCarver extends Carver {
|
||||
Worm carving = getWorm(seed, new Vector((x << 4) + r.nextInt(16), height.get(r), (z << 4) + r.nextInt(16)));
|
||||
Vector origin = carving.getOrigin();
|
||||
List<Worm.WormPoint> points = new GlueList<>();
|
||||
boolean v = true;
|
||||
for(int i = 0; i < carving.getLength(); i++) {
|
||||
if((i & 1) == 0 // This check is laggy. Do it every other step.
|
||||
&& !((UserDefinedBiome) grid.getBiome(carving.getRunning().toLocation(w), GenerationPhase.POPULATE)).getConfig().getCarvers().containsKey(this)) { // Stop if we enter a biome this carver is not present in
|
||||
v = false;
|
||||
break;
|
||||
}
|
||||
carving.step();
|
||||
if(carving.getRunning().clone().setY(0).distanceSquared(origin.clone().setY(0)) > sixtyFourSq) break;
|
||||
Biome biome = grid.getBiome(carving.getRunning().toLocation(w), GenerationPhase.POPULATE);
|
||||
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(this)) { // Stop if we enter a biome this carver is not present in
|
||||
continue z;
|
||||
}
|
||||
if(FastMath.floorDiv(origin.getBlockX(), 16) != chunkX && FastMath.floorDiv(origin.getBlockZ(), 16) != chunkZ)
|
||||
continue;
|
||||
points.add(carving.getPoint());
|
||||
}
|
||||
if(v) points.forEach(point -> point.carve(data, chunkX, chunkZ));
|
||||
points.forEach(point -> point.carve(chunkX, chunkZ, consumer));
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setRecalcMagnitude(double recalcMagnitude) {
|
||||
|
||||
@@ -14,10 +14,9 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.polydev.gaea.profiler.ProfileFuture;
|
||||
import org.polydev.gaea.world.carving.CarvingData;
|
||||
import org.polydev.gaea.world.carving.Carver;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -32,7 +31,6 @@ public class CavePopulator extends BlockPopulator {
|
||||
@SuppressWarnings("try")
|
||||
@Override
|
||||
public void populate(@NotNull World world, @NotNull Random r, @NotNull Chunk chunk) {
|
||||
//if(ConfigUtil.masterDisableCaves) return;
|
||||
try(ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("CaveTime")) {
|
||||
Random random = PopulationUtil.getRandom(chunk);
|
||||
TerraWorld tw = TerraWorld.getWorld(world);
|
||||
@@ -43,25 +41,22 @@ public class CavePopulator extends BlockPopulator {
|
||||
CarverTemplate template = c.getConfig();
|
||||
Map<Location, Material> shiftCandidate = new HashMap<>();
|
||||
Set<Block> updateNeeded = new HashSet<>();
|
||||
Map<Vector, CarvingData.CarvingType> blocks = c.carve(chunk.getX(), chunk.getZ(), world).getCarvedBlocks();
|
||||
for(Map.Entry<Vector, CarvingData.CarvingType> e : blocks.entrySet()) {
|
||||
|
||||
Vector v = e.getKey();
|
||||
c.carve(chunk.getX(), chunk.getZ(), world, (v, type) -> {
|
||||
Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
|
||||
Material m = b.getType();
|
||||
if(e.getValue().equals(CarvingData.CarvingType.CENTER) && template.getInner().canReplace(m)) {
|
||||
if(type.equals(Carver.CarvingType.CENTER) && template.getInner().canReplace(m)) {
|
||||
if(template.getShift().containsKey(b.getType()))
|
||||
shiftCandidate.put(b.getLocation(), b.getType());
|
||||
b.setBlockData(template.getInner().get(v.getBlockY()).get(random), false);
|
||||
} else if(e.getValue().equals(CarvingData.CarvingType.WALL) && template.getOuter().canReplace(m)) {
|
||||
} else if(type.equals(Carver.CarvingType.WALL) && template.getOuter().canReplace(m)) {
|
||||
if(template.getShift().containsKey(b.getType()))
|
||||
shiftCandidate.put(b.getLocation(), b.getType());
|
||||
b.setBlockData(template.getOuter().get(v.getBlockY()).get(random), false);
|
||||
} else if(e.getValue().equals(CarvingData.CarvingType.TOP) && template.getTop().canReplace(m)) {
|
||||
} else if(type.equals(Carver.CarvingType.TOP) && template.getTop().canReplace(m)) {
|
||||
if(template.getShift().containsKey(b.getType()))
|
||||
shiftCandidate.put(b.getLocation(), b.getType());
|
||||
b.setBlockData(template.getTop().get(v.getBlockY()).get(random), false);
|
||||
} else if(e.getValue().equals(CarvingData.CarvingType.BOTTOM) && template.getBottom().canReplace(m)) {
|
||||
} else if(type.equals(Carver.CarvingType.BOTTOM) && template.getBottom().canReplace(m)) {
|
||||
if(template.getShift().containsKey(b.getType()))
|
||||
shiftCandidate.put(b.getLocation(), b.getType());
|
||||
b.setBlockData(template.getBottom().get(v.getBlockY()).get(random), false);
|
||||
@@ -69,7 +64,7 @@ public class CavePopulator extends BlockPopulator {
|
||||
if(template.getUpdate().contains(m)) {
|
||||
updateNeeded.add(b);
|
||||
}
|
||||
}
|
||||
});
|
||||
for(Map.Entry<Location, Material> entry : shiftCandidate.entrySet()) {
|
||||
Location l = entry.getKey();
|
||||
Location mut = l.clone();
|
||||
|
||||
Reference in New Issue
Block a user