Sulphuric caves (WIP)
This commit is contained in:
parent
b7c0ce452e
commit
9518bb3c85
6 changed files with 203 additions and 8 deletions
|
@ -9,6 +9,7 @@ import net.minecraft.block.LeavesBlock;
|
|||
import net.minecraft.block.Material;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockPos.Mutable;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.StructureWorldAccess;
|
||||
import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
|
@ -16,20 +17,27 @@ import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
|||
import ru.betterend.noise.OpenSimplexNoise;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
import ru.betterend.util.MHelper;
|
||||
import ru.betterend.util.sdf.SDF;
|
||||
import ru.betterend.util.sdf.operator.SDFCoordModify;
|
||||
import ru.betterend.util.sdf.operator.SDFDisplacement;
|
||||
import ru.betterend.util.sdf.operator.SDFInvert;
|
||||
import ru.betterend.util.sdf.operator.SDFRotation;
|
||||
import ru.betterend.util.sdf.operator.SDFScale3D;
|
||||
import ru.betterend.util.sdf.operator.SDFSmoothUnion;
|
||||
import ru.betterend.util.sdf.operator.SDFSubtraction;
|
||||
import ru.betterend.util.sdf.operator.SDFTranslate;
|
||||
import ru.betterend.util.sdf.operator.SDFUnion;
|
||||
import ru.betterend.util.sdf.primitive.SDFCapedCone;
|
||||
import ru.betterend.util.sdf.primitive.SDFFlatland;
|
||||
import ru.betterend.util.sdf.primitive.SDFPrimitive;
|
||||
import ru.betterend.util.sdf.primitive.SDFSphere;
|
||||
import ru.betterend.world.features.DefaultFeature;
|
||||
|
||||
public class GeyserFeature extends DefaultFeature {
|
||||
protected static final Function<BlockState, Boolean> REPLACE;
|
||||
protected static final Function<BlockState, Boolean> REPLACE1;
|
||||
protected static final Function<BlockState, Boolean> REPLACE2;
|
||||
|
||||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
|
||||
|
@ -93,7 +101,60 @@ public class GeyserFeature extends DefaultFeature {
|
|||
bowl = new SDFRotation().setRotation(Vector3f.POSITIVE_Y, i * 4F).setSource(bowl);
|
||||
sdf = /*new SDFSmoothUnion()*/new SDFUnion()/*.setRadius(3)*/.setSourceA(sdf).setSourceB(bowl);
|
||||
}
|
||||
sdf.setReplaceFunction(REPLACE).fillRecursive(world, pos);
|
||||
sdf.setReplaceFunction(REPLACE2).fillRecursive(world, pos);
|
||||
|
||||
radius2 = radius2 * 0.5F;
|
||||
if (radius2 < 0.7F) {
|
||||
radius2 = 0.7F;
|
||||
}
|
||||
final OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong());
|
||||
|
||||
SDFPrimitive obj1;
|
||||
SDFPrimitive obj2;
|
||||
|
||||
obj1 = new SDFCapedCone().setHeight(halfHeight + 5).setRadius1(radius1 * 0.5F).setRadius2(radius2);
|
||||
sdf = new SDFTranslate().setTranslate(0, halfHeight - 13, 0).setSource(obj1);
|
||||
sdf = new SDFDisplacement().setFunction((vec) -> {
|
||||
return (float) noise.eval(vec.getX() * 0.3F, vec.getY() * 0.3F, vec.getZ() * 0.3F) * 0.5F;
|
||||
}).setSource(sdf);
|
||||
|
||||
obj2 = new SDFSphere().setRadius(radius1);
|
||||
SDF cave = new SDFScale3D().setScale(1.5F, 1, 1.5F).setSource(obj2);
|
||||
cave = new SDFDisplacement().setFunction((vec) -> {
|
||||
return (float) noise.eval(vec.getX() * 0.1F, vec.getY() * 0.1F, vec.getZ() * 0.1F) * 2F;
|
||||
}).setSource(cave);
|
||||
cave = new SDFTranslate().setTranslate(0, -halfHeight - 10, 0).setSource(cave);
|
||||
|
||||
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(EndBlocks.BRIMSTONE);
|
||||
obj2.setBlock(EndBlocks.BRIMSTONE);
|
||||
new SDFDisplacement().setFunction((vec) -> {
|
||||
return -2F;
|
||||
}).setSource(sdf).setReplaceFunction(REPLACE1).fillRecursive(world, pos);
|
||||
|
||||
obj1.setBlock(WATER);
|
||||
obj2.setBlock(WATER);
|
||||
sdf.setReplaceFunction(REPLACE2);
|
||||
sdf.fillRecursive(world, pos);
|
||||
|
||||
Mutable mut = new Mutable().set(pos);
|
||||
for (int i = 0; i < halfHeight + 5; i++) {
|
||||
BlockState state = world.getBlockState(mut);
|
||||
if (state.isIn(EndTags.GEN_TERRAIN) || state.isOf(Blocks.WATER)) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, WATER);
|
||||
mut.setY(mut.getY() + 1);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -102,8 +163,12 @@ public class GeyserFeature extends DefaultFeature {
|
|||
}
|
||||
|
||||
static {
|
||||
REPLACE = (state) -> {
|
||||
if (state.isIn(EndTags.END_GROUND)) {
|
||||
REPLACE1 = (state) -> {
|
||||
return state.isAir() || (state.isIn(EndTags.GEN_TERRAIN) && !state.isOf(EndBlocks.SULPHURIC_ROCK.stone) && !state.isOf(EndBlocks.BRIMSTONE));
|
||||
};
|
||||
|
||||
REPLACE2 = (state) -> {
|
||||
if (state.isIn(EndTags.GEN_TERRAIN)) {
|
||||
return true;
|
||||
}
|
||||
if (state.getBlock() instanceof LeavesBlock) {
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package ru.betterend.world.features.terrain;
|
||||
|
||||
import java.util.Random;
|
||||
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.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.noise.OpenSimplexNoise;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.BlocksHelper;
|
||||
import ru.betterend.util.MHelper;
|
||||
import ru.betterend.world.features.DefaultFeature;
|
||||
|
||||
public class SulphuricCaveFeature extends DefaultFeature {
|
||||
private static final BlockState CAVE_AIR = Blocks.CAVE_AIR.getDefaultState();
|
||||
private static final BlockState WATER = Blocks.WATER.getDefaultState();
|
||||
|
||||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
|
||||
int radius = MHelper.randRange(20, 40, 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;
|
||||
|
||||
if (top <= bottom) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Mutable bpos = new Mutable();
|
||||
pos = new BlockPos(pos.getX(), MHelper.randRange(bottom, top, random), pos.getZ());
|
||||
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(MHelper.getSeed(534, pos.getX(), pos.getZ()));
|
||||
|
||||
int x1 = pos.getX() - radius - 5;
|
||||
int z1 = pos.getZ() - radius - 5;
|
||||
int x2 = pos.getX() + radius + 5;
|
||||
int z2 = pos.getZ() + radius + 5;
|
||||
int y1 = MHelper.floor(pos.getY() - (radius + 5) / 1.6);
|
||||
int y2 = MHelper.floor(pos.getY() + (radius + 5) / 1.6);
|
||||
|
||||
double hr = radius * 0.75;
|
||||
double nr = radius * 0.25;
|
||||
|
||||
BlockState terrain = EndBlocks.BRIMSTONE.getDefaultState();
|
||||
BlockState rock = EndBlocks.SULPHURIC_ROCK.stone.getDefaultState();
|
||||
int waterLevel = random.nextBoolean() ? -200 : MHelper.floor(pos.getY() - radius * 0.3F);
|
||||
|
||||
for (int x = x1; x <= x2; x++) {
|
||||
int xsq = x - pos.getX();
|
||||
xsq *= xsq;
|
||||
bpos.setX(x);
|
||||
for (int z = z1; z <= z2; z++) {
|
||||
int zsq = z - pos.getZ();
|
||||
zsq *= zsq;
|
||||
bpos.setZ(z);
|
||||
for (int y = y1; y <= y2; y++) {
|
||||
int ysq = y - pos.getY();
|
||||
ysq *= 1.6;
|
||||
ysq *= ysq;
|
||||
bpos.setY(y);
|
||||
double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr;
|
||||
double r2 = r + 5;
|
||||
double dist = xsq + ysq + zsq;
|
||||
if (dist < r * r) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isReplaceable(BlockState state) {
|
||||
return state.isIn(EndTags.GEN_TERRAIN)
|
||||
|| state.getMaterial().isReplaceable()
|
||||
|| state.getMaterial().equals(Material.PLANT)
|
||||
|| state.getMaterial().equals(Material.LEAVES);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue