feat: worldgen improvements
This commit is contained in:
parent
1b736b5e31
commit
b1b243fd1c
@ -1,5 +1,5 @@
|
||||
|
||||
minestom_version = d0754f2a15
|
||||
minestom_version = e8f34c317a
|
||||
minestompvp_version = 547b6e95af
|
||||
vri_version = a79a2d9422
|
||||
jnoise_version = 5.0.0-SNAPSHOT
|
||||
|
@ -30,7 +30,11 @@ public class EventHandler {
|
||||
public static void onPlayerConfiguration(AsyncPlayerConfigurationEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
event.setSpawningInstance(Main.overworld);
|
||||
player.setRespawnPoint(new Pos(0, 42, 0));
|
||||
int y = 200;
|
||||
while (Main.overworld.getBlock(0, y, 0) == Block.AIR) {
|
||||
y--;
|
||||
}
|
||||
player.setRespawnPoint(new Pos(0, y, 0));
|
||||
};
|
||||
|
||||
public static void onPlayerDeath(EntityPreDeathEvent event) {
|
||||
|
@ -6,6 +6,8 @@ import dev.ninjdai.werewolf.commands.PlayerKillCommand;
|
||||
import dev.ninjdai.werewolf.gui.Gui;
|
||||
import dev.ninjdai.werewolf.uhc.UHCPlayer;
|
||||
import dev.ninjdai.werewolf.worldgen.LGGenerator;
|
||||
import dev.ninjdai.werewolf.worldgen.LGTerrainBuilder;
|
||||
import dev.ninjdai.werewolf.worldgen.TerrainBuilder;
|
||||
import io.github.togar2.pvp.MinestomPvP;
|
||||
import io.github.togar2.pvp.feature.CombatFeatureSet;
|
||||
import io.github.togar2.pvp.feature.CombatFeatures;
|
||||
@ -33,8 +35,8 @@ public class Main {
|
||||
|
||||
//VanillaReimplementation vri = VanillaReimplementation.hook(MinecraftServer.process());
|
||||
|
||||
overworld.setGenerator(LGGenerator::generate);
|
||||
overworld.setChunkSupplier(LightingChunk::new);
|
||||
overworld.setGenerator(new LGGenerator(new LGTerrainBuilder(3301)));
|
||||
|
||||
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
||||
EventHandler.register(globalEventHandler);
|
||||
@ -50,6 +52,8 @@ public class Main {
|
||||
|
||||
MinecraftServer.getConnectionManager().setPlayerProvider(UHCPlayer::new);
|
||||
|
||||
overworld.loadChunk(0, 0);
|
||||
|
||||
OpenToLAN.open();
|
||||
MinecraftServer.setBrandName("Playground");
|
||||
//VelocityProxy.enable("cMkrrJ8tdUS6");
|
||||
|
@ -0,0 +1,68 @@
|
||||
package dev.ninjdai.werewolf.worldgen;
|
||||
|
||||
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||
import de.articdive.jnoise.modules.octavation.fractal_functions.FractalFunction;
|
||||
import de.articdive.jnoise.pipeline.JNoise;
|
||||
import dev.ninjdai.werewolf.worldgen.utils.AbsClampNoiseModifier;
|
||||
import net.minestom.vanilla.datapack.worldgen.math.SplineInterpolator;
|
||||
|
||||
public enum InterpolatedNoises {
|
||||
CONTINENTALNESS(
|
||||
JNoise.newBuilder()
|
||||
.fastSimplex(FastSimplexNoiseGenerator.newBuilder()
|
||||
.setSeed(0)
|
||||
.build())
|
||||
.octavate(5, 0.5, 2.2, FractalFunction.FBM, false)
|
||||
.scale(0.002)
|
||||
.addModifier(new AbsClampNoiseModifier())
|
||||
.build(),
|
||||
new SplineInterpolatorBuilder()
|
||||
.add(0.0, 0.0)
|
||||
.add(0.25, 0.1)
|
||||
.add(0.285, 0.38)
|
||||
.add(0.3, 0.444)
|
||||
.add(0.39, 0.666)
|
||||
.add(0.433, 0.777)
|
||||
.add(0.5, 0.888)
|
||||
.add(0.7, 0.97)
|
||||
.add(1, 1)
|
||||
.build()
|
||||
),
|
||||
EROSION(
|
||||
JNoise.newBuilder()
|
||||
.fastSimplex(FastSimplexNoiseGenerator.newBuilder()
|
||||
.setSeed(0)
|
||||
.build())
|
||||
.octavate(5, 0.3, 3, FractalFunction.FBM, false)
|
||||
.scale(0.0015)
|
||||
.invert()
|
||||
.addModifier(new AbsClampNoiseModifier())
|
||||
.build(),
|
||||
new SplineInterpolatorBuilder()
|
||||
.add(0, 0)
|
||||
.add(0.1, 0.3)
|
||||
.add(0.5, 0.9)
|
||||
.add(0.6, 0.91)
|
||||
.add(0.62, 0.7)
|
||||
.add(0.7, 0.71)
|
||||
.add(0.72, 0.91)
|
||||
.add(1, 1)
|
||||
.build()
|
||||
);
|
||||
|
||||
final private JNoise noise;
|
||||
final private SplineInterpolator interpolator;
|
||||
|
||||
InterpolatedNoises(JNoise noise, SplineInterpolator interpolator) {
|
||||
this.noise = noise;
|
||||
this.interpolator = interpolator;
|
||||
}
|
||||
|
||||
public double evaluateNoise(int x, int z) {
|
||||
return interpolator.interpolate(noise.evaluateNoise(x, z));
|
||||
}
|
||||
|
||||
double evaluateNoise(int x, int y, int z) {
|
||||
return interpolator.interpolate(noise.evaluateNoise(x, y, z));
|
||||
}
|
||||
}
|
@ -1,39 +1,89 @@
|
||||
package dev.ninjdai.werewolf.worldgen;
|
||||
|
||||
import de.articdive.jnoise.core.api.functions.Interpolation;
|
||||
import de.articdive.jnoise.core.api.modifiers.NoiseModifier;
|
||||
import de.articdive.jnoise.generators.noise_parameters.fade_functions.FadeFunction;
|
||||
import de.articdive.jnoise.modifiers.clamp.ClampModifier;
|
||||
import de.articdive.jnoise.modules.octavation.fractal_functions.FractalFunction;
|
||||
import de.articdive.jnoise.pipeline.JNoise;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.generator.GenerationUnit;
|
||||
import net.minestom.server.instance.generator.Generator;
|
||||
import net.minestom.server.world.biome.Biome;
|
||||
import net.minestom.vanilla.generation.VanillaWorldGenerationFeature;
|
||||
import net.minestom.vanilla.tag.Tags;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LGGenerator {
|
||||
static final JNoise noise1 = JNoise.newBuilder()
|
||||
.perlin(3301, Interpolation.LINEAR, FadeFunction.QUINTIC_POLY)
|
||||
.scale(1/48.0)
|
||||
.addModifier(v -> (v + 1) / 2.0)
|
||||
.clamp(0.0, 1.0)
|
||||
.octavate(3, 0.5, .75, FractalFunction.TURBULENCE, true)
|
||||
.build();
|
||||
import java.util.Random;
|
||||
|
||||
public static void generate(@NotNull GenerationUnit unit) {
|
||||
Point start = unit.absoluteStart();
|
||||
for (int x = 0; x < unit.size().x(); x++) {
|
||||
for (int z = 0; z < unit.size().z(); z++) {
|
||||
Point bottom = start.add(x, 0, z);
|
||||
public class LGGenerator implements Generator {
|
||||
TerrainBuilder terrainBuilder;
|
||||
Random random;
|
||||
double densityThreshold = 1;//0.6;
|
||||
int upperRelativeDensityLimit = 50;
|
||||
int lowerRelativeDensityLimit = 50;
|
||||
|
||||
synchronized (noise1) {
|
||||
double height = noise1.evaluateNoise(bottom.x(), bottom.z()) * 16 + 20;
|
||||
// * 16 means the height will be between -16 and +16
|
||||
unit.modifier().fill(bottom, bottom.add(1, 0, 1).withY(height), Block.STONE);
|
||||
unit.modifier().fill(bottom.withY(height), bottom.add(1, 0, 1).withY(height+3), Block.DIRT);
|
||||
unit.modifier().fill(bottom.withY(height+3), bottom.add(1, 0, 1).withY(height+4), Block.GRASS_BLOCK);
|
||||
}
|
||||
public LGGenerator(TerrainBuilder tb) {
|
||||
this.terrainBuilder = tb;
|
||||
this.random = new Random(tb.seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(@NotNull GenerationUnit unit) {
|
||||
final Point min = unit.absoluteStart();
|
||||
final Point max = unit.absoluteEnd();
|
||||
|
||||
for (int x = min.blockX(); x < max.blockX(); x++) {
|
||||
for (int z = min.blockZ(); z < max.blockZ(); z++) {
|
||||
generate3D(min, max, x, z, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generate3D(Point min, Point max, int x, int z, GenerationUnit unit) {
|
||||
int height = terrainBuilder.getSurfaceHeight(x, z);
|
||||
int upperDensityLimit = height + upperRelativeDensityLimit;
|
||||
int lowerDensityLimit = height - lowerRelativeDensityLimit;
|
||||
int terrainHeight = lowerDensityLimit;
|
||||
|
||||
for (int y = upperDensityLimit; y >= lowerDensityLimit; y--) {
|
||||
if (y == lowerDensityLimit) {
|
||||
unit.modifier().fill(min.withX(x).withZ(z), new Vec(x + 1, lowerDensityLimit + 1, z + 1), Block.STONE);
|
||||
break;
|
||||
}
|
||||
|
||||
Vec pos = new Vec(x, y, z);
|
||||
if (terrainBuilder.getDensity(x, y, z) > densityThreshold) {
|
||||
unit.modifier().setBlock(pos, Block.STONE);
|
||||
terrainHeight = Math.max(terrainHeight, y);
|
||||
}
|
||||
}
|
||||
decorate(x, terrainHeight, z, unit);
|
||||
}
|
||||
|
||||
private void decorate(int x, int y, int z, GenerationUnit unit) {
|
||||
unit.modifier().setBlock(x, y + 4, z, Block.GRASS_BLOCK);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Block b = switch ((int) (2*Noises.FEATURES.evaluateNoise(x, y+i, z))) {
|
||||
case 0 -> Block.COARSE_DIRT;
|
||||
case 1 -> Block.ROOTED_DIRT;
|
||||
default -> Block.DIRT;
|
||||
};
|
||||
unit.modifier().setBlock(x, y + i, z, b);
|
||||
}
|
||||
int ry = y+5;
|
||||
double ft = Noises.FEATURES.evaluateNoise(x, z);
|
||||
if (ft > 0.995) {
|
||||
int height = (int) (3 + 3*Noises.FEATURES.evaluateNoise(x, y, z));
|
||||
|
||||
GenerationUnit fork = unit.fork(new Vec(x-2, ry, z-2), new Vec(x+3, ry+height+4, z+3));
|
||||
fork.modifier().fill(new Vec(x, ry, z), new Vec(x+1, ry+height, z+1), Block.OAK_LOG);
|
||||
fork.modifier().fill(new Vec(x-2, ry+height, z-2), new Vec(x+3, ry+height+2, z+3), Block.OAK_LEAVES);
|
||||
fork.modifier().fill(new Vec(x-1, ry+height+2, z-1), new Vec(x+2, ry+height+3, z+2), Block.OAK_LEAVES);
|
||||
} else if (ft > 0.95) {
|
||||
unit.modifier().setBlock(x, ry, z, Block.TALL_GRASS);
|
||||
unit.modifier().setBlock(x, ry+1, z, Block.TALL_GRASS.withProperty("half", "upper"));
|
||||
} else if (ft > 0.8) {
|
||||
unit.modifier().setBlock(x, ry, z, Block.SHORT_GRASS);
|
||||
} else if (ft < -0.99) {
|
||||
unit.modifier().setBlock(x, ry, z, Block.POPPY);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package dev.ninjdai.werewolf.worldgen;
|
||||
|
||||
public class LGTerrainBuilder extends TerrainBuilder {
|
||||
// 0: no squashing the terrain, 1: basically the surface height
|
||||
private final double squashingFactor = 1.5;
|
||||
|
||||
|
||||
public LGTerrainBuilder(long seed) {
|
||||
super(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSurfaceHeight(int x, int z) {
|
||||
double continentalness = InterpolatedNoises.CONTINENTALNESS.evaluateNoise(x, z);
|
||||
double erosion = InterpolatedNoises.EROSION.evaluateNoise(x, z);
|
||||
|
||||
return (int) ((continentalness + erosion) * 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDensity(int x, int y, int z) {
|
||||
double density = Noises.DENSITY.evaluateNoise(x, y, z);
|
||||
int surfaceHeight = getSurfaceHeight(x, z);
|
||||
|
||||
density *= (double) surfaceHeight / y;
|
||||
|
||||
return density;
|
||||
}
|
||||
}
|
45
src/main/java/dev/ninjdai/werewolf/worldgen/Noises.java
Normal file
45
src/main/java/dev/ninjdai/werewolf/worldgen/Noises.java
Normal file
@ -0,0 +1,45 @@
|
||||
package dev.ninjdai.werewolf.worldgen;
|
||||
|
||||
import de.articdive.jnoise.generators.noisegen.opensimplex.FastSimplexNoiseGenerator;
|
||||
import de.articdive.jnoise.generators.noisegen.random.white.WhiteNoiseGenerator;
|
||||
import de.articdive.jnoise.modules.octavation.fractal_functions.FractalFunction;
|
||||
import de.articdive.jnoise.pipeline.JNoise;
|
||||
import dev.ninjdai.werewolf.worldgen.utils.AbsClampNoiseModifier;
|
||||
|
||||
public enum Noises {
|
||||
WEIRDNESS(JNoise.newBuilder()
|
||||
.fastSimplex(FastSimplexNoiseGenerator.newBuilder()
|
||||
.setSeed(0)
|
||||
.build())
|
||||
.octavate(5, 0.5, 1.2, FractalFunction.FBM, false)
|
||||
.scale(0.005)
|
||||
.addModifier(new AbsClampNoiseModifier())
|
||||
.build()),
|
||||
DENSITY(JNoise.newBuilder()
|
||||
.fastSimplex(FastSimplexNoiseGenerator.newBuilder()
|
||||
.setSeed(0)
|
||||
.build())
|
||||
.octavate(5, 0.7, 1.6, FractalFunction.FBM, true)
|
||||
.scale(0.006)
|
||||
.addModifier(new AbsClampNoiseModifier())
|
||||
.build()),
|
||||
|
||||
FEATURES(JNoise.newBuilder()
|
||||
.white(WhiteNoiseGenerator.newBuilder().setSeed(0).build())
|
||||
.addModifier(new AbsClampNoiseModifier())
|
||||
.build());
|
||||
|
||||
final private JNoise noise;
|
||||
|
||||
Noises(JNoise noise) {
|
||||
this.noise = noise;
|
||||
}
|
||||
|
||||
public double evaluateNoise(int x, int z) {
|
||||
return noise.evaluateNoise(x, z);
|
||||
}
|
||||
|
||||
public double evaluateNoise(int x, int y, int z) {
|
||||
return noise.evaluateNoise(x, y, z);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package dev.ninjdai.werewolf.worldgen;
|
||||
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleList;
|
||||
import net.minestom.vanilla.datapack.worldgen.math.SplineInterpolator;
|
||||
|
||||
public class SplineInterpolatorBuilder {
|
||||
private DoubleList xList;
|
||||
private DoubleList yList;
|
||||
|
||||
SplineInterpolatorBuilder() {
|
||||
this.xList = new DoubleArrayList();
|
||||
this.yList = new DoubleArrayList();
|
||||
}
|
||||
|
||||
public SplineInterpolatorBuilder add(double x, double y) {
|
||||
this.xList.add(x);
|
||||
this.yList.add(y);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SplineInterpolator build() {
|
||||
return SplineInterpolator.createMonotoneCubicSpline(xList, yList);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package dev.ninjdai.werewolf.worldgen;
|
||||
|
||||
public abstract class TerrainBuilder {
|
||||
long seed;
|
||||
|
||||
TerrainBuilder(long seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
abstract int getSurfaceHeight(int x, int z);
|
||||
abstract double getDensity(int x, int y, int z);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package dev.ninjdai.werewolf.worldgen.utils;
|
||||
|
||||
import de.articdive.jnoise.core.api.modifiers.NoiseModifier;
|
||||
|
||||
public class AbsClampNoiseModifier implements NoiseModifier {
|
||||
@Override
|
||||
public double apply(double result) {
|
||||
return (result + 1) * 0.5;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user