Stalactites

This commit is contained in:
paulevsGitch 2021-03-09 07:27:38 +03:00
parent 2ac1ec8f5a
commit 7e73d9a31c
39 changed files with 657 additions and 31 deletions

View file

@ -25,6 +25,7 @@ public class BlockProperties {
public static final IntProperty FULLNESS = IntProperty.of("fullness", 0, 3); public static final IntProperty FULLNESS = IntProperty.of("fullness", 0, 3);
public static final IntProperty COLOR = IntProperty.of("color", 0, 7); public static final IntProperty COLOR = IntProperty.of("color", 0, 7);
public static final IntProperty PORTAL = IntProperty.of("portal", 0, EndPortals.getCount()); public static final IntProperty PORTAL = IntProperty.of("portal", 0, EndPortals.getCount());
public static final IntProperty SIZE = IntProperty.of("size", 0, 7);
public static enum TripleShape implements StringIdentifiable { public static enum TripleShape implements StringIdentifiable {
TOP("top"), TOP("top"),

View file

@ -0,0 +1,133 @@
package ru.betterend.blocks.basis;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ShapeContext;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.IntProperty;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.util.math.Direction;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
import ru.betterend.blocks.BlockProperties;
import ru.betterend.patterns.Patterns;
public class StalactiteBlock extends BlockBaseNotFull {
public static final IntProperty SIZE = BlockProperties.SIZE;
private static final Mutable POS = new Mutable();
private static final VoxelShape[] SHAPES;
private final Block source;
public StalactiteBlock(Block source) {
super(FabricBlockSettings.copy(source).nonOpaque());
this.setDefaultState(getStateManager().getDefaultState().with(SIZE, 0));
this.source = source;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) {
stateManager.add(SIZE);
}
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ePos) {
return SHAPES[state.get(SIZE)];
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
if (world.getBlockState(pos.down()).getBlock() instanceof StalactiteBlock) {
POS.setX(pos.getX());
POS.setZ(pos.getZ());
for (int i = 1; i < 8; i++) {
POS.setY(pos.getY() - i);
if (world.getBlockState(POS).getBlock() instanceof StalactiteBlock) {
BlockState state2 = world.getBlockState(POS);
int size = state2.get(SIZE);
if (size < i) {
world.setBlockState(POS, state2.with(SIZE, i));
}
else {
break;
}
}
else {
break;
}
}
}
if (world.getBlockState(pos.up()).getBlock() instanceof StalactiteBlock) {
POS.setX(pos.getX());
POS.setZ(pos.getZ());
for (int i = 1; i < 8; i++) {
POS.setY(pos.getY() + i);
if (world.getBlockState(POS).getBlock() instanceof StalactiteBlock) {
BlockState state2 = world.getBlockState(POS);
int size = state2.get(SIZE);
if (size < i) {
world.setBlockState(POS, state2.with(SIZE, i));
}
else {
break;
}
}
else {
break;
}
}
}
}
@Override
public BlockState getStateForNeighborUpdate(BlockState state, Direction facing, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) {
if (!canPlaceAt(state, world, pos)) {
return Blocks.AIR.getDefaultState();
}
else {
return state;
}
}
@Override
public boolean canPlaceAt(BlockState state, WorldView world, BlockPos pos) {
BlockState upState = world.getBlockState(pos.up());
BlockState downState = world.getBlockState(pos.down());
int size = state.get(SIZE);
boolean validUp = (upState.isOf(this) && upState.get(SIZE) >= size) || upState.isFullCube(world, pos.up());
boolean validDown = (downState.isOf(this) && downState.get(SIZE) >= size) || downState.isFullCube(world, pos.down());
return validUp || validDown;
}
@Override
public String getModelPattern(String block) {
Identifier blockId = Registry.BLOCK.getId(this);
if (block.contains("item")) {
return Patterns.createJson(Patterns.ITEM_GENERATED, "item/" + blockId.getPath());
}
blockId = Registry.BLOCK.getId(source);
int shape = Character.getNumericValue(block.charAt(block.lastIndexOf('_') + 1));
return Patterns.createJson(Patterns.BLOCKS_STALACTITE[shape], blockId.getNamespace() + ":block/" + blockId.getPath());
}
@Override
public Identifier statePatternId() {
return Patterns.STATE_STALACTITE;
}
static {
SHAPES = new VoxelShape[8];
for (int i = 0; i < 8; i++) {
SHAPES[i] = Block.createCuboidShape(7 - i, 0, 7 - i, 9 + i, 16, 9 + i);
}
}
}

View file

@ -0,0 +1,92 @@
package ru.betterend.particle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.AnimatedParticle;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.ParticleTextureSheet;
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 SmaragdantParticle extends AnimatedParticle {
private double preVX;
private double preVY;
private double preVZ;
private double nextVX;
private double nextVY;
private double nextVZ;
protected SmaragdantParticle(ClientWorld world, double x, double y, double z, double r, double g, double b, SpriteProvider sprites) {
super(world, x, y, z, sprites, 0);
setSprite(sprites.getSprite(random));
this.maxAge = MHelper.randRange(60, 120, random);
this.scale = MHelper.randRange(0.05F, 0.15F, random);
this.setColor(1, 1, 1);
this.setColorAlpha(0);
preVX = random.nextGaussian() * 0.01;
preVY = random.nextGaussian() * 0.01;
preVZ = random.nextGaussian() * 0.01;
nextVX = random.nextGaussian() * 0.01;
nextVY = random.nextGaussian() * 0.01;
nextVZ = random.nextGaussian() * 0.01;
}
@Override
public void tick() {
int ticks = this.age & 31;
if (ticks == 0) {
preVX = nextVX;
preVY = nextVY;
preVZ = nextVZ;
nextVX = random.nextGaussian() * 0.015;
nextVY = random.nextFloat() * 0.02 + 0.01;
nextVZ = random.nextGaussian() * 0.015;
}
double delta = (double) ticks / 31.0;
if (this.age <= 31) {
this.setColorAlpha(this.age / 31F);
}
else if (this.age >= this.maxAge - 31) {
this.setColorAlpha((this.maxAge - this.age) / 31F);
}
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 SmaragdantParticleFactory implements ParticleFactory<DefaultParticleType> {
private final SpriteProvider sprites;
public SmaragdantParticleFactory(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 SmaragdantParticle(world, x, y, z, 1, 1, 1, sprites);
}
}
}

View file

@ -46,6 +46,7 @@ public class Patterns {
public final static Identifier STATE_CHANDELIER = BetterEnd.makeID("patterns/blockstate/chandelier.json"); public final static Identifier STATE_CHANDELIER = BetterEnd.makeID("patterns/blockstate/chandelier.json");
public final static Identifier STATE_FURNACE = BetterEnd.makeID("patterns/blockstate/furnace.json"); public final static Identifier STATE_FURNACE = BetterEnd.makeID("patterns/blockstate/furnace.json");
public final static Identifier STATE_ROTATED_TOP = BetterEnd.makeID("patterns/blockstate/rotated_top.json"); public final static Identifier STATE_ROTATED_TOP = BetterEnd.makeID("patterns/blockstate/rotated_top.json");
public final static Identifier STATE_STALACTITE = BetterEnd.makeID("patterns/blockstate/stalactite.json");
//Models Block //Models Block
public final static Identifier BLOCK_EMPTY = BetterEnd.makeID("patterns/block/empty.json"); public final static Identifier BLOCK_EMPTY = BetterEnd.makeID("patterns/block/empty.json");
@ -104,6 +105,17 @@ public class Patterns {
public final static Identifier BLOCK_TOP_SIDE_BOTTOM = BetterEnd.makeID("patterns/block/top_side_bottom.json"); public final static Identifier BLOCK_TOP_SIDE_BOTTOM = BetterEnd.makeID("patterns/block/top_side_bottom.json");
public final static Identifier BLOCK_PATH = BetterEnd.makeID("patterns/block/path.json"); public final static Identifier BLOCK_PATH = BetterEnd.makeID("patterns/block/path.json");
public final static Identifier[] BLOCKS_STALACTITE = new Identifier[] {
BetterEnd.makeID("patterns/block/stalactite_0.json"),
BetterEnd.makeID("patterns/block/stalactite_1.json"),
BetterEnd.makeID("patterns/block/stalactite_2.json"),
BetterEnd.makeID("patterns/block/stalactite_3.json"),
BetterEnd.makeID("patterns/block/stalactite_4.json"),
BetterEnd.makeID("patterns/block/stalactite_5.json"),
BetterEnd.makeID("patterns/block/stalactite_6.json"),
BetterEnd.makeID("patterns/block/stalactite_7.json")
};
//Models Item //Models Item
public final static Identifier ITEM_WALL = BetterEnd.makeID("patterns/item/pattern_wall.json"); public final static Identifier ITEM_WALL = BetterEnd.makeID("patterns/item/pattern_wall.json");
public final static Identifier ITEM_FENCE = BetterEnd.makeID("patterns/item/pattern_fence.json"); public final static Identifier ITEM_FENCE = BetterEnd.makeID("patterns/item/pattern_fence.json");

View file

@ -107,6 +107,7 @@ import ru.betterend.blocks.basis.EndUnderwaterWallPlantBlock;
import ru.betterend.blocks.basis.EndWallPlantBlock; import ru.betterend.blocks.basis.EndWallPlantBlock;
import ru.betterend.blocks.basis.FurBlock; import ru.betterend.blocks.basis.FurBlock;
import ru.betterend.blocks.basis.SimpleLeavesBlock; import ru.betterend.blocks.basis.SimpleLeavesBlock;
import ru.betterend.blocks.basis.StalactiteBlock;
import ru.betterend.blocks.basis.StoneLanternBlock; import ru.betterend.blocks.basis.StoneLanternBlock;
import ru.betterend.blocks.basis.VineBlock; import ru.betterend.blocks.basis.VineBlock;
import ru.betterend.blocks.basis.WallMushroomBlock; import ru.betterend.blocks.basis.WallMushroomBlock;
@ -177,6 +178,8 @@ public class EndBlocks {
public static final Block DENSE_EMERALD_ICE = registerBlock("dense_emerald_ice", new DenseEmeraldIceBlock()); public static final Block DENSE_EMERALD_ICE = registerBlock("dense_emerald_ice", new DenseEmeraldIceBlock());
public static final Block ANCIENT_EMERALD_ICE = registerBlock("ancient_emerald_ice", new AncientEmeraldIceBlock()); public static final Block ANCIENT_EMERALD_ICE = registerBlock("ancient_emerald_ice", new AncientEmeraldIceBlock());
public static final Block END_STONE_STALACTITE = registerBlock("end_stone_stalactite", new StalactiteBlock(Blocks.END_STONE));
// Wooden Materials And Trees // // Wooden Materials And Trees //
public static final Block MOSSY_GLOWSHROOM_SAPLING = registerBlock("mossy_glowshroom_sapling", new MossyGlowshroomSaplingBlock()); public static final Block MOSSY_GLOWSHROOM_SAPLING = registerBlock("mossy_glowshroom_sapling", new MossyGlowshroomSaplingBlock());
public static final Block MOSSY_GLOWSHROOM_CAP = registerBlock("mossy_glowshroom_cap", new MossyGlowshroomCapBlock()); public static final Block MOSSY_GLOWSHROOM_CAP = registerBlock("mossy_glowshroom_cap", new MossyGlowshroomCapBlock());

View file

@ -5,6 +5,7 @@ import java.util.function.Supplier;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.minecraft.block.Blocks;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.GenerationStep;
@ -45,9 +46,10 @@ import ru.betterend.world.features.terrain.GeyserFeature;
import ru.betterend.world.features.terrain.IceStarFeature; import ru.betterend.world.features.terrain.IceStarFeature;
import ru.betterend.world.features.terrain.ObsidianBoulderFeature; import ru.betterend.world.features.terrain.ObsidianBoulderFeature;
import ru.betterend.world.features.terrain.ObsidianPillarBasementFeature; import ru.betterend.world.features.terrain.ObsidianPillarBasementFeature;
import ru.betterend.world.features.terrain.SingleBlockFeature;
import ru.betterend.world.features.terrain.SmaragdantCrystalFeature; import ru.betterend.world.features.terrain.SmaragdantCrystalFeature;
import ru.betterend.world.features.terrain.SmaragdantCrystalShardFeature;
import ru.betterend.world.features.terrain.SpireFeature; import ru.betterend.world.features.terrain.SpireFeature;
import ru.betterend.world.features.terrain.StalactiteFeature;
import ru.betterend.world.features.terrain.SulphurHillFeature; import ru.betterend.world.features.terrain.SulphurHillFeature;
import ru.betterend.world.features.terrain.SulphuricCaveFeature; import ru.betterend.world.features.terrain.SulphuricCaveFeature;
import ru.betterend.world.features.terrain.SulphuricLakeFeature; import ru.betterend.world.features.terrain.SulphuricLakeFeature;
@ -191,8 +193,12 @@ public class EndFeatures {
// Caves // Caves
public static final DefaultFeature SMARAGDANT_CRYSTAL = new SmaragdantCrystalFeature(); public static final DefaultFeature SMARAGDANT_CRYSTAL = new SmaragdantCrystalFeature();
public static final DefaultFeature SMARAGDANT_CRYSTAL_SHARD = new SmaragdantCrystalShardFeature(); public static final DefaultFeature SMARAGDANT_CRYSTAL_SHARD = new SingleBlockFeature(EndBlocks.SMARAGDANT_CRYSTAL_SHARD);
public static final DefaultFeature BIG_AURORA_CRYSTAL = new BigAuroraCrystalFeature(); public static final DefaultFeature BIG_AURORA_CRYSTAL = new BigAuroraCrystalFeature();
public static final DefaultFeature CAVE_BUSH = new BushFeature(EndBlocks.CAVE_BUSH, EndBlocks.CAVE_BUSH);
public static final DefaultFeature CAVE_GRASS = new SingleBlockFeature(EndBlocks.CAVE_GRASS);
public static final DefaultFeature END_STONE_STALACTITE = new StalactiteFeature(true, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE);
public static final DefaultFeature END_STONE_STALAGMITE = new StalactiteFeature(false, EndBlocks.END_STONE_STALACTITE, Blocks.END_STONE);
public static void registerBiomeFeatures(Identifier id, Biome biome, List<List<Supplier<ConfiguredFeature<?, ?>>>> features) { public static void registerBiomeFeatures(Identifier id, Biome biome, List<List<Supplier<ConfiguredFeature<?, ?>>>> features) {
if (id.getNamespace().equals(BetterEnd.MOD_ID)) { if (id.getNamespace().equals(BetterEnd.MOD_ID)) {

View file

@ -18,6 +18,7 @@ import ru.betterend.particle.ParticleSnowflake;
import ru.betterend.particle.ParticleSulphur; import ru.betterend.particle.ParticleSulphur;
import ru.betterend.particle.ParticleTenaneaPetal; import ru.betterend.particle.ParticleTenaneaPetal;
import ru.betterend.particle.PaticlePortalSphere; import ru.betterend.particle.PaticlePortalSphere;
import ru.betterend.particle.SmaragdantParticle;
public class EndParticles { public class EndParticles {
public static final DefaultParticleType GLOWING_SPHERE = register("glowing_sphere"); public static final DefaultParticleType GLOWING_SPHERE = register("glowing_sphere");
@ -31,6 +32,7 @@ public class EndParticles {
public static final DefaultParticleType TENANEA_PETAL = register("tenanea_petal"); public static final DefaultParticleType TENANEA_PETAL = register("tenanea_petal");
public static final DefaultParticleType JUNGLE_SPORE = register("jungle_spore"); public static final DefaultParticleType JUNGLE_SPORE = register("jungle_spore");
public static final DefaultParticleType FIREFLY = register("firefly"); public static final DefaultParticleType FIREFLY = register("firefly");
public static final DefaultParticleType SMARAGDANT = register("smaragdant_particle");
public static void register() { public static void register() {
ParticleFactoryRegistry.getInstance().register(GLOWING_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new); ParticleFactoryRegistry.getInstance().register(GLOWING_SPHERE, ParticleGlowingSphere.FactoryGlowingSphere::new);
@ -44,6 +46,7 @@ public class EndParticles {
ParticleFactoryRegistry.getInstance().register(TENANEA_PETAL, ParticleTenaneaPetal.FactoryTenaneaPetal::new); ParticleFactoryRegistry.getInstance().register(TENANEA_PETAL, ParticleTenaneaPetal.FactoryTenaneaPetal::new);
ParticleFactoryRegistry.getInstance().register(JUNGLE_SPORE, ParticleJungleSpore.FactoryJungleSpore::new); ParticleFactoryRegistry.getInstance().register(JUNGLE_SPORE, ParticleJungleSpore.FactoryJungleSpore::new);
ParticleFactoryRegistry.getInstance().register(FIREFLY, FireflyParticle.FireflyParticleFactory::new); ParticleFactoryRegistry.getInstance().register(FIREFLY, FireflyParticle.FireflyParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(SMARAGDANT, SmaragdantParticle.SmaragdantParticleFactory::new);
} }
private static DefaultParticleType register(String name) { private static DefaultParticleType register(String name) {

View file

@ -24,6 +24,7 @@ import net.minecraft.world.WorldAccess;
import ru.betterend.blocks.BlueVineBlock; import ru.betterend.blocks.BlueVineBlock;
import ru.betterend.blocks.basis.DoublePlantBlock; import ru.betterend.blocks.basis.DoublePlantBlock;
import ru.betterend.blocks.basis.FurBlock; import ru.betterend.blocks.basis.FurBlock;
import ru.betterend.blocks.basis.StalactiteBlock;
import ru.betterend.blocks.basis.VineBlock; import ru.betterend.blocks.basis.VineBlock;
import ru.betterend.registry.EndBlocks; import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndTags; import ru.betterend.registry.EndTags;
@ -207,6 +208,24 @@ public class BlocksHelper {
} }
} }
} }
else if (state.getBlock() instanceof StalactiteBlock) {
if (!state.canPlaceAt(world, POS)) {
if (world.getBlockState(POS.up()).getBlock() instanceof StalactiteBlock) {
while (state.getBlock() instanceof StalactiteBlock) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() + 1);
state = world.getBlockState(POS);
}
}
else {
while (state.getBlock() instanceof StalactiteBlock) {
setWithoutUpdate(world, POS, AIR);
POS.setY(POS.getY() - 1);
state = world.getBlockState(POS);
}
}
}
}
else if (!state.canPlaceAt(world, POS)) { else if (!state.canPlaceAt(world, POS)) {
// Chorus // Chorus
if (state.isOf(Blocks.CHORUS_PLANT)) { if (state.isOf(Blocks.CHORUS_PLANT)) {

View file

@ -14,11 +14,19 @@ public class EmptyAuroraCaveBiome extends EndCaveBiome {
.setWaterAndFogColor(186, 77, 237) .setWaterAndFogColor(186, 77, 237)
.setMusic(EndSounds.MUSIC_FOREST) .setMusic(EndSounds.MUSIC_FOREST)
.setParticles(EndParticles.GLOWING_SPHERE, 0.001F)); .setParticles(EndParticles.GLOWING_SPHERE, 0.001F));
this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1); this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1);
this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1);
} }
@Override @Override
public float getFloorDensity() { public float getFloorDensity() {
return 0.01F; return 0.01F;
} }
@Override
public float getCeilDensity() {
return 0.1F;
}
} }

View file

@ -1,5 +1,6 @@
package ru.betterend.world.biome.cave; package ru.betterend.world.biome.cave;
import ru.betterend.registry.EndFeatures;
import ru.betterend.registry.EndSounds; import ru.betterend.registry.EndSounds;
import ru.betterend.world.biome.land.BiomeDefinition; import ru.betterend.world.biome.land.BiomeDefinition;
@ -8,5 +9,18 @@ public class EmptyEndCaveBiome extends EndCaveBiome {
super(new BiomeDefinition("empty_end_cave") super(new BiomeDefinition("empty_end_cave")
.setFogDensity(2.0F) .setFogDensity(2.0F)
.setMusic(EndSounds.MUSIC_FOREST)); .setMusic(EndSounds.MUSIC_FOREST));
this.addFloorFeature(EndFeatures.END_STONE_STALAGMITE, 1);
this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1);
}
@Override
public float getFloorDensity() {
return 0.1F;
}
@Override
public float getCeilDensity() {
return 0.1F;
} }
} }

View file

@ -13,13 +13,21 @@ public class EmptySmaragdantCaveBiome extends EndCaveBiome {
.setPlantsColor(0, 131, 145) .setPlantsColor(0, 131, 145)
.setWaterAndFogColor(31, 167, 212) .setWaterAndFogColor(31, 167, 212)
.setMusic(EndSounds.MUSIC_FOREST) .setMusic(EndSounds.MUSIC_FOREST)
.setParticles(EndParticles.FIREFLY, 0.001F)); .setParticles(EndParticles.SMARAGDANT, 0.001F));
this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1); this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1);
this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD, 20); this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD, 20);
this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1);
} }
@Override @Override
public float getFloorDensity() { public float getFloorDensity() {
return 0.1F; return 0.1F;
} }
@Override
public float getCeilDensity() {
return 0.1F;
}
} }

