Better cave biome distribution
This commit is contained in:
parent
609381dee8
commit
df0a626420
8 changed files with 91 additions and 67 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue