diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index 5c45a673..54d43f50 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -65,6 +65,7 @@ import ru.betterend.world.features.terrain.SulphurHillFeature; import ru.betterend.world.features.terrain.SulphuricCaveFeature; import ru.betterend.world.features.terrain.SulphuricLakeFeature; import ru.betterend.world.features.terrain.SurfaceVentFeature; +import ru.betterend.world.features.terrain.ThinArchFeature; import ru.betterend.world.features.terrain.caves.RoundCaveFeature; import ru.betterend.world.features.terrain.caves.TunelCaveFeature; import ru.betterend.world.features.trees.DragonTreeFeature; @@ -518,7 +519,8 @@ public class EndFeatures { BetterEnd.makeID("tunel_cave"), new TunelCaveFeature() ); - public static final BCLFeature UMBRALITH_ARCH = registerChanced("umbralith_arch", new ArchFeature(), 10); + public static final BCLFeature UMBRALITH_ARCH = registerChanced("umbralith_arch", new ArchFeature(EndBlocks.UMBRALITH.stone), 10); + public static final BCLFeature THIN_UMBRALITH_ARCH = registerChanced("thin_umbralith_arch", new ThinArchFeature(EndBlocks.UMBRALITH.stone), 15); // Ores // public static final BCLFeature THALLASIUM_ORE = registerOre( diff --git a/src/main/java/ru/betterend/world/biome/land/UmbraValleyBiome.java b/src/main/java/ru/betterend/world/biome/land/UmbraValleyBiome.java index f3391046..de68e32e 100644 --- a/src/main/java/ru/betterend/world/biome/land/UmbraValleyBiome.java +++ b/src/main/java/ru/betterend/world/biome/land/UmbraValleyBiome.java @@ -15,6 +15,7 @@ public class UmbraValleyBiome extends EndBiome { .setWaterAndFogColor(69, 104, 134) .setSurface(SurfaceBuilders.UMBRA_SURFACE.configured(SurfaceBuilders.DEFAULT_END_CONFIG)) .addFeature(EndFeatures.UMBRALITH_ARCH) + .addFeature(EndFeatures.THIN_UMBRALITH_ARCH) ); } } diff --git a/src/main/java/ru/betterend/world/features/terrain/ArchFeature.java b/src/main/java/ru/betterend/world/features/terrain/ArchFeature.java index 555b4e61..11df6514 100644 --- a/src/main/java/ru/betterend/world/features/terrain/ArchFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/ArchFeature.java @@ -2,6 +2,7 @@ package ru.betterend.world.features.terrain; import net.minecraft.core.BlockPos; import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; @@ -19,6 +20,12 @@ import ru.betterend.noise.OpenSimplexNoise; import java.util.Random; public class ArchFeature extends DefaultFeature { + private Block block; + + public ArchFeature(Block block) { + this.block = block; + } + @Override public boolean place(FeaturePlaceContext featurePlaceContext) { final WorldGenLevel world = featurePlaceContext.level(); @@ -35,7 +42,7 @@ public class ArchFeature extends DefaultFeature { if (smallRadius + bigRadius > 23) { smallRadius = 23 - bigRadius; } - SDF arch = new SDFTorus().setBigRadius(bigRadius).setSmallRadius(smallRadius).setBlock(Blocks.DIAMOND_BLOCK); + SDF arch = new SDFTorus().setBigRadius(bigRadius).setSmallRadius(smallRadius).setBlock(block); arch = new SDFRotation().setRotation(MHelper.randomHorizontal(random), (float) Math.PI * 0.5F).setSource(arch); final float smallRadiusF = smallRadius; @@ -48,7 +55,11 @@ public class ArchFeature extends DefaultFeature { )) * 3F + Math.abs(noise.eval(vec.x() * 0.3, vec.y() * 0.3 + 100, vec.z() * 0.3)) * 1.3F) - smallRadiusF * Math.abs(1 - vec.y() / bigRadius); }).setSource(arch); - arch.fillArea(world, pos, AABB.ofSize(Vec3.atCenterOf(pos), 46, 46, 46)); + float side = (bigRadius + smallRadius + 3F) * 2; + if (side > 47) { + side = 47; + } + arch.fillArea(world, pos, AABB.ofSize(Vec3.atCenterOf(pos), side, side, side)); return true; } } diff --git a/src/main/java/ru/betterend/world/features/terrain/ThinArchFeature.java b/src/main/java/ru/betterend/world/features/terrain/ThinArchFeature.java new file mode 100644 index 00000000..5a063242 --- /dev/null +++ b/src/main/java/ru/betterend/world/features/terrain/ThinArchFeature.java @@ -0,0 +1,79 @@ +package ru.betterend.world.features.terrain; + +import com.mojang.math.Vector3f; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import ru.bclib.api.TagAPI; +import ru.bclib.sdf.SDF; +import ru.bclib.sdf.operator.SDFCoordModify; +import ru.bclib.sdf.operator.SDFDisplacement; +import ru.bclib.sdf.operator.SDFRotation; +import ru.bclib.sdf.operator.SDFTranslate; +import ru.bclib.sdf.operator.SDFUnion; +import ru.bclib.sdf.primitive.SDFTorus; +import ru.bclib.util.MHelper; +import ru.bclib.world.features.DefaultFeature; +import ru.betterend.noise.OpenSimplexNoise; + +import java.util.Random; + +public class ThinArchFeature extends DefaultFeature { + private Block block; + + public ThinArchFeature(Block block) { + this.block = block; + } + + @Override + public boolean place(FeaturePlaceContext featurePlaceContext) { + final WorldGenLevel world = featurePlaceContext.level(); + BlockPos origin = featurePlaceContext.origin(); + Random random = featurePlaceContext.random(); + + BlockPos pos = getPosOnSurfaceWG(world, new BlockPos((origin.getX() & 0xFFFFFFF0) | 7, 0, (origin.getZ() & 0xFFFFFFF0) | 7)); + if (!world.getBlockState(pos.below(5)).is(TagAPI.BLOCK_GEN_TERRAIN)) { + return false; + } + + SDF sdf = null; + float bigRadius = MHelper.randRange(15F, 20F, random); + float variation = bigRadius * 0.3F; + int count = MHelper.randRange(2, 4, random); + + for (int i = 0; i < count; i++) { + float smallRadius = MHelper.randRange(0.6F, 1.3F, random); + SDF arch = new SDFTorus().setBigRadius(bigRadius - random.nextFloat() * variation).setSmallRadius(smallRadius).setBlock(block); + float angle = (i - count * 0.5F) * 0.3F + random.nextFloat() * 0.05F + (float) Math.PI * 0.5F; + arch = new SDFRotation().setRotation(Vector3f.XP, angle).setSource(arch); + sdf = sdf == null ? arch : new SDFUnion().setSourceA(sdf).setSourceB(arch); + } + + sdf = new SDFRotation().setRotation(MHelper.randomHorizontal(random), random.nextFloat() * MHelper.PI2).setSource(sdf); + + OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong()); + sdf = new SDFCoordModify().setFunction(vec -> { + float dx = (float) noise.eval(vec.y() * 0.02, vec.z() * 0.02); + float dy = (float) noise.eval(vec.x() * 0.02, vec.z() * 0.02); + float dz = (float) noise.eval(vec.x() * 0.02, vec.y() * 0.02); + vec.add(dx * 10, dy * 10, dz * 10); + }).setSource(sdf); + sdf = new SDFDisplacement().setFunction(vec -> { + float offset = vec.y() / bigRadius - 0.5F; + return Mth.clamp(offset * 3, -10F, 0F); + }).setSource(sdf); + + float side = (bigRadius + 2.5F) * 2; + if (side > 47) { + side = 47; + } + sdf.fillArea(world, pos, AABB.ofSize(Vec3.atCenterOf(pos), side, side, side)); + return true; + } +}