View file

@ -34,4 +34,8 @@ public class EndCaveBiome extends EndBiome {
public float getFloorDensity() { public float getFloorDensity() {
return 0; return 0;
} }
public float getCeilDensity() {
return 0;
}
} }

View file

@ -16,11 +16,21 @@ public class LushAuroraCaveBiome extends EndCaveBiome {
.setMusic(EndSounds.MUSIC_FOREST) .setMusic(EndSounds.MUSIC_FOREST)
.setParticles(EndParticles.GLOWING_SPHERE, 0.001F) .setParticles(EndParticles.GLOWING_SPHERE, 0.001F)
.setSurface(EndBlocks.CAVE_MOSS)); .setSurface(EndBlocks.CAVE_MOSS));
this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1); this.addFloorFeature(EndFeatures.BIG_AURORA_CRYSTAL, 1);
this.addFloorFeature(EndFeatures.CAVE_BUSH, 10);
this.addFloorFeature(EndFeatures.CAVE_GRASS, 40);
this.addCeilFeature(EndFeatures.CAVE_BUSH, 1);
} }
@Override @Override
public float getFloorDensity() { public float getFloorDensity() {
return 0.01F; return 0.1F;
}
@Override
public float getCeilDensity() {
return 0.03F;
} }
} }

View file

@ -14,14 +14,22 @@ public class LushSmaragdantCaveBiome extends EndCaveBiome {
.setPlantsColor(0, 131, 145) .setPlantsColor(0, 131, 145)
.setWaterAndFogColor(31, 167, 212) .setWaterAndFogColor(31, 167, 212)
.setMusic(EndSounds.MUSIC_FOREST) .setMusic(EndSounds.MUSIC_FOREST)
.setParticles(EndParticles.FIREFLY, 0.001F) .setParticles(EndParticles.SMARAGDANT, 0.001F)
.setSurface(EndBlocks.CAVE_MOSS)); .setSurface(EndBlocks.CAVE_MOSS));
this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1); this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL, 1);
this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD, 20); this.addFloorFeature(EndFeatures.SMARAGDANT_CRYSTAL_SHARD, 20);
this.addCeilFeature(EndFeatures.END_STONE_STALACTITE, 1);
} }
@Override @Override
public float getFloorDensity() { public float getFloorDensity() {
return 0.1F; return 0.1F;
} }
@Override
public float getCeilDensity() {
return 0.1F;
}
} }

View file

@ -63,7 +63,12 @@ public class BushFeature extends DefaultFeature {
for (Direction d: Direction.values()) { for (Direction d: Direction.values()) {
BlockPos p = pos.offset(d); BlockPos p = pos.offset(d);
if (world.isAir(p)) { if (world.isAir(p)) {
BlocksHelper.setWithoutUpdate(world, p, leaves.getDefaultState().with(LeavesBlock.DISTANCE, 1)); if (leaves instanceof LeavesBlock) {
BlocksHelper.setWithoutUpdate(world, p, leaves.getDefaultState().with(LeavesBlock.DISTANCE, 1));
}
else {
BlocksHelper.setWithoutUpdate(world, p, leaves.getDefaultState());
}
} }
} }

View file

@ -2,27 +2,36 @@ package ru.betterend.world.features.terrain;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.StructureWorldAccess; import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.chunk.ChunkGenerator; import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig; import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndTags; import ru.betterend.registry.EndTags;
import ru.betterend.util.BlocksHelper; import ru.betterend.util.BlocksHelper;
import ru.betterend.world.features.DefaultFeature; import ru.betterend.world.features.DefaultFeature;
public class SmaragdantCrystalShardFeature extends DefaultFeature { public class SingleBlockFeature extends DefaultFeature {
private final Block block;
public SingleBlockFeature(Block block) {
this.block = block;
}
@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) {
if (!world.getBlockState(pos.down()).isIn(EndTags.GEN_TERRAIN)) { if (!world.getBlockState(pos.down()).isIn(EndTags.GEN_TERRAIN)) {
return false; return false;
} }
BlockState shard = EndBlocks.SMARAGDANT_CRYSTAL_SHARD.getDefaultState(); BlockState state = block.getDefaultState();
boolean waterlogged = !world.getFluidState(pos).isEmpty(); if (block.getStateManager().getProperty("waterlogged") != null) {
BlocksHelper.setWithoutUpdate(world, pos, shard.with(Properties.WATERLOGGED, waterlogged)); boolean waterlogged = !world.getFluidState(pos).isEmpty();
state = state.with(Properties.WATERLOGGED, waterlogged);
}
BlocksHelper.setWithoutUpdate(world, pos, state);
return true; return true;
} }

View file

@ -40,13 +40,8 @@ public class SmaragdantCrystalFeature extends DefaultFeature {
BlocksHelper.setWithoutUpdate(world, mut, crystal); BlocksHelper.setWithoutUpdate(world, mut, crystal);
mut.setY(mut.getY() + 1); mut.setY(mut.getY() + 1);
} }
if (random.nextBoolean()) { boolean waterlogged = !world.getFluidState(mut).isEmpty();
boolean waterlogged = !world.getFluidState(mut).isEmpty(); BlocksHelper.setWithoutUpdate(world, mut, shard.with(Properties.WATERLOGGED, waterlogged));
BlocksHelper.setWithoutUpdate(world, mut, shard.with(Properties.WATERLOGGED, waterlogged));
}
else {
BlocksHelper.setWithoutUpdate(world, mut, crystal);
}
} }
} }
} }

