Better cave biome distribution

This commit is contained in:
paulevsGitch 2021-05-05 04:30:15 +03:00
parent 609381dee8
commit df0a626420
8 changed files with 91 additions and 67 deletions

View file

@ -51,7 +51,7 @@ public abstract class EndCaveFeature extends DefaultFeature {
return false;
}
EndCaveBiome biome = EndBiomes.getCaveBiome(random);
EndCaveBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ());
Set<BlockPos> caveBlocks = generate(world, center, radius, random);
if (!caveBlocks.isEmpty()) {
if (biome != null) {

View file

@ -1,8 +1,10 @@
package ru.betterend.world.features.terrain.caves;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import net.minecraft.core.BlockPos;
@ -21,9 +23,6 @@ import ru.betterend.util.BlocksHelper;
import ru.betterend.world.biome.cave.EndCaveBiome;
public class TunelCaveFeature extends EndCaveFeature {
private static final OpenSimplexNoise BIOME_NOISE_X = new OpenSimplexNoise("biome_noise_x".hashCode());
private static final OpenSimplexNoise BIOME_NOISE_Z = new OpenSimplexNoise("biome_noise_z".hashCode());
private Set<BlockPos> generate(WorldGenLevel world, BlockPos center, Random random) {
int cx = center.getX() >> 4;
int cz = center.getZ() >> 4;
@ -78,62 +77,63 @@ public class TunelCaveFeature extends EndCaveFeature {
if (biomeMissingCaves(world, pos)) {
return false;
}
EndCaveBiome biome = EndBiomes.getCaveBiome(random);
Set<BlockPos> preCaveBlocks = generate(world, pos, random);
Set<BlockPos> caveBlocks = mutateBlocks(preCaveBlocks);
if (!caveBlocks.isEmpty()) {
if (biome != null) {
setBiomes(world, biome, caveBlocks);
Set<BlockPos> floorPositions = Sets.newHashSet();
Set<BlockPos> ceilPositions = Sets.newHashSet();
MutableBlockPos mut = new MutableBlockPos();
Set<BlockPos> remove = Sets.newHashSet();
caveBlocks.forEach((bpos) -> {
mut.set(bpos);
int height = world.getHeight(Types.WORLD_SURFACE, bpos.getX(), bpos.getZ());
if (mut.getY() >= height) {
remove.add(bpos);
}
else if (world.getBlockState(mut).getMaterial().isReplaceable()) {
mut.setY(bpos.getY() - 1);
if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) {
floorPositions.add(mut.immutable());
}
mut.setY(bpos.getY() + 1);
if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) {
ceilPositions.add(mut.immutable());
}
}
});
BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial();
placeFloor(world, biome, floorPositions, random, surfaceBlock);
placeCeil(world, biome, ceilPositions, random);
caveBlocks.removeAll(remove);
placeWalls(world, biome, caveBlocks, random);
}
fixBlocks(world, preCaveBlocks);
Set<BlockPos> caveBlocks = generate(world, pos, random);
if (caveBlocks.isEmpty()) {
return false;
}
return true;
}
private Set<BlockPos> mutateBlocks(Set<BlockPos> caveBlocks) {
Set<BlockPos> result = Sets.newHashSet();
caveBlocks.forEach(pos -> {
int dx = pos.getX() + Mth.floor(BIOME_NOISE_X.eval(pos.getX() * 0.1, pos.getZ() * 0.1) * 3);
int dz = pos.getZ() + Mth.floor(BIOME_NOISE_Z.eval(pos.getX() * 0.1, pos.getZ() * 0.1) * 3);
if (dx >> 4 == pos.getX() >> 4 && dz >> 4 == pos.getZ() >> 4) {
int cx = ((pos.getX() >> 4) << 4) | 8;
int cz = ((pos.getZ() >> 4) << 4) | 8;
dx = pos.getX() - cx;
dz = pos.getZ() - cz;
if (dx * dx + dz * dz < 64) {
result.add(pos);
Map<EndCaveBiome, Set<BlockPos>> floorSets = Maps.newHashMap();
Map<EndCaveBiome, Set<BlockPos>> ceilSets = Maps.newHashMap();
MutableBlockPos mut = new MutableBlockPos();
Set<BlockPos> remove = Sets.newHashSet();
caveBlocks.forEach((bpos) -> {
mut.set(bpos);
EndCaveBiome bio = EndBiomes.getCaveBiome(bpos.getX(), bpos.getZ());
int height = world.getHeight(Types.WORLD_SURFACE, bpos.getX(), bpos.getZ());
if (mut.getY() >= height) {
remove.add(bpos);
}
else if (world.getBlockState(mut).getMaterial().isReplaceable()) {
mut.setY(bpos.getY() - 1);
if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) {
Set<BlockPos> floorPositions = floorSets.get(bio);
if (floorPositions == null) {
floorPositions = Sets.newHashSet();
floorSets.put(bio, floorPositions);
}
floorPositions.add(mut.immutable());
}
mut.setY(bpos.getY() + 1);
if (world.getBlockState(mut).is(EndTags.GEN_TERRAIN)) {
Set<BlockPos> ceilPositions = ceilSets.get(bio);
if (ceilPositions == null) {
ceilPositions = Sets.newHashSet();
ceilSets.put(bio, ceilPositions);
}
ceilPositions.add(mut.immutable());
}
setBiome(world, bpos, bio);
}
});
return result;
caveBlocks.removeAll(remove);
if (caveBlocks.isEmpty()) {
return true;
}
floorSets.forEach((biome, floorPositions) -> {
BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceBuilderConfig().getTopMaterial();
placeFloor(world, biome, floorPositions, random, surfaceBlock);
});
ceilSets.forEach((biome, ceilPositions) -> {
placeCeil(world, biome, ceilPositions, random);
});
EndCaveBiome biome = EndBiomes.getCaveBiome(pos.getX(), pos.getZ());
placeWalls(world, biome, caveBlocks, random);
fixBlocks(world, caveBlocks);
return true;
}
@Override

View file

@ -20,6 +20,7 @@ public class BiomeMap {
private final OpenSimplexNoise noiseX;
private final OpenSimplexNoise noiseZ;
private final BiomePicker picker;
private final long seed;
public BiomeMap(long seed, int size, BiomePicker picker) {
maps.clear();
@ -30,6 +31,11 @@ public class BiomeMap {
depth = (int) Math.ceil(Math.log(size) / Math.log(2)) - 2;
this.size = 1 << depth;
this.picker = picker;
this.seed = seed;
}
public long getSeed() {
return seed;
}
public void clearCache() {

View file

@ -7,6 +7,7 @@ import ru.betterend.config.Configs;
public class GeneratorOptions {
private static int biomeSizeLand;
private static int biomeSizeVoid;
private static int biomeSizeCaves;
private static boolean hasPortal;
private static boolean hasPillars;
private static boolean hasDragonFights;
@ -33,6 +34,7 @@ public class GeneratorOptions {
public static void init() {
biomeSizeLand = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeLand", 256);
biomeSizeVoid = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeVoid", 256);
biomeSizeCaves = Configs.GENERATOR_CONFIG.getInt("biomeMap", "biomeSizeCaves", 32);
hasPortal = Configs.GENERATOR_CONFIG.getBoolean("portal", "hasPortal", true);
hasPillars = Configs.GENERATOR_CONFIG.getBoolean("spikes", "hasSpikes", true);
hasDragonFights = Configs.GENERATOR_CONFIG.getBooleanRoot("hasDragonFights", true);
@ -67,6 +69,10 @@ public class GeneratorOptions {
public static int getBiomeSizeVoid() {
return Mth.clamp(biomeSizeVoid, 1, 8192);
}
public static int getBiomeSizeCaves() {
return Mth.clamp(biomeSizeCaves, 1, 8192);
}
public static boolean hasPortal() {
return hasPortal;