From 6b846b5bb7f456157256284a67babaa03d648756 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Sun, 18 Oct 2020 22:19:07 +0300 Subject: [PATCH] Dust Wastelands & Megalakes --- .../ru/betterend/registry/BiomeRegistry.java | 4 + .../betterend/registry/BlockTagRegistry.java | 1 + .../betterend/registry/FeatureRegistry.java | 6 + .../betterend/registry/StructureRegistry.java | 2 + .../java/ru/betterend/util/BlocksHelper.java | 13 +- .../world/biome/BiomeDustWastelands.java | 22 +++ .../betterend/world/biome/BiomeMegalake.java | 21 +++ .../features/StructureMegaLake.java | 41 ++++ .../world/structures/piece/LakePiece.java | 178 ++++++++++++++++++ .../assets/betterend/lang/en_us.json | 2 + .../assets/betterend/lang/ru_ru.json | 2 + 11 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/betterend/world/biome/BiomeDustWastelands.java create mode 100644 src/main/java/ru/betterend/world/biome/BiomeMegalake.java create mode 100644 src/main/java/ru/betterend/world/structures/features/StructureMegaLake.java create mode 100644 src/main/java/ru/betterend/world/structures/piece/LakePiece.java diff --git a/src/main/java/ru/betterend/registry/BiomeRegistry.java b/src/main/java/ru/betterend/registry/BiomeRegistry.java index e4b65660..f31d0c07 100644 --- a/src/main/java/ru/betterend/registry/BiomeRegistry.java +++ b/src/main/java/ru/betterend/registry/BiomeRegistry.java @@ -13,7 +13,9 @@ import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome.Category; import net.minecraft.world.biome.BiomeKeys; import ru.betterend.world.biome.BiomeChorusForest; +import ru.betterend.world.biome.BiomeDustWastelands; import ru.betterend.world.biome.BiomeFoggyMushroomland; +import ru.betterend.world.biome.BiomeMegalake; import ru.betterend.world.biome.EndBiome; import ru.betterend.world.generator.BiomePicker; import ru.betterend.world.generator.BiomeType; @@ -32,6 +34,8 @@ public class BiomeRegistry { public static final EndBiome SMALL_END_ISLANDS = registerBiome(BiomeKeys.SMALL_END_ISLANDS, BiomeType.VOID, true); public static final EndBiome FOGGY_MUSHROOMLAND = registerBiome(new BiomeFoggyMushroomland(), BiomeType.LAND); public static final EndBiome CHORUS_FOREST = registerBiome(new BiomeChorusForest(), BiomeType.LAND); + public static final EndBiome DUST_WASTELANDS = registerBiome(new BiomeDustWastelands(), BiomeType.LAND); + public static final EndBiome MEGALAKE = registerBiome(new BiomeMegalake(), BiomeType.LAND); public static void register() {} diff --git a/src/main/java/ru/betterend/registry/BlockTagRegistry.java b/src/main/java/ru/betterend/registry/BlockTagRegistry.java index b0fe1891..24e2ead4 100644 --- a/src/main/java/ru/betterend/registry/BlockTagRegistry.java +++ b/src/main/java/ru/betterend/registry/BlockTagRegistry.java @@ -23,6 +23,7 @@ public class BlockTagRegistry { addSurfaceBlock(BlockRegistry.END_MOSS); addSurfaceBlock(BlockRegistry.END_MYCELIUM); addSurfaceBlock(BlockRegistry.CHORUS_NYLIUM); + addSurfaceBlock(BlockRegistry.ENDSTONE_DUST); TagHelper.addTag(GEN_TERRAIN, BlockRegistry.ENDER_ORE, BlockRegistry.FLAVOLITE.stone, BlockRegistry.VIOLECITE.stone); } diff --git a/src/main/java/ru/betterend/registry/FeatureRegistry.java b/src/main/java/ru/betterend/registry/FeatureRegistry.java index 08d30ce7..beb71f41 100644 --- a/src/main/java/ru/betterend/registry/FeatureRegistry.java +++ b/src/main/java/ru/betterend/registry/FeatureRegistry.java @@ -5,6 +5,7 @@ import java.util.function.Supplier; import com.google.common.collect.Lists; +import net.minecraft.world.gen.GenerationStep.Feature; import net.minecraft.world.gen.feature.ConfiguredFeature; import ru.betterend.world.features.BlueVineFeature; import ru.betterend.world.features.DoublePlantFeature; @@ -17,6 +18,8 @@ import ru.betterend.world.features.PythadendronTreeFeature; import ru.betterend.world.features.SinglePlantFeature; import ru.betterend.world.features.UnderwaterPlantFeature; import ru.betterend.world.features.VineFeature; +import ru.betterend.world.structures.EndStructureFeature; +import ru.betterend.world.structures.features.StructureMegaLake; public class FeatureRegistry { private final static List GLOBAL_FEATURES = Lists.newArrayList(); @@ -48,6 +51,9 @@ public class FeatureRegistry { public static final EndFeature VIOLECITE_LAYER = EndFeature.makeLayerFeature("violecite_layer", BlockRegistry.VIOLECITE, 15, 4, 96, 8); public static final EndFeature FLAVOLITE_LAYER = EndFeature.makeLayerFeature("flavolite_layer", BlockRegistry.FLAVOLITE, 12, 4, 96, 6); + // Structures // + public static final EndStructureFeature MEGALAKE = new EndStructureFeature("megalake", new StructureMegaLake(), Feature.RAW_GENERATION, 4, 1); + public static void registerGlobals(List>>> features) { GLOBAL_FEATURES.forEach(feature -> { int index = feature.getFeatureStep().ordinal(); diff --git a/src/main/java/ru/betterend/registry/StructureRegistry.java b/src/main/java/ru/betterend/registry/StructureRegistry.java index 1ee3c946..24cda148 100644 --- a/src/main/java/ru/betterend/registry/StructureRegistry.java +++ b/src/main/java/ru/betterend/registry/StructureRegistry.java @@ -7,6 +7,7 @@ import ru.betterend.BetterEnd; import ru.betterend.world.structures.EndStructureFeature; import ru.betterend.world.structures.features.StructureGiantMossyGlowshroom; import ru.betterend.world.structures.piece.CavePiece; +import ru.betterend.world.structures.piece.LakePiece; import ru.betterend.world.structures.piece.MountainPiece; import ru.betterend.world.structures.piece.VoxelPiece; @@ -14,6 +15,7 @@ public class StructureRegistry { public static final StructurePieceType VOXEL_PIECE = register("voxel", VoxelPiece::new); public static final StructurePieceType MOUNTAIN_PIECE = register("mountain_piece", MountainPiece::new); public static final StructurePieceType CAVE_PIECE = register("cave_piece", CavePiece::new); + public static final StructurePieceType LAKE_PIECE = register("lake_piece", LakePiece::new); public static final EndStructureFeature GIANT_MOSSY_GLOWSHROOM = new EndStructureFeature("giant_mossy_glowshroom", new StructureGiantMossyGlowshroom(), Feature.SURFACE_STRUCTURES, 16, 8); diff --git a/src/main/java/ru/betterend/util/BlocksHelper.java b/src/main/java/ru/betterend/util/BlocksHelper.java index 6f45ebff..88610356 100644 --- a/src/main/java/ru/betterend/util/BlocksHelper.java +++ b/src/main/java/ru/betterend/util/BlocksHelper.java @@ -160,7 +160,18 @@ public class BlocksHelper { } else { POS.setY(y); - BlocksHelper.setWithoutUpdate(world, POS, AIR); + boolean place = true; + for (Direction dir: HORIZONTAL) { + state = world.getBlockState(POS.offset(dir)); + if (!state.getFluidState().isEmpty()) { + BlocksHelper.setWithoutUpdate(world, POS, state); + place = false; + break; + } + } + if (place) { + BlocksHelper.setWithoutUpdate(world, POS, AIR); + } POS.setY(y - ray); BlocksHelper.setWithoutUpdate(world, POS, falling); diff --git a/src/main/java/ru/betterend/world/biome/BiomeDustWastelands.java b/src/main/java/ru/betterend/world/biome/BiomeDustWastelands.java new file mode 100644 index 00000000..af1cda26 --- /dev/null +++ b/src/main/java/ru/betterend/world/biome/BiomeDustWastelands.java @@ -0,0 +1,22 @@ +package ru.betterend.world.biome; + +import net.minecraft.entity.EntityType; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.world.gen.feature.ConfiguredStructureFeatures; +import ru.betterend.registry.BlockRegistry; + +public class BiomeDustWastelands extends EndBiome { + public BiomeDustWastelands() { + super(new BiomeDefinition("dust_wastelands") + .setFogColor(226, 239, 168) + .setFogDensity(2) + .setWaterColor(192, 180, 131) + .setWaterFogColor(192, 180, 131) + .setSurface(BlockRegistry.ENDSTONE_DUST) + .setParticles(ParticleTypes.WHITE_ASH, 0.01F) + //.setLoop(SoundRegistry.AMBIENT_FOGGY_MUSHROOMLAND) + //.setMusic(SoundRegistry.MUSIC_FOGGY_MUSHROOMLAND) + .addStructureFeature(ConfiguredStructureFeatures.END_CITY) + .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); + } +} diff --git a/src/main/java/ru/betterend/world/biome/BiomeMegalake.java b/src/main/java/ru/betterend/world/biome/BiomeMegalake.java new file mode 100644 index 00000000..edf125f0 --- /dev/null +++ b/src/main/java/ru/betterend/world/biome/BiomeMegalake.java @@ -0,0 +1,21 @@ +package ru.betterend.world.biome; + +import net.minecraft.entity.EntityType; +import net.minecraft.world.gen.feature.ConfiguredStructureFeatures; +import ru.betterend.registry.BlockRegistry; +import ru.betterend.registry.FeatureRegistry; + +public class BiomeMegalake extends EndBiome { + public BiomeMegalake() { + super(new BiomeDefinition("megalake") + .setFogColor(178, 209, 248) + .setWaterColor(96, 163, 255) + .setWaterFogColor(96, 163, 255) + .setSurface(BlockRegistry.ENDSTONE_DUST) + .addStructureFeature(FeatureRegistry.MEGALAKE) + .addStructureFeature(ConfiguredStructureFeatures.END_CITY) + .addFeature(FeatureRegistry.BUBBLE_CORAL) + .addFeature(FeatureRegistry.END_LILY) + .addMobSpawn(EntityType.ENDERMAN, 50, 1, 2)); + } +} diff --git a/src/main/java/ru/betterend/world/structures/features/StructureMegaLake.java b/src/main/java/ru/betterend/world/structures/features/StructureMegaLake.java new file mode 100644 index 00000000..dd4d3535 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/features/StructureMegaLake.java @@ -0,0 +1,41 @@ +package ru.betterend.world.structures.features; + +import net.minecraft.structure.StructureManager; +import net.minecraft.structure.StructureStart; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.DynamicRegistryManager; +import net.minecraft.world.Heightmap.Type; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import net.minecraft.world.gen.feature.StructureFeature; +import ru.betterend.util.MHelper; +import ru.betterend.world.structures.piece.LakePiece; + +public class StructureMegaLake extends StructureFeatureBase { + @Override + public StructureFeature.StructureStartFactory getStructureStartFactory() { + return SDFStructureStart::new; + } + + public static class SDFStructureStart extends StructureStart { + public SDFStructureStart(StructureFeature feature, int chunkX, int chunkZ, BlockBox box, int references, long seed) { + super(feature, chunkX, chunkZ, box, references, seed); + } + + @Override + public void init(DynamicRegistryManager registryManager, ChunkGenerator chunkGenerator, StructureManager manager, int chunkX, int chunkZ, Biome biome, DefaultFeatureConfig config) { + int x = (chunkX << 4) | MHelper.randRange(4, 12, random); + int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); + int y = chunkGenerator.getHeight(x, z, Type.WORLD_SURFACE_WG); + if (y > 5) { + float radius = MHelper.randRange(50, 100, random); + float depth = MHelper.randRange(10, 16, random); + LakePiece piece = new LakePiece(new BlockPos(x, y, z), radius, depth, random.nextInt()); + this.children.add(piece); + } + this.setBoundingBoxFromChildren(); + } + } +} diff --git a/src/main/java/ru/betterend/world/structures/piece/LakePiece.java b/src/main/java/ru/betterend/world/structures/piece/LakePiece.java new file mode 100644 index 00000000..422de1b1 --- /dev/null +++ b/src/main/java/ru/betterend/world/structures/piece/LakePiece.java @@ -0,0 +1,178 @@ +package ru.betterend.world.structures.piece; + +import java.util.Random; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.structure.StructureManager; +import net.minecraft.util.math.BlockBox; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.Heightmap; +import net.minecraft.world.Heightmap.Type; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.StructureAccessor; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import ru.betterend.noise.OpenSimplexNoise; +import ru.betterend.registry.BiomeRegistry; +import ru.betterend.registry.BlockRegistry; +import ru.betterend.registry.BlockTagRegistry; +import ru.betterend.registry.StructureRegistry; +import ru.betterend.util.MHelper; + +public class LakePiece extends BasePiece { + private static final BlockState WATER = Blocks.WATER.getDefaultState(); + private OpenSimplexNoise noise; + private BlockPos center; + private float radius; + private float depth; + private float r2; + + public LakePiece(BlockPos center, float radius, float depth, int id) { + super(StructureRegistry.LAKE_PIECE, id); + this.center = center; + this.radius = radius; + this.depth = depth; + this.r2 = radius * radius; + this.noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); + makeBoundingBox(); + } + + public LakePiece(StructureManager manager, CompoundTag tag) { + super(StructureRegistry.LAKE_PIECE, tag); + makeBoundingBox(); + } + + @Override + protected void toNbt(CompoundTag tag) { + tag.put("center", NbtHelper.fromBlockPos(center)); + tag.putFloat("radius", radius); + tag.putFloat("depth", depth); + } + + @Override + protected void fromNbt(CompoundTag tag) { + center = NbtHelper.toBlockPos(tag.getCompound("center")); + radius = tag.getFloat("radius"); + depth = tag.getFloat("depth"); + r2 = radius * radius; + noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); + } + + @Override + public boolean generate(StructureWorldAccess world, StructureAccessor arg, ChunkGenerator chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos, BlockPos blockPos) { + int sx = chunkPos.getStartX(); + int sz = chunkPos.getStartZ(); + Mutable pos = new Mutable(); + Chunk chunk = world.getChunk(chunkPos.x, chunkPos.z); + Heightmap map = chunk.getHeightmap(Type.WORLD_SURFACE_WG); + for (int x = 0; x < 16; x++) { + int px = x + sx; + int px2 = px - center.getX(); + px2 *= px2; + pos.setX(x); + for (int z = 0; z < 16; z++) { + int pz = z + sz; + int pz2 = pz - center.getZ(); + pz2 *= pz2; + float dist = px2 + pz2; + if (dist < r2) { + pos.setZ(z); + dist = 1 - dist / r2; + int maxY = map.get(x, z); + if (maxY > 55) { + float minY = dist * depth * getHeightClamp(world, 4, px, pz); + if (minY > 0) { + minY *= (float) noise.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F; + minY *= (float) noise.eval(px * 0.1, pz * 0.1) * 0.1F + 0.8F; + float lerp = minY / 2F; + if (lerp > 1) { + lerp = 1; + } + minY = MathHelper.lerp(lerp, maxY - minY, 56 - minY); + //System.out.println(minY + " " + maxY); + for (int y = maxY; y >= minY; y--) { + pos.setY(y - 1); + BlockState state = chunk.getBlockState(pos); + if (state.getMaterial().isReplaceable() || state.isIn(BlockTagRegistry.GEN_TERRAIN)) { + pos.setY(y); + chunk.setBlockState(pos, y > 56 ? AIR : WATER, false); + } + else { + pos.setY(y); + break; + } + } + if (pos.getY() < 57) { + BlockState state = chunk.getBlockState(pos); + if (state.getMaterial().isReplaceable() || state.isIn(BlockTagRegistry.GEN_TERRAIN)) { + chunk.setBlockState(pos, BlockRegistry.ENDSTONE_DUST.getDefaultState(), false); + pos.setY(pos.getY() - 1); + state = chunk.getBlockState(pos); + if (state.getMaterial().isReplaceable() || state.isIn(BlockTagRegistry.GEN_TERRAIN)) { + chunk.setBlockState(pos, BlockRegistry.ENDSTONE_DUST.getDefaultState(), false); + pos.setY(pos.getY() - 1); + } + if (!chunk.getBlockState(pos).isIn(BlockTagRegistry.GEN_TERRAIN)) { + + chunk.setBlockState(pos, Blocks.END_STONE.getDefaultState(), false); + } + } + } + } + } + } + } + } + + map = chunk.getHeightmap(Type.WORLD_SURFACE); + + return true; + } + + private int getHeight(StructureWorldAccess world, BlockPos pos) { + if (BiomeRegistry.getFromBiome(world.getBiome(pos)) != BiomeRegistry.MEGALAKE) { + return -4; + } + int h = world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + if (h < 57) { + return 0; + } + return h - 57; + } + + private float getHeightClamp(StructureWorldAccess world, int radius, int posX, int posZ) { + Mutable mut = new Mutable(); + int r2 = radius * radius; + float height = 0; + float max = 0; + for (int x = -radius; x <= radius; x++) { + mut.setX(posX + x); + int x2 = x * x; + for (int z = -radius; z <= radius; z++) { + mut.setZ(posZ + z); + int z2 = z * z; + if (x2 + z2 < r2) { + float mult = 1 - (float) Math.sqrt(x2 + z2) / radius; + max += mult; + height += getHeight(world, mut) * mult; + } + } + } + height /= max; + return MathHelper.clamp(height / radius, 0, 1); + } + + private void makeBoundingBox() { + int minX = MHelper.floor(center.getX() - radius); + int minZ = MHelper.floor(center.getZ() - radius); + int maxX = MHelper.floor(center.getX() + radius + 1); + int maxZ = MHelper.floor(center.getZ() + radius + 1); + this.boundingBox = new BlockBox(minX, minZ, maxX, maxZ); + } +} diff --git a/src/main/resources/assets/betterend/lang/en_us.json b/src/main/resources/assets/betterend/lang/en_us.json index fb15d83f..82319d49 100644 --- a/src/main/resources/assets/betterend/lang/en_us.json +++ b/src/main/resources/assets/betterend/lang/en_us.json @@ -2,7 +2,9 @@ "itemGroup.betterend.items": "Better End", "biome.betterend.foggy_mushroomland": "Foggy Mushroomland", + "biome.betterend.dust_wastelands": "Dust Wastelands", "biome.betterend.chorus_forest": "Chorus Forest", + "biome.betterend.megalake": "Megalake", "entity.betterend.dragonfly": "Dragonfly", "item.betterend.spawn_egg_dragonfly": "Dragonfly Spawn Egg", diff --git a/src/main/resources/assets/betterend/lang/ru_ru.json b/src/main/resources/assets/betterend/lang/ru_ru.json index 3b2ab0d5..a7346029 100644 --- a/src/main/resources/assets/betterend/lang/ru_ru.json +++ b/src/main/resources/assets/betterend/lang/ru_ru.json @@ -2,7 +2,9 @@ "itemGroup.betterend.items": "Улучшенный Край", "biome.betterend.foggy_mushroomland": "Туманное гриболесье", + "biome.betterend.dust_wastelands": "Пыльные пустоши", "biome.betterend.chorus_forest": "Хорусовый лес", + "biome.betterend.megalake": "Мегаозеро", "entity.betterend.dragonfly": "Стрекоза", "item.betterend.spawn_egg_dragonfly": "Яйцо призыва стрекозы",