Sulphuric terrain, lakes, particles

This commit is contained in:
paulevsGitch 2020-12-02 03:55:11 +03:00
parent e051bf3578
commit b375d76956
19 changed files with 384 additions and 14 deletions

View file

@ -2,9 +2,7 @@ package ru.betterend;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Identifier;
import ru.betterend.api.BetterEndPlugin;
import ru.betterend.config.MainConfig;
import ru.betterend.effects.EndEnchantments;
@ -25,6 +23,7 @@ import ru.betterend.registry.EndStructures;
import ru.betterend.registry.EndTags;
import ru.betterend.util.Logger;
import ru.betterend.world.generator.BetterEndBiomeSource;
import ru.betterend.world.surface.SurfaceBuilders;
public class BetterEnd implements ModInitializer {
public static final String MOD_ID = "betterend";
@ -37,6 +36,7 @@ public class BetterEnd implements ModInitializer {
EndBlockEntities.register();
EndFeatures.register();
EndEntities.register();
SurfaceBuilders.register();
EndBiomes.register();
BetterEndBiomeSource.register();
EndTags.register();

View file

@ -10,7 +10,6 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Lists;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
@ -37,7 +36,6 @@ import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import ru.betterend.blocks.BlockProperties;
import ru.betterend.blocks.BlockProperties.PedestalState;
import ru.betterend.blocks.entities.PedestalBlockEntity;

View file

@ -10,7 +10,6 @@ import com.google.gson.JsonObject;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import ru.betterend.BetterEnd;
public final class ConfigKeeper {

View file

@ -1,6 +1,7 @@
package ru.betterend.config;
import org.jetbrains.annotations.Nullable;
import net.minecraft.util.Identifier;
import ru.betterend.config.ConfigKeeper.Entry;

View file

@ -9,7 +9,6 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry.ModelProvider;
import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry.TextureProvider;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.entity.EquipmentSlot;
@ -17,7 +16,6 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import ru.betterend.BetterEnd;
import ru.betterend.registry.EndItems;

View file

@ -6,7 +6,6 @@ import com.google.common.collect.Lists;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.entity.model.BipedEntityModel;

View file

@ -0,0 +1,95 @@
package ru.betterend.particle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.ParticleTextureSheet;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.DefaultParticleType;
import net.minecraft.util.math.MathHelper;
import ru.betterend.util.MHelper;
@Environment(EnvType.CLIENT)
public class ParticleSulphur extends SpriteBillboardParticle {
private int ticks;
private double preVX;
private double preVY;
private double preVZ;
private double nextVX;
private double nextVY;
private double nextVZ;
protected ParticleSulphur(ClientWorld world, double x, double y, double z, double r, double g, double b, SpriteProvider sprites) {
super(world, x, y, z, r, g, b);
setSprite(sprites);
this.maxAge = MHelper.randRange(150, 300, random);
this.scale = MHelper.randRange(0.05F, 0.15F, random);
preVX = random.nextGaussian() * 0.015;
preVY = random.nextGaussian() * 0.015;
preVZ = random.nextGaussian() * 0.015;
nextVX = random.nextGaussian() * 0.015;
nextVY = random.nextGaussian() * 0.015;
nextVZ = random.nextGaussian() * 0.015;
}
@Override
public void tick() {
ticks ++;
if (ticks > 200) {
preVX = nextVX;
preVY = nextVY;
preVZ = nextVZ;
nextVX = random.nextGaussian() * 0.015;
nextVY = random.nextGaussian() * 0.015;
nextVZ = random.nextGaussian() * 0.015;
if (random.nextInt(4) == 0) {
nextVY = Math.abs(nextVY);
}
ticks = 0;
}
double delta = (double) ticks / 200.0;
if (this.age <= 40) {
this.setColorAlpha(this.age / 40F);
}
else if (this.age >= this.maxAge + 40) {
this.setColorAlpha((this.maxAge - this.age) / 40F);
}
if (this.age >= this.maxAge) {
this.markDead();
}
this.velocityX = MathHelper.lerp(delta, preVX, nextVX);
this.velocityY = MathHelper.lerp(delta, preVY, nextVY);
this.velocityZ = MathHelper.lerp(delta, preVZ, nextVZ);
super.tick();
}
@Override
public ParticleTextureSheet getType() {
return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
}
@Environment(EnvType.CLIENT)
public static class FactorySulphur implements ParticleFactory<DefaultParticleType> {
private final SpriteProvider sprites;
public FactorySulphur(SpriteProvider sprites) {
this.sprites = sprites;
}
@Override
public Particle createParticle(DefaultParticleType type, ClientWorld world, double x, double y, double z, double vX, double vY, double vZ) {
return new ParticleSulphur(world, x, y, z, 1, 1, 1, sprites);
}
}
}

View file

@ -26,6 +26,7 @@ import net.minecraft.world.biome.BiomeKeys;
import ru.betterend.BetterEnd;
import ru.betterend.util.JsonFactory;
import ru.betterend.world.biome.BiomeAmberLand;
import ru.betterend.world.biome.BiomeBlossomingSpires;
import ru.betterend.world.biome.BiomeChorusForest;
import ru.betterend.world.biome.BiomeCrystalMountains;
import ru.betterend.world.biome.BiomeDustWastelands;
@ -34,9 +35,8 @@ import ru.betterend.world.biome.BiomeMegalake;
import ru.betterend.world.biome.BiomeMegalakeGrove;
import ru.betterend.world.biome.BiomePaintedMountains;
import ru.betterend.world.biome.BiomeShadowForest;
import ru.betterend.world.biome.BiomeBlossomingSpires;
import ru.betterend.world.biome.EndBiome;
import ru.betterend.world.biome.BiomeSulfurSprings;
import ru.betterend.world.biome.EndBiome;
import ru.betterend.world.generator.BiomePicker;
import ru.betterend.world.generator.BiomeType;

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.RoundCaveFeature;
import ru.betterend.world.features.terrain.SpireFeature;
import ru.betterend.world.features.terrain.SulphuricLakeFeature;
import ru.betterend.world.features.trees.DragonTreeFeature;
import ru.betterend.world.features.trees.LacugroveFeature;
import ru.betterend.world.features.trees.MossyGlowshroomFeature;
@ -94,6 +95,7 @@ public class EndFeatures {
public static final EndFeature SPIRE = EndFeature.makeRawGenFeature("spire", new SpireFeature(), 2);
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);
// Ores //
public static final EndFeature ENDER_ORE = EndFeature.makeOreFeature("ender_ore", EndBlocks.ENDER_ORE, 6, 3, 0, 4, 96);

View file

@ -10,17 +10,20 @@ import ru.betterend.BetterEnd;
import ru.betterend.particle.InfusionParticle;
import ru.betterend.particle.InfusionParticleType;
import ru.betterend.particle.ParticleGlowingSphere;
import ru.betterend.particle.ParticleSulphur;
import ru.betterend.particle.PaticlePortalSphere;
public class EndParticles {
public static final DefaultParticleType GLOWING_SPHERE = register("glowing_sphere");
public static final DefaultParticleType PORTAL_SPHERE = register("portal_sphere");
public static final ParticleType<InfusionParticleType> INFUSION = register("infusion", FabricParticleTypes.complex(InfusionParticleType.PARAMETERS_FACTORY));
public static final DefaultParticleType SULPHUR_PARTICLE = register("sulphur_particle");
public static void register() {
ParticleFactoryRegistry.getInstance().register(GLOWING_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new);
ParticleFactoryRegistry.getInstance().register(PORTAL_SPHERE, PaticlePortalSphere.FactoryPortalSphere::new);
ParticleFactoryRegistry.getInstance().register(INFUSION, InfusionParticle.DefaultFactory::new);
ParticleFactoryRegistry.getInstance().register(SULPHUR_PARTICLE, ParticleSulphur.FactorySulphur::new);
}
private static DefaultParticleType register(String name) {

View file

@ -71,7 +71,7 @@ public class EndTags {
}
});
TagHelper.addTag(GEN_TERRAIN, EndBlocks.ENDER_ORE, EndBlocks.FLAVOLITE.stone, EndBlocks.VIOLECITE.stone);
TagHelper.addTag(GEN_TERRAIN, EndBlocks.ENDER_ORE, EndBlocks.FLAVOLITE.stone, EndBlocks.VIOLECITE.stone, EndBlocks.SULFURIC_ROCK.stone, EndBlocks.BRIMSTONE);
ToolManagerImpl.tag(HAMMERS).register(new ModdedToolsVanillaBlocksToolHandler(
Arrays.asList(

View file

@ -35,6 +35,7 @@ import ru.betterend.util.MHelper;
import ru.betterend.world.features.EndFeature;
import ru.betterend.world.structures.EndStructureFeature;
import ru.betterend.world.surface.DoubleBlockSurfaceBuilder;
import ru.betterend.world.surface.SurfaceBuilders;
public class BiomeDefinition {
private static final int DEF_FOLIAGE = MHelper.color(197, 210, 112);
@ -84,6 +85,10 @@ public class BiomeDefinition {
return this;
}
public BiomeDefinition setSurface(SurfaceBuilder<TernarySurfaceConfig> builder) {
return setSurface(builder.withConfig(SurfaceBuilders.DEFAULT_END_CONFIG));
}
public BiomeDefinition setParticles(ParticleEffect particle, float probability) {
this.particleConfig = new BiomeParticleConfig(particle, probability);
return this;

View file

@ -1,14 +1,19 @@
package ru.betterend.world.biome;
import net.minecraft.entity.EntityType;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndFeatures;
import ru.betterend.registry.EndParticles;
import ru.betterend.world.surface.SurfaceBuilders;
public class BiomeSulfurSprings extends EndBiome {
public BiomeSulfurSprings() {
super(new BiomeDefinition("sulfur_springs")
.setSurface(EndBlocks.SULFURIC_ROCK.stone)
.setSurface(SurfaceBuilders.SULPHURIC_SURFACE)
.setFogColor(207, 194, 62)
.setFogDensity(1.5F)
.setParticles(EndParticles.SULPHUR_PARTICLE, 0.001F)
.addFeature(EndFeatures.GEYSER)
.addFeature(EndFeatures.SULPHURIC_LAKE)
.addMobSpawn(EntityType.ENDERMAN, 50, 1, 4));
}
}

View file

@ -19,7 +19,6 @@ import ru.betterend.registry.EndTags;
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.SDFSubtraction;

View file

@ -0,0 +1,191 @@
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.fluid.Fluids;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.Direction;
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;
import ru.betterend.util.BlocksHelper;
import ru.betterend.util.MHelper;
import ru.betterend.world.features.DefaultFeature;
public class SulphuricLakeFeature extends DefaultFeature {
private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(15152);
private static final Mutable POS = new Mutable();
@Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos blockPos, DefaultFeatureConfig featureConfig) {
blockPos = getPosOnSurfaceWG(world, blockPos);
if (blockPos.getY() < 57) {
return false;
}
double radius = MHelper.randRange(10.0, 20.0, random);
int dist2 = MHelper.floor(radius * 1.5);
int minX = blockPos.getX() - dist2;
int maxX = blockPos.getX() + dist2;
int minZ = blockPos.getZ() - dist2;
int maxZ = blockPos.getZ() + dist2;
Set<BlockPos> brimstone = Sets.newHashSet();
for (int x = minX; x <= maxX; x++) {
POS.setX(x);
int x2 = x - blockPos.getX();
x2 *= x2;
for (int z = minZ; z <= maxZ; z++) {
POS.setZ(z);
int z2 = z - blockPos.getZ();
z2 *= z2;
double r = radius * (NOISE.eval(x * 0.2, z * 0.2) * 0.25 + 0.75);
double r2 = r * 1.5;
r *= r;
r2 *= r2;
int dist = x2 + z2;
if (dist <= r) {
POS.setY(getYOnSurface(world, x, z) - 1);
if (world.getBlockState(POS).isIn(EndTags.GEN_TERRAIN)) {
if (isBorder(world, POS)) {
if (random.nextInt(8) > 0) {
brimstone.add(POS.toImmutable());
if (random.nextBoolean()) {
brimstone.add(POS.down());
if (random.nextBoolean()) {
brimstone.add(POS.down(2));
}
}
}
else {
if (!isAbsoluteBorder(world, POS)) {
BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER);
world.getFluidTickScheduler().schedule(POS, Fluids.WATER, 0);
brimstone.add(POS.down());
if (random.nextBoolean()) {
brimstone.add(POS.down(2));
if (random.nextBoolean()) {
brimstone.add(POS.down(3));
}
}
}
else {
brimstone.add(POS.toImmutable());
if (random.nextBoolean()) {
brimstone.add(POS.down());
}
}
}
}
else {
BlocksHelper.setWithoutUpdate(world, POS, Blocks.WATER);
if (isDeepWater(world, POS)) {
BlocksHelper.setWithoutUpdate(world, POS.move(Direction.DOWN), Blocks.WATER);
}
brimstone.add(POS.down());
if (random.nextBoolean()) {
brimstone.add(POS.down(2));
if (random.nextBoolean()) {
brimstone.add(POS.down(3));
}
}
}
}
}
else if (dist < r2) {
POS.setY(getYOnSurface(world, x, z) - 1);
if (world.getBlockState(POS).isIn(EndTags.GEN_TERRAIN)) {
brimstone.add(POS.toImmutable());
if (random.nextBoolean()) {
brimstone.add(POS.down());
if (random.nextBoolean()) {
brimstone.add(POS.down(2));
}
}
}
}
}
}
brimstone.forEach((bpos) -> {
placeBrimstone(world, bpos, random);
});
return true;
}
private boolean isBorder(StructureWorldAccess world, BlockPos pos) {
int y = pos.getY() + 1;
for (Direction dir: BlocksHelper.DIRECTIONS) {
if (getYOnSurface(world, pos.getX() + dir.getOffsetX(), pos.getZ() + dir.getOffsetZ()) < y) {
return true;
}
}
return false;
}
private boolean isAbsoluteBorder(StructureWorldAccess world, BlockPos pos) {
int y = pos.getY() - 2;
for (Direction dir: BlocksHelper.DIRECTIONS) {
if (getYOnSurface(world, pos.getX() + dir.getOffsetX() * 3, pos.getZ() + dir.getOffsetZ() * 3) < y) {
return true;
}
}
return false;
}
private boolean isDeepWater(StructureWorldAccess world, BlockPos pos) {
int y = pos.getY() + 1;
for (Direction dir: BlocksHelper.DIRECTIONS) {
if (getYOnSurface(world, pos.getX() + dir.getOffsetX(), pos.getZ() + dir.getOffsetZ()) < y
|| getYOnSurface(world, pos.getX() + dir.getOffsetX() * 2, pos.getZ() + dir.getOffsetZ() * 2) < y
|| getYOnSurface(world, pos.getX() + dir.getOffsetX() * 3, pos.getZ() + dir.getOffsetZ() * 3) < y) {
return false;
}
}
return true;
}
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(4) == 0 && world.getBlockState((side = pos.offset(dir))).getMaterial().isReplaceable()) {
BlockState state = EndBlocks.SULPHUR_CRYSTAL.getDefaultState()
.with(BlockSulphurCrystal.WATERLOGGED, world.getBlockState(side).isOf(Blocks.WATER))
.with(BlockSulphurCrystal.FACING, dir)
.with(BlockSulphurCrystal.AGE, random.nextInt(3));
BlocksHelper.setWithoutUpdate(world, side, state);
}
}
}
}

View file

@ -0,0 +1,41 @@
package ru.betterend.world.surface;
import java.util.Random;
import net.minecraft.block.BlockState;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder;
import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.util.MHelper;
public class SulphuricSurfaceBuilder extends SurfaceBuilder<TernarySurfaceConfig> {
private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(5123);
public SulphuricSurfaceBuilder() {
super(TernarySurfaceConfig.CODEC);
}
@Override
public void generate(Random random, Chunk chunk, Biome biome, int x, int z, int height, double noise, BlockState defaultBlock, BlockState defaultFluid, int seaLevel, long seed, TernarySurfaceConfig surfaceBlocks) {
double value = NOISE.eval(x * 0.03, z * 0.03) + NOISE.eval(x * 0.1, z * 0.1) * 0.3 + MHelper.randRange(-0.1, 0.1, MHelper.RANDOM);
if (value < -0.6) {
SurfaceBuilder.DEFAULT.generate(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.DEFAULT_END_CONFIG);
}
else if (value < -0.3) {
SurfaceBuilder.DEFAULT.generate(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.FLAVOLITE_CONFIG);
}
else if (value < 0.5) {
SurfaceBuilder.DEFAULT.generate(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.SULFURIC_ROCK_CONFIG);
}
else {
SurfaceBuilder.DEFAULT.generate(random, chunk, biome, x, z, height, noise, defaultBlock, defaultFluid, seaLevel, seed, SurfaceBuilders.BRIMSTONE_CONFIG);
}
}
public static SulphuricSurfaceBuilder register(String name) {
return Registry.register(Registry.SURFACE_BUILDER, name, new SulphuricSurfaceBuilder());
}
}

View file

@ -0,0 +1,29 @@
package ru.betterend.world.surface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder;
import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig;
import ru.betterend.registry.EndBlocks;
public class SurfaceBuilders {
public static final TernarySurfaceConfig DEFAULT_END_CONFIG = makeSimpleConfig(Blocks.END_STONE);
public static final TernarySurfaceConfig FLAVOLITE_CONFIG = makeSimpleConfig(EndBlocks.FLAVOLITE.stone);
public static final TernarySurfaceConfig BRIMSTONE_CONFIG = makeSimpleConfig(EndBlocks.BRIMSTONE);
public static final TernarySurfaceConfig SULFURIC_ROCK_CONFIG = makeSimpleConfig(EndBlocks.SULFURIC_ROCK.stone);
public static final SurfaceBuilder<TernarySurfaceConfig> SULPHURIC_SURFACE = register("sulphuric_surface", new SulphuricSurfaceBuilder());
private static SurfaceBuilder<TernarySurfaceConfig> register(String name, SurfaceBuilder<TernarySurfaceConfig> builder) {
return Registry.register(Registry.SURFACE_BUILDER, name, builder);
}
private static TernarySurfaceConfig makeSimpleConfig(Block block) {
BlockState state = block.getDefaultState();
return new TernarySurfaceConfig(state, state, state);
}
public static void register() {}
}

View file

@ -0,0 +1,5 @@
{
"textures": [
"betterend:sulphur_particle"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB