This commit is contained in:
Aleksey 2020-12-04 09:42:03 +03:00
commit b07faf054c
6 changed files with 203 additions and 8 deletions

View file

@ -30,6 +30,7 @@ import ru.betterend.world.features.terrain.FloatingSpireFeature;
import ru.betterend.world.features.terrain.GeyserFeature; import ru.betterend.world.features.terrain.GeyserFeature;
import ru.betterend.world.features.terrain.RoundCaveFeature; import ru.betterend.world.features.terrain.RoundCaveFeature;
import ru.betterend.world.features.terrain.SpireFeature; import ru.betterend.world.features.terrain.SpireFeature;
import ru.betterend.world.features.terrain.SulphuricCaveFeature;
import ru.betterend.world.features.terrain.SulphuricLakeFeature; import ru.betterend.world.features.terrain.SulphuricLakeFeature;
import ru.betterend.world.features.trees.DragonTreeFeature; import ru.betterend.world.features.trees.DragonTreeFeature;
import ru.betterend.world.features.trees.LacugroveFeature; import ru.betterend.world.features.trees.LacugroveFeature;
@ -96,6 +97,7 @@ public class EndFeatures {
public static final EndFeature FLOATING_SPIRE = EndFeature.makeRawGenFeature("floating_spire", new FloatingSpireFeature(), 8); 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 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_LAKE = EndFeature.makeLakeFeature("sulphuric_lake", new SulphuricLakeFeature(), 8);
public static final EndFeature SULPHURIC_CAVE = EndFeature.makeRawGenFeature("sulphuric_cave", new SulphuricCaveFeature(), 1);
// Ores // // Ores //
public static final EndFeature ENDER_ORE = EndFeature.makeOreFeature("ender_ore", EndBlocks.ENDER_ORE, 6, 3, 0, 4, 96); public static final EndFeature ENDER_ORE = EndFeature.makeOreFeature("ender_ore", EndBlocks.ENDER_ORE, 6, 3, 0, 4, 96);

View file

@ -140,8 +140,10 @@ public abstract class SDF {
if (infos.size() > 0) { if (infos.size() > 0) {
Collections.sort(infos); Collections.sort(infos);
infos.forEach((info) -> { infos.forEach((info) -> {
BlockState state = postProcess.apply(info); info.setState(postProcess.apply(info));
BlocksHelper.setWithoutUpdate(world, info.getPos(), state); });
infos.forEach((info) -> {
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
}); });
infos.clear(); infos.clear();
@ -181,8 +183,10 @@ public abstract class SDF {
if (infos.size() > 0) { if (infos.size() > 0) {
Collections.sort(infos); Collections.sort(infos);
infos.forEach((info) -> { infos.forEach((info) -> {
BlockState state = postProcess.apply(info); info.setState(postProcess.apply(info));
BlocksHelper.setWithoutUpdate(world, info.getPos(), state); });
infos.forEach((info) -> {
BlocksHelper.setWithoutUpdate(world, info.getPos(), info.getState());
}); });
infos.clear(); infos.clear();

View file

@ -23,7 +23,10 @@ import net.minecraft.world.biome.BiomeEffects.Builder;
import net.minecraft.world.biome.BiomeParticleConfig; import net.minecraft.world.biome.BiomeParticleConfig;
import net.minecraft.world.biome.GenerationSettings; import net.minecraft.world.biome.GenerationSettings;
import net.minecraft.world.biome.SpawnSettings; import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.gen.GenerationStep.Carver;
import net.minecraft.world.gen.GenerationStep.Feature; import net.minecraft.world.gen.GenerationStep.Feature;
import net.minecraft.world.gen.ProbabilityConfig;
import net.minecraft.world.gen.carver.ConfiguredCarver;
import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature; import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder; import net.minecraft.world.gen.surfacebuilder.ConfiguredSurfaceBuilder;
@ -42,6 +45,7 @@ public class BiomeDefinition {
private final List<ConfiguredStructureFeature<?, ?>> structures = Lists.newArrayList(); private final List<ConfiguredStructureFeature<?, ?>> structures = Lists.newArrayList();
private final List<FeatureInfo> features = Lists.newArrayList(); private final List<FeatureInfo> features = Lists.newArrayList();
private final List<CarverInfo> carvers = Lists.newArrayList();
private final List<SpawnInfo> mobs = Lists.newArrayList(); private final List<SpawnInfo> mobs = Lists.newArrayList();
private BiomeParticleConfig particleConfig; private BiomeParticleConfig particleConfig;
@ -221,6 +225,7 @@ public class BiomeDefinition {
generationSettings.surfaceBuilder(surface == null ? ConfiguredSurfaceBuilders.END : surface); generationSettings.surfaceBuilder(surface == null ? ConfiguredSurfaceBuilders.END : surface);
structures.forEach((structure) -> generationSettings.structureFeature(structure)); structures.forEach((structure) -> generationSettings.structureFeature(structure));
features.forEach((info) -> generationSettings.feature(info.featureStep, info.feature)); features.forEach((info) -> generationSettings.feature(info.featureStep, info.feature));
carvers.forEach((info) -> generationSettings.carver(info.carverStep, info.carver));
effects.skyColor(0).waterColor(waterColor).waterFogColor(waterFogColor).fogColor(fogColor).foliageColor(foliageColor).grassColor(grassColor); effects.skyColor(0).waterColor(waterColor).waterFogColor(waterFogColor).fogColor(fogColor).foliageColor(foliageColor).grassColor(grassColor);
if (loop != null) effects.loopSound(loop); if (loop != null) effects.loopSound(loop);
@ -253,6 +258,11 @@ public class BiomeDefinition {
Feature featureStep; Feature featureStep;
ConfiguredFeature<?, ?> feature; ConfiguredFeature<?, ?> feature;
} }
private static final class CarverInfo {
Carver carverStep;
ConfiguredCarver<ProbabilityConfig> carver;
}
public Identifier getID() { public Identifier getID() {
return id; return id;
@ -269,4 +279,12 @@ public class BiomeDefinition {
public boolean hasCaves() { public boolean hasCaves() {
return hasCaves; return hasCaves;
} }
public BiomeDefinition addCarver(Carver carverStep, ConfiguredCarver<ProbabilityConfig> carver) {
CarverInfo info = new CarverInfo();
info.carverStep = carverStep;
info.carver = carver;
carvers.add(info);
return this;
}
} }

View file

@ -1,6 +1,8 @@
package ru.betterend.world.biome; package ru.betterend.world.biome;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.carver.ConfiguredCarvers;
import ru.betterend.registry.EndFeatures; import ru.betterend.registry.EndFeatures;
import ru.betterend.registry.EndParticles; import ru.betterend.registry.EndParticles;
import ru.betterend.world.surface.SurfaceBuilders; import ru.betterend.world.surface.SurfaceBuilders;
@ -16,6 +18,8 @@ public class BiomeSulfurSprings extends EndBiome {
.setParticles(EndParticles.SULPHUR_PARTICLE, 0.001F) .setParticles(EndParticles.SULPHUR_PARTICLE, 0.001F)
.addFeature(EndFeatures.GEYSER) .addFeature(EndFeatures.GEYSER)
.addFeature(EndFeatures.SULPHURIC_LAKE) .addFeature(EndFeatures.SULPHURIC_LAKE)
.addFeature(EndFeatures.SULPHURIC_CAVE)
.addCarver(GenerationStep.Carver.AIR, ConfiguredCarvers.CAVE)
.addMobSpawn(EntityType.ENDERMAN, 50, 1, 4)); .addMobSpawn(EntityType.ENDERMAN, 50, 1, 4));
} }
} }

View file

@ -9,6 +9,7 @@ import net.minecraft.block.LeavesBlock;
import net.minecraft.block.Material; import net.minecraft.block.Material;
import net.minecraft.client.util.math.Vector3f; import net.minecraft.client.util.math.Vector3f;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.chunk.ChunkGenerator; 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.noise.OpenSimplexNoise;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndTags; import ru.betterend.registry.EndTags;
import ru.betterend.util.BlocksHelper;
import ru.betterend.util.MHelper; import ru.betterend.util.MHelper;
import ru.betterend.util.sdf.SDF; import ru.betterend.util.sdf.SDF;
import ru.betterend.util.sdf.operator.SDFCoordModify; 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.SDFInvert;
import ru.betterend.util.sdf.operator.SDFRotation; 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.SDFSubtraction;
import ru.betterend.util.sdf.operator.SDFTranslate; import ru.betterend.util.sdf.operator.SDFTranslate;
import ru.betterend.util.sdf.operator.SDFUnion; import ru.betterend.util.sdf.operator.SDFUnion;
import ru.betterend.util.sdf.primitive.SDFCapedCone; import ru.betterend.util.sdf.primitive.SDFCapedCone;
import ru.betterend.util.sdf.primitive.SDFFlatland; 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; import ru.betterend.world.features.DefaultFeature;
public class GeyserFeature extends 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 @Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) { 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); bowl = new SDFRotation().setRotation(Vector3f.POSITIVE_Y, i * 4F).setSource(bowl);
sdf = /*new SDFSmoothUnion()*/new SDFUnion()/*.setRadius(3)*/.setSourceA(sdf).setSourceB(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; return true;
} }
@ -102,8 +163,12 @@ public class GeyserFeature extends DefaultFeature {
} }
static { static {
REPLACE = (state) -> { REPLACE1 = (state) -> {
if (state.isIn(EndTags.END_GROUND)) { 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; return true;
} }
if (state.getBlock() instanceof LeavesBlock) { if (state.getBlock() instanceof LeavesBlock) {

View file

@ -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);
}
}