Better cave biome distribution
This commit is contained in:
parent
609381dee8
commit
df0a626420
8 changed files with 91 additions and 67 deletions
|
@ -1,14 +1,15 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.model.ArmorStandArmorModel;
|
||||
import net.minecraft.client.renderer.entity.ArmorStandRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import ru.betterend.client.render.ArmoredElytraLayer;
|
||||
|
||||
@Mixin(ArmorStandRenderer.class)
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package ru.betterend.mixin.client;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.model.HumanoidModel;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.entity.HumanoidMobRenderer;
|
||||
import net.minecraft.client.renderer.entity.MobRenderer;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import ru.betterend.client.render.ArmoredElytraLayer;
|
||||
|
||||
@Mixin(HumanoidMobRenderer.class)
|
||||
|
|
|
@ -27,6 +27,7 @@ import net.minecraft.world.level.dimension.DimensionType;
|
|||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.registry.EndBiomes;
|
||||
import ru.betterend.util.DataFixerUtil;
|
||||
import ru.betterend.util.WorldDataUtil;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
@ -46,6 +47,7 @@ public class ServerLevelMixin {
|
|||
lastWorld = session.getLevelId();
|
||||
|
||||
ServerLevel world = ServerLevel.class.cast(this);
|
||||
EndBiomes.onWorldLoad(world.getSeed());
|
||||
File dir = session.getDimensionPath(world.dimension());
|
||||
if (!new File(dir, "level.dat").exists()) {
|
||||
dir = dir.getParentFile();
|
||||
|
|
|
@ -5,7 +5,6 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
@ -58,8 +57,10 @@ import ru.betterend.world.biome.land.PaintedMountainsBiome;
|
|||
import ru.betterend.world.biome.land.ShadowForestBiome;
|
||||
import ru.betterend.world.biome.land.SulphurSpringsBiome;
|
||||
import ru.betterend.world.biome.land.UmbrellaJungleBiome;
|
||||
import ru.betterend.world.generator.BiomeMap;
|
||||
import ru.betterend.world.generator.BiomePicker;
|
||||
import ru.betterend.world.generator.BiomeType;
|
||||
import ru.betterend.world.generator.GeneratorOptions;
|
||||
|
||||
public class EndBiomes {
|
||||
private static final HashMap<ResourceLocation, EndBiome> ID_MAP = Maps.newHashMap();
|
||||
|
@ -74,6 +75,7 @@ public class EndBiomes {
|
|||
private static final JsonObject EMPTY_JSON = new JsonObject();
|
||||
|
||||
private static Registry<Biome> biomeRegistry;
|
||||
private static BiomeMap caveBiomeMap;
|
||||
|
||||
// Vanilla Land
|
||||
public static final EndBiome END = registerBiome(Biomes.THE_END, BiomeType.LAND, 1F);
|
||||
|
@ -118,6 +120,12 @@ public class EndBiomes {
|
|||
CAVE_BIOMES.rebuild();
|
||||
}
|
||||
|
||||
public static void onWorldLoad(long seed) {
|
||||
if (caveBiomeMap == null || caveBiomeMap.getSeed() != seed) {
|
||||
caveBiomeMap = new BiomeMap(seed, GeneratorOptions.getBiomeSizeCaves(), CAVE_BIOMES);
|
||||
}
|
||||
}
|
||||
|
||||
public static void mutateRegistry(Registry<Biome> biomeRegistry) {
|
||||
EndBiomes.biomeRegistry = biomeRegistry;
|
||||
|
||||
|
@ -439,8 +447,8 @@ public class EndBiomes {
|
|||
return biome;
|
||||
}
|
||||
|
||||
public static EndCaveBiome getCaveBiome(Random random) {
|
||||
return (EndCaveBiome) CAVE_BIOMES.getBiome(random);
|
||||
public static EndCaveBiome getCaveBiome(int x, int z) {
|
||||
return (EndCaveBiome) caveBiomeMap.getBiome(x, z);
|
||||
}
|
||||
|
||||
public static boolean hasBiome(ResourceLocation biomeID) {
|
||||
|
|
|
@ -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;
|
||||
|
@ -79,61 +78,62 @@ public class TunelCaveFeature extends EndCaveFeature {
|
|||
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);
|
||||
|
@ -68,6 +70,10 @@ public class GeneratorOptions {
|
|||
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