View file

@ -0,0 +1,68 @@
package ru.betterend.world.features.terrain;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
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;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import ru.betterend.blocks.basis.StalactiteBlock;
import ru.betterend.registry.EndTags;
import ru.betterend.util.BlocksHelper;
import ru.betterend.world.features.DefaultFeature;
public class StalactiteFeature extends DefaultFeature {
private final boolean ceiling;
private final Block[] ground;
private final Block block;
public StalactiteFeature(boolean ceiling, Block block, Block... ground) {
this.ceiling = ceiling;
this.ground = ground;
this.block = block;
}
@Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
if (!isGround(world.getBlockState(ceiling ? pos.up() : pos.down()).getBlock())) {
return false;
}
Mutable mut = new Mutable().set(pos);
int height = random.nextInt(8);
int dir = ceiling ? -1 : 1;
boolean stalagnate = false;
for (int i = 1; i <= height; i++) {
mut.setY(pos.getY() + i * dir);
BlockState state = world.getBlockState(mut);
if (!state.isAir()) {
stalagnate = state.isIn(EndTags.GEN_TERRAIN);
height = i - 1;
break;
}
}
int center = stalagnate ? height >> 1 : 0;
for (int i = 0; i < height; i++) {
mut.setY(pos.getY() + i * dir);
int size = stalagnate ? MathHelper.abs(i - center) + 1 : height - i - 1;
BlocksHelper.setWithoutUpdate(world, mut, block.getDefaultState().with(StalactiteBlock.SIZE, size));
}
return true;
}
private boolean isGround(Block block) {
for (Block b : ground) {
if (b == block) {
return true;
}
}
return false;
}
}

