diff --git a/src/main/java/ru/betterend/blocks/BlockSulphurCrystal.java b/src/main/java/ru/betterend/blocks/BlockSulphurCrystal.java index c37a5b3d..bfa5f4d8 100644 --- a/src/main/java/ru/betterend/blocks/BlockSulphurCrystal.java +++ b/src/main/java/ru/betterend/blocks/BlockSulphurCrystal.java @@ -37,6 +37,7 @@ import net.minecraft.world.WorldView; import ru.betterend.blocks.basis.BlockAttached; import ru.betterend.client.render.ERenderLayer; import ru.betterend.interfaces.IRenderTypeable; +import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndItems; import ru.betterend.util.MHelper; @@ -102,6 +103,13 @@ public class BlockSulphurCrystal extends BlockAttached implements IRenderTypeabl return BOUNDING_SHAPES.get(state.get(FACING)); } + @Override + public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) { + Direction direction = (Direction) state.get(FACING); + BlockPos blockPos = pos.offset(direction.getOpposite()); + return world.getBlockState(blockPos).isOf(EndBlocks.BRIMSTONE); + } + static { BOUNDING_SHAPES.put(Direction.UP, VoxelShapes.cuboid(0.125, 0.0, 0.125, 0.875F, 0.5, 0.875F)); BOUNDING_SHAPES.put(Direction.DOWN, VoxelShapes.cuboid(0.125, 0.5, 0.125, 0.875F, 1.0, 0.875F)); diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index fa96dd93..e081cf7a 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -97,7 +97,7 @@ public class EndFeatures { public static final EndFeature FLOATING_SPIRE = EndFeature.makeRawGenFeature("floating_spire", new FloatingSpireFeature(), 8); public static final EndFeature GEYSER = EndFeature.makeRawGenFeature("geyser", new GeyserFeature(), 8); public static final EndFeature SULPHURIC_LAKE = EndFeature.makeLakeFeature("sulphuric_lake", new SulphuricLakeFeature(), 8); - public static final EndFeature SULPHURIC_CAVE = EndFeature.makeRawGenFeature("sulphuric_cave", new SulphuricCaveFeature(), 1); + public static final EndFeature SULPHURIC_CAVE = EndFeature.makeCountRawFeature("sulphuric_cave", new SulphuricCaveFeature(), 2); // Ores // public static final EndFeature ENDER_ORE = EndFeature.makeOreFeature("ender_ore", EndBlocks.ENDER_ORE, 6, 3, 0, 4, 96); diff --git a/src/main/java/ru/betterend/world/features/EndFeature.java b/src/main/java/ru/betterend/world/features/EndFeature.java index 5847e5bc..653933a3 100644 --- a/src/main/java/ru/betterend/world/features/EndFeature.java +++ b/src/main/java/ru/betterend/world/features/EndFeature.java @@ -103,6 +103,11 @@ public class EndFeature { return new EndFeature(name, feature, GenerationStep.Feature.SURFACE_STRUCTURES, configured); } + public static EndFeature makeCountRawFeature(String name, Feature feature, int chance) { + ConfiguredFeature configured = feature.configure(FeatureConfig.DEFAULT).decorate(Decorator.COUNT.configure(new CountConfig(chance))); + return new EndFeature(name, feature, GenerationStep.Feature.RAW_GENERATION, configured); + } + public Feature getFeature() { return feature; } diff --git a/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java b/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java index 7146f815..af1ea389 100644 --- a/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/GeyserFeature.java @@ -38,6 +38,7 @@ import ru.betterend.world.features.DefaultFeature; public class GeyserFeature extends DefaultFeature { protected static final Function REPLACE1; protected static final Function REPLACE2; + private static final Function IGNORE; @Override public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) { @@ -56,19 +57,6 @@ public class GeyserFeature extends DefaultFeature { float delta = (float) i / (float) (count - 1); float radius = MathHelper.lerp(delta, radius1, radius2) * 1.3F; - /*SDF bowl = new SDFCapedCone().setHeight(radius).setRadius1(0).setRadius2(radius).setBlock(EndBlocks.SULFURIC_ROCK.stone); - SDF cut = new SDFTranslate().setTranslate(0, 2, 0).setSource(bowl); - bowl = new SDFSubtraction().setSourceA(bowl).setSourceB(cut); - - SDF inner = new SDFCapedCone().setHeight(radius - 2).setRadius1(0).setRadius2(radius - 1).setBlock(EndBlocks.BRIMSTONE); - cut = new SDFTranslate().setTranslate(0, 4, 0).setSource(inner); - inner = new SDFSubtraction().setSourceA(inner).setSourceB(cut); - inner = new SDFTranslate().setTranslate(0, 1.99F, 0).setSource(inner); - bowl = new SDFUnion().setSourceA(inner).setSourceB(bowl); - - SDF water = new SDFCapedCone().setHeight(radius - 4).setRadius1(0).setRadius2(radius - 3).setBlock(Blocks.WATER); - bowl = new SDFUnion().setSourceA(water).setSourceB(bowl);*/ - SDF bowl = new SDFCapedCone().setHeight(radius).setRadius1(0).setRadius2(radius).setBlock(EndBlocks.SULPHURIC_ROCK.stone); SDF brimstone = new SDFCapedCone().setHeight(radius).setRadius1(0).setRadius2(radius).setBlock(EndBlocks.BRIMSTONE); @@ -83,9 +71,7 @@ public class GeyserFeature extends DefaultFeature { final OpenSimplexNoise noise1 = new OpenSimplexNoise(random.nextLong()); final OpenSimplexNoise noise2 = new OpenSimplexNoise(random.nextLong()); - /*bowl = new SDFDisplacement().setFunction((vec) -> { - return (float) noise.eval(vec.getX() * 0.1, vec.getY() * 0.1, vec.getZ() * 0.1); - }).setSource(bowl);*/ + bowl = new SDFCoordModify().setFunction((vec) -> { float dx = (float) noise1.eval(vec.getX() * 0.1, vec.getY() * 0.1, vec.getZ() * 0.1); float dz = (float) noise2.eval(vec.getX() * 0.1, vec.getY() * 0.1, vec.getZ() * 0.1); @@ -99,7 +85,7 @@ public class GeyserFeature extends DefaultFeature { bowl = new SDFTranslate().setTranslate(radius, py - radius, 0).setSource(bowl); bowl = new SDFRotation().setRotation(Vector3f.POSITIVE_Y, i * 4F).setSource(bowl); - sdf = /*new SDFSmoothUnion()*/new SDFUnion()/*.setRadius(3)*/.setSourceA(sdf).setSourceB(bowl); + sdf = new SDFUnion().setSourceA(sdf).setSourceB(bowl); } sdf.setReplaceFunction(REPLACE2).fillRecursive(world, pos); @@ -127,22 +113,28 @@ public class GeyserFeature extends DefaultFeature { sdf = new SDFSmoothUnion().setRadius(5).setSourceA(cave).setSourceB(sdf); - obj1.setBlock(EndBlocks.SULPHURIC_ROCK.stone); - obj2.setBlock(EndBlocks.SULPHURIC_ROCK.stone); - new SDFDisplacement().setFunction((vec) -> { - return -4F; - }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursive(world, pos); + obj1.setBlock(WATER); + obj2.setBlock(WATER); + sdf.setReplaceFunction(REPLACE2); + sdf.fillRecursive(world, pos); obj1.setBlock(EndBlocks.BRIMSTONE); obj2.setBlock(EndBlocks.BRIMSTONE); new SDFDisplacement().setFunction((vec) -> { return -2F; - }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursive(world, pos); + }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); - obj1.setBlock(WATER); - obj2.setBlock(WATER); - sdf.setReplaceFunction(REPLACE2); - sdf.fillRecursive(world, pos); + obj1.setBlock(EndBlocks.SULPHURIC_ROCK.stone); + obj2.setBlock(EndBlocks.SULPHURIC_ROCK.stone); + new SDFDisplacement().setFunction((vec) -> { + return -4F; + }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); + + obj1.setBlock(Blocks.END_STONE); + obj2.setBlock(Blocks.END_STONE); + new SDFDisplacement().setFunction((vec) -> { + return -6F; + }).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursiveIgnore(world, pos, IGNORE); Mutable mut = new Mutable().set(pos); for (int i = 0; i < halfHeight + 5; i++) { @@ -164,7 +156,7 @@ public class GeyserFeature extends DefaultFeature { static { REPLACE1 = (state) -> { - return state.isAir() || (state.isIn(EndTags.GEN_TERRAIN) && !state.isOf(EndBlocks.SULPHURIC_ROCK.stone) && !state.isOf(EndBlocks.BRIMSTONE)); + return state.isAir() || (state.isIn(EndTags.GEN_TERRAIN)); }; REPLACE2 = (state) -> { @@ -179,5 +171,9 @@ public class GeyserFeature extends DefaultFeature { } return state.getMaterial().isReplaceable(); }; + + IGNORE = (state) -> { + return state.isOf(Blocks.WATER) || state.isOf(Blocks.CAVE_AIR) || state.isOf(EndBlocks.SULPHURIC_ROCK.stone) || state.isOf(EndBlocks.BRIMSTONE); + }; } } diff --git a/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java index 16e02c3e..2d5b5576 100644 --- a/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/SulphuricCaveFeature.java @@ -1,16 +1,22 @@ package ru.betterend.world.features.terrain; import java.util.Random; +import java.util.Set; + +import com.google.common.collect.Sets; + import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.Material; -import net.minecraft.fluid.Fluids; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.BlockPos.Mutable; import net.minecraft.world.Heightmap; import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import ru.betterend.blocks.BlockProperties; +import ru.betterend.blocks.BlockSulphurCrystal; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndTags; @@ -24,7 +30,7 @@ public class SulphuricCaveFeature extends DefaultFeature { @Override public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) { - int radius = MHelper.randRange(20, 40, random); + int radius = MHelper.randRange(10, 30, random); int bottom = BlocksHelper.upRay(world, new BlockPos(pos.getX(), 0, pos.getZ()), 32) + radius + 5; int top = world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ()) - radius - 5; @@ -47,10 +53,9 @@ public class SulphuricCaveFeature extends DefaultFeature { double hr = radius * 0.75; double nr = radius * 0.25; - BlockState terrain = EndBlocks.BRIMSTONE.getDefaultState(); + Set brimstone = Sets.newHashSet(); BlockState rock = EndBlocks.SULPHURIC_ROCK.stone.getDefaultState(); - int waterLevel = random.nextBoolean() ? -200 : MHelper.floor(pos.getY() - radius * 0.3F); - + int waterLevel = pos.getY() + MHelper.randRange(MHelper.floor(radius * 0.8), radius, random); for (int x = x1; x <= x2; x++) { int xsq = x - pos.getX(); xsq *= xsq; @@ -71,32 +76,66 @@ public class SulphuricCaveFeature extends DefaultFeature { BlockState state = world.getBlockState(bpos); if (isReplaceable(state)) { BlocksHelper.setWithoutUpdate(world, bpos, y < waterLevel ? WATER : CAVE_AIR); - world.getFluidTickScheduler().schedule(bpos, Fluids.WATER, random.nextInt(16)); - } - int depth = MHelper.randRange(2, 4, random); - for (int i = 0; i < depth; i++) { - bpos.setY(y - 1); - if (world.getBlockState(bpos).isIn(EndTags.GEN_TERRAIN)) { - BlocksHelper.setWithoutUpdate(world, bpos, terrain); - } } } else if (dist < r2 * r2) { if (world.getBlockState(bpos).isIn(EndTags.GEN_TERRAIN)) { - BlocksHelper.setWithoutUpdate(world, bpos, rock); + double v = noise.eval(x * 0.1, y * 0.1, z * 0.1) + noise.eval(x * 0.03, y * 0.03, z * 0.03) * 0.5; + if (v < 0) { + brimstone.add(bpos.toImmutable()); + } + else { + BlocksHelper.setWithoutUpdate(world, bpos, rock); + } } } } } } + brimstone.forEach((blockPos) -> { + placeBrimstone(world, blockPos, random); + }); + + BlocksHelper.fixBlocks(world, new BlockPos(x1, y1, z1), new BlockPos(x2, y2, z2)); return true; } private boolean isReplaceable(BlockState state) { return state.isIn(EndTags.GEN_TERRAIN) + || state.isOf(EndBlocks.SULPHUR_CRYSTAL) || state.getMaterial().isReplaceable() || state.getMaterial().equals(Material.PLANT) || state.getMaterial().equals(Material.LEAVES); } + + private void placeBrimstone(StructureWorldAccess world, BlockPos pos, Random random) { + BlockState state = getBrimstone(world, pos); + BlocksHelper.setWithoutUpdate(world, pos, state); + if (state.get(BlockProperties.ACTIVATED)) { + makeShards(world, pos, random); + } + } + + private BlockState getBrimstone(StructureWorldAccess world, BlockPos pos) { + for (Direction dir: BlocksHelper.DIRECTIONS) { + if (world.getBlockState(pos.offset(dir)).isOf(Blocks.WATER)) { + return EndBlocks.BRIMSTONE.getDefaultState().with(BlockProperties.ACTIVATED, true); + } + } + return EndBlocks.BRIMSTONE.getDefaultState(); + } + + private void makeShards(StructureWorldAccess world, BlockPos pos, Random random) { + for (Direction dir: BlocksHelper.DIRECTIONS) { + BlockPos side; + if (random.nextInt(3) == 0 && world.getBlockState((side = pos.offset(dir))).isOf(Blocks.WATER)) { + BlockState state = EndBlocks.SULPHUR_CRYSTAL.getDefaultState() + .with(BlockSulphurCrystal.WATERLOGGED, true) + .with(BlockSulphurCrystal.FACING, dir) + .with(BlockSulphurCrystal.AGE, random.nextInt(3)); + BlocksHelper.setWithoutUpdate(world, side, state); + } + } + } }