diff --git a/src/main/java/ru/betterend/registry/FeatureRegistry.java b/src/main/java/ru/betterend/registry/FeatureRegistry.java index 2f1235db..f15f6583 100644 --- a/src/main/java/ru/betterend/registry/FeatureRegistry.java +++ b/src/main/java/ru/betterend/registry/FeatureRegistry.java @@ -9,8 +9,6 @@ import net.minecraft.util.Identifier; import net.minecraft.world.biome.Biome; import net.minecraft.world.gen.feature.ConfiguredFeature; import ru.betterend.world.features.BlueVineFeature; -import ru.betterend.world.features.CaveBushFeature; -import ru.betterend.world.features.CaveBushFeatureCeil; import ru.betterend.world.features.CavePlantFeature; import ru.betterend.world.features.DoublePlantFeature; import ru.betterend.world.features.EndFeature; @@ -39,9 +37,7 @@ public class FeatureRegistry { public static final EndFeature CREEPING_MOSS = new EndFeature("creeping_moss", new SinglePlantFeature(BlockRegistry.CREEPING_MOSS, 5), 5); public static final EndFeature BLUE_VINE = new EndFeature("blue_vine", new BlueVineFeature(), 1); public static final EndFeature CHORUS_GRASS = new EndFeature("chorus_grass", new SinglePlantFeature(BlockRegistry.CHORUS_GRASS, 4), 5); - public static final EndFeature CAVE_GRASS = new EndFeature("cave_grass", new CavePlantFeature(BlockRegistry.CAVE_GRASS, 7), 5); - public static final EndFeature CAVE_BUSH = new EndFeature("cave_bush", new CaveBushFeature(5), 2); - public static final EndFeature CAVE_BUSH_CEIL = new EndFeature("cave_bush_ceil", new CaveBushFeatureCeil(15), 10); + public static final EndFeature CAVE_GRASS = new EndFeature("cave_grass", new CavePlantFeature(BlockRegistry.CAVE_GRASS, 7), 7); public static final EndFeature DENSE_VINE = new EndFeature("dense_vine", new VineFeature(BlockRegistry.DENSE_VINE, 24), 3); @@ -68,8 +64,6 @@ public class FeatureRegistry { addFeature(ENDER_ORE, features); addFeature(ROUND_CAVE_RARE, features); addFeature(CAVE_GRASS, features); - addFeature(CAVE_BUSH, features); - addFeature(CAVE_BUSH_CEIL, features); if (id.getNamespace().equals("minecraft")) { if (id.getPath().equals("end_highlands")) { diff --git a/src/main/java/ru/betterend/world/features/CaveBushFeatureCeil.java b/src/main/java/ru/betterend/world/features/CaveBushFeatureCeil.java index 9e0def15..9f69f582 100644 --- a/src/main/java/ru/betterend/world/features/CaveBushFeatureCeil.java +++ b/src/main/java/ru/betterend/world/features/CaveBushFeatureCeil.java @@ -28,12 +28,14 @@ public class CaveBushFeatureCeil extends InvertedScatterFeature { @Override public boolean canGenerate(StructureWorldAccess world, Random random, BlockPos center, BlockPos blockPos, float radius) { - return blockPos.getY() < 64 && world.isAir(blockPos) && world.getBlockState(blockPos.up()).isIn(BlockTagRegistry.GEN_TERRAIN); + return world.isAir(blockPos.down()) + && world.getBlockState(blockPos.up()).isIn(BlockTagRegistry.GEN_TERRAIN) + && world.getBlockState(blockPos.down(BlocksHelper.downRay(world, blockPos.down(), 64) + 2)).isIn(BlockTagRegistry.GEN_TERRAIN); } @Override public void generate(StructureWorldAccess world, Random random, BlockPos blockPos) { - float radius = MHelper.randRange(0.8F, 2.5F, random); + float radius = MHelper.randRange(1.0F, 3.2F, random); OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); SDF sphere = new SDFSphere().setRadius(radius).setBlock(BlockRegistry.CAVE_BUSH); sphere = new SDFScale3D().setScale(MHelper.randRange(0.8F, 1.2F, random), MHelper.randRange(0.8F, 1.2F, random), MHelper.randRange(0.8F, 1.2F, random)).setSource(sphere); diff --git a/src/main/java/ru/betterend/world/features/RoundCave.java b/src/main/java/ru/betterend/world/features/RoundCave.java index 8f7b41b3..ba022fb7 100644 --- a/src/main/java/ru/betterend/world/features/RoundCave.java +++ b/src/main/java/ru/betterend/world/features/RoundCave.java @@ -1,6 +1,9 @@ package ru.betterend.world.features; import java.util.Random; +import java.util.Set; + +import com.google.common.collect.Sets; import net.minecraft.block.BlockState; import net.minecraft.block.Material; @@ -18,8 +21,13 @@ import ru.betterend.registry.StructureRegistry; import ru.betterend.util.BlocksHelper; import ru.betterend.util.MHelper; import ru.betterend.util.sdf.SDF; +import ru.betterend.util.sdf.operator.SDFDisplacement; import ru.betterend.util.sdf.operator.SDFRotation; +import ru.betterend.util.sdf.operator.SDFScale3D; +import ru.betterend.util.sdf.operator.SDFSubtraction; +import ru.betterend.util.sdf.operator.SDFTranslate; import ru.betterend.util.sdf.primitive.SDFHexPrism; +import ru.betterend.util.sdf.primitive.SDFSphere; public class RoundCave extends DefaultFeature { @Override @@ -45,6 +53,7 @@ public class RoundCave extends DefaultFeature { double nr = radius * 0.25; Mutable bpos = new Mutable(); + Set bushes = Sets.newHashSet(); BlockState terrain = BlockRegistry.CAVE_MOSS.getDefaultState(); for (int x = x1; x <= x2; x++) { int xsq = x - pos.getX(); @@ -62,22 +71,55 @@ public class RoundCave extends DefaultFeature { double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; double dist = xsq + ysq + zsq; if (dist < r * r) { - if (isReplaceable(world.getBlockState(bpos))) { + BlockState state = world.getBlockState(bpos); + if (isReplaceable(state)) { BlocksHelper.setWithoutUpdate(world, bpos, AIR); + + while (state.getMaterial().equals(Material.LEAVES)) { + BlocksHelper.setWithoutUpdate(world, bpos, AIR); + bpos.setY(bpos.getY() + 1); + state = world.getBlockState(bpos); + } + + bpos.setY(y - 1); + while (state.getMaterial().equals(Material.LEAVES)) { + BlocksHelper.setWithoutUpdate(world, bpos, AIR); + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } } bpos.setY(y - 1); if (world.getBlockState(bpos).isIn(BlockTagRegistry.GEN_TERRAIN)) { BlocksHelper.setWithoutUpdate(world, bpos, terrain); } } + else if (world.getBlockState(bpos).isIn(BlockTagRegistry.GEN_TERRAIN)) { + if (world.isAir(bpos.down())) { + int h = BlocksHelper.downRay(world, bpos.down(), 64); + if (h > 6 && h < 32 && world.getBlockState(bpos.down(h + 3)).isIn(BlockTagRegistry.GEN_TERRAIN)) { + bushes.add(bpos.down()); + } + } + else if (world.isAir(bpos.up())) { + int h = BlocksHelper.upRay(world, bpos.up(), 64); + if (h > 6 && h < 32 && world.getBlockState(bpos.up(h + 3)).isIn(BlockTagRegistry.GEN_TERRAIN)) { + bushes.add(bpos.up()); + } + } + } } } } + bushes.forEach((cpos) -> { + if (random.nextInt(32) == 0) { + generateBush(world, random, cpos); + } + }); if (random.nextBoolean() && world.getBiome(pos).getGenerationSettings().hasStructureFeature(StructureRegistry.MOUNTAIN.getStructure())) { pos = pos.add(random.nextGaussian() * 5, random.nextGaussian() * 5, random.nextGaussian() * 5); BlockPos down = pos.down(BlocksHelper.downRay(world, pos, 64) + 2); - if (world.getBlockState(down).isIn(BlockTagRegistry.GEN_TERRAIN)) { + if (isReplaceable(world.getBlockState(down))) { SDF prism = new SDFHexPrism().setHeight(radius * MHelper.randRange(0.6F, 0.75F, random)).setRadius(3).setBlock(BlockRegistry.AURORA_CRYSTAL); float angleY = MHelper.randRange(0, MHelper.PI2, random); float vx = (float) Math.sin(angleY); @@ -101,4 +143,16 @@ public class RoundCave extends DefaultFeature { || state.getMaterial().equals(Material.PLANT) || state.getMaterial().equals(Material.LEAVES); } + + private void generateBush(StructureWorldAccess world, Random random, BlockPos blockPos) { + float radius = MHelper.randRange(1.0F, 3.2F, random); + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextInt()); + SDF sphere = new SDFSphere().setRadius(radius).setBlock(BlockRegistry.CAVE_BUSH); + sphere = new SDFScale3D().setScale(MHelper.randRange(0.8F, 1.2F, random), MHelper.randRange(0.8F, 1.2F, random), MHelper.randRange(0.8F, 1.2F, random)).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { return (float) noise.eval(vec.getX() * 0.2, vec.getY() * 0.2, vec.getZ() * 0.2) * 3; }).setSource(sphere); + sphere = new SDFDisplacement().setFunction((vec) -> { return random.nextFloat() * 3F - 1.5F; }).setSource(sphere); + sphere = new SDFSubtraction().setSourceA(sphere).setSourceB(new SDFTranslate().setTranslate(0, -radius, 0).setSource(sphere)); + sphere.fillRecursive(world, blockPos); + BlocksHelper.setWithoutUpdate(world, blockPos, BlockRegistry.CAVE_BUSH); + } } diff --git a/src/main/resources/assets/betterend/blockstates/cave_bush.json b/src/main/resources/assets/betterend/blockstates/cave_bush.json index f6b158d2..d1ef270e 100644 --- a/src/main/resources/assets/betterend/blockstates/cave_bush.json +++ b/src/main/resources/assets/betterend/blockstates/cave_bush.json @@ -1,10 +1,10 @@ { "variants": { "": [ - { "model": "betterend:block/cave_bush_01", "weight": 3 }, + { "model": "betterend:block/cave_bush_01", "weight": 4 }, { "model": "betterend:block/cave_bush_02" }, - { "model": "betterend:block/cave_bush_03" }, - { "model": "betterend:block/cave_bush_04" } + { "model": "betterend:block/cave_bush_03", "weight": 2 }, + { "model": "betterend:block/cave_bush_04", "weight": 2 } ] } } diff --git a/src/main/resources/assets/betterend/materialmaps/block/cave_grass.json b/src/main/resources/assets/betterend/materialmaps/block/cave_grass.json new file mode 100644 index 00000000..352de84b --- /dev/null +++ b/src/main/resources/assets/betterend/materialmaps/block/cave_grass.json @@ -0,0 +1,3 @@ +{ + "defaultMaterial": "betterend:waving_floor" +}