View file

@ -52,23 +52,31 @@ public abstract class EndCaveFeature extends DefaultFeature {
Set<BlockPos> caveBlocks = generate(world, center, radius, random); Set<BlockPos> caveBlocks = generate(world, center, radius, random);
if (!caveBlocks.isEmpty()) { if (!caveBlocks.isEmpty()) {
if (biome != null) { if (biome != null) {
boolean fillFloor = biome.getFloorDensity() > 0;
boolean fillCeil = biome.getCeilDensity() > 0;
setBiomes(world, biome, caveBlocks); setBiomes(world, biome, caveBlocks);
Set<BlockPos> floorPositions = Sets.newHashSet(); Set<BlockPos> floorPositions = Sets.newHashSet();
Set<BlockPos> ceilPositions = Sets.newHashSet(); Set<BlockPos> ceilPositions = Sets.newHashSet();
Mutable mut = new Mutable(); Mutable mut = new Mutable();
caveBlocks.forEach((bpos) -> { if (fillFloor || fillCeil) {
mut.set(bpos); caveBlocks.forEach((bpos) -> {
if (world.getBlockState(mut).getMaterial().isReplaceable()) { mut.set(bpos);
mut.setY(bpos.getY() - 1); if (world.getBlockState(mut).getMaterial().isReplaceable()) {
if (world.getBlockState(mut).isIn(EndTags.GEN_TERRAIN)) { if (fillFloor) {
floorPositions.add(mut.toImmutable()); mut.setY(bpos.getY() - 1);
if (world.getBlockState(mut).isIn(EndTags.GEN_TERRAIN)) {
floorPositions.add(mut.toImmutable());
}
}
if (fillCeil) {
mut.setY(bpos.getY() + 1);
if (world.getBlockState(mut).isIn(EndTags.GEN_TERRAIN)) {
ceilPositions.add(mut.toImmutable());
}
}
} }
mut.setY(bpos.getY() + 1); });
if (world.getBlockState(mut).isIn(EndTags.GEN_TERRAIN)) { }
ceilPositions.add(mut.toImmutable());
}
}
});
BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceConfig().getTopMaterial(); BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceConfig().getTopMaterial();
placeFloor(world, biome, floorPositions, random, surfaceBlock); placeFloor(world, biome, floorPositions, random, surfaceBlock);
placeCeil(world, biome, ceilPositions, random); placeCeil(world, biome, ceilPositions, random);
@ -100,7 +108,17 @@ public abstract class EndCaveFeature extends DefaultFeature {
} }
protected void placeCeil(StructureWorldAccess world, EndCaveBiome biome, Set<BlockPos> ceilPositions, Random random) { protected void placeCeil(StructureWorldAccess world, EndCaveBiome biome, Set<BlockPos> ceilPositions, Random random) {
float density = biome.getCeilDensity();
if (density > 0) {
ceilPositions.forEach((pos) -> {
if (random.nextFloat() <= density) {
Feature<?> feature = biome.getCeilFeature(random);
if (feature != null) {
feature.generate(world, null, random, pos.down(), null);
}
}
});
}
} }
protected void setBiomes(StructureWorldAccess world, EndCaveBiome biome, Set<BlockPos> blocks) { protected void setBiomes(StructureWorldAccess world, EndCaveBiome biome, Set<BlockPos> blocks) {

View file

@ -0,0 +1,13 @@
{
"textures": [
"betterend:smaragdant_particle_1",
"betterend:smaragdant_particle_2",
"betterend:smaragdant_particle_3",
"betterend:smaragdant_particle_4",
"betterend:smaragdant_particle_5",
"betterend:smaragdant_particle_6",
"betterend:smaragdant_particle_7",
"betterend:smaragdant_particle_8",
"betterend:smaragdant_particle_9"
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 7, 0, 7 ],
"to": [ 9, 16, 9 ],
"faces": {
"down": { "uv": [ 7, 7, 9, 9 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 7, 7, 9, 9 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 7, 0, 9, 16 ], "texture": "#texture" },
"south": { "uv": [ 7, 0, 9, 16 ], "texture": "#texture" },
"west": { "uv": [ 7, 0, 9, 16 ], "texture": "#texture" },
"east": { "uv": [ 7, 0, 9, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 6, 0, 6 ],
"to": [ 10, 16, 10 ],
"faces": {
"down": { "uv": [ 6, 6, 10, 10 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 6, 6, 10, 10 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
"south": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
"west": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" },
"east": { "uv": [ 6, 0, 10, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 5, 0, 5 ],
"to": [ 11, 16, 11 ],
"faces": {
"down": { "uv": [ 5, 5, 11, 11 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 5, 5, 11, 11 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 5, 0, 11, 16 ], "texture": "#texture" },
"south": { "uv": [ 5, 0, 11, 16 ], "texture": "#texture" },
"west": { "uv": [ 5, 0, 11, 16 ], "texture": "#texture" },
"east": { "uv": [ 5, 0, 11, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 4, 0, 4 ],
"to": [ 12, 16, 12 ],
"faces": {
"down": { "uv": [ 4, 4, 12, 12 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 4, 4, 12, 12 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 4, 0, 12, 16 ], "texture": "#texture" },
"south": { "uv": [ 4, 0, 12, 16 ], "texture": "#texture" },
"west": { "uv": [ 4, 0, 12, 16 ], "texture": "#texture" },
"east": { "uv": [ 4, 0, 12, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 3, 0, 3 ],
"to": [ 13, 16, 13 ],
"faces": {
"down": { "uv": [ 3, 3, 13, 13 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 3, 3, 13, 13 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 3, 0, 13, 16 ], "texture": "#texture" },
"south": { "uv": [ 3, 0, 13, 16 ], "texture": "#texture" },
"west": { "uv": [ 3, 0, 13, 16 ], "texture": "#texture" },
"east": { "uv": [ 3, 0, 13, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 2, 0, 2 ],
"to": [ 14, 16, 14 ],
"faces": {
"down": { "uv": [ 2, 2, 14, 14 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 2, 2, 14, 14 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 2, 0, 14, 16 ], "texture": "#texture" },
"south": { "uv": [ 2, 0, 14, 16 ], "texture": "#texture" },
"west": { "uv": [ 2, 0, 14, 16 ], "texture": "#texture" },
"east": { "uv": [ 2, 0, 14, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 1, 0, 1 ],
"to": [ 15, 16, 15 ],
"faces": {
"down": { "uv": [ 1, 1, 15, 15 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 1, 1, 15, 15 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 1, 0, 15, 16 ], "texture": "#texture" },
"south": { "uv": [ 1, 0, 15, 16 ], "texture": "#texture" },
"west": { "uv": [ 1, 0, 15, 16 ], "texture": "#texture" },
"east": { "uv": [ 1, 0, 15, 16 ], "texture": "#texture" }
}
}
]
}

View file

@ -0,0 +1,23 @@
{
"__comment": "Designed by Paulevs with Cubik Studio - https://cubik.studio",
"parent": "block/block",
"textures": {
"particle": "%texture%",
"texture": "%texture%"
},
"elements": [
{
"__comment": "Box1",
"from": [ 0, 0, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "down" },
"up": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "up" },
"north": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "north" },
"south": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "south" },
"west": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "west" },
"east": { "uv": [ 0, 0, 16, 16 ], "texture": "#texture", "cullface": "east" }
}
}
]
}

View file

@ -0,0 +1,13 @@
{
"variants":
{
"size=0": { "model": "betterend:pattern/%block%/%block%_0" },
"size=1": { "model": "betterend:pattern/%block%/%block%_1" },
"size=2": { "model": "betterend:pattern/%block%/%block%_2" },
"size=3": { "model": "betterend:pattern/%block%/%block%_3" },
"size=4": { "model": "betterend:pattern/%block%/%block%_4" },
"size=5": { "model": "betterend:pattern/%block%/%block%_5" },
"size=6": { "model": "betterend:pattern/%block%/%block%_6" },
"size=7": { "model": "betterend:pattern/%block%/%block%_7" }
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B