Dragon Graveyards prototype
This commit is contained in:
parent
05b4e80a9d
commit
0dfcc950ca
15 changed files with 313 additions and 7 deletions
56
src/main/java/ru/betterend/blocks/MossyObsidian.java
Normal file
56
src/main/java/ru/betterend/blocks/MossyObsidian.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package ru.betterend.blocks;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.SnowBlock;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.context.LootContext;
|
||||
import net.minecraft.loot.context.LootContextParameters;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.WorldView;
|
||||
import net.minecraft.world.chunk.light.ChunkLightProvider;
|
||||
import ru.betterend.blocks.basis.BlockBase;
|
||||
|
||||
public class MossyObsidian extends BlockBase {
|
||||
public MossyObsidian() {
|
||||
super(FabricBlockSettings.copyOf(Blocks.OBSIDIAN).hardness(3).ticksRandomly());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDroppedStacks(BlockState state, LootContext.Builder builder) {
|
||||
ItemStack tool = builder.get(LootContextParameters.TOOL);
|
||||
if (tool != null && EnchantmentHelper.getLevel(Enchantments.SILK_TOUCH, tool) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
}
|
||||
return Collections.singletonList(new ItemStack(Blocks.OBSIDIAN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
||||
if (random.nextInt(16) == 0 && !canSurvive(state, world, pos)) {
|
||||
world.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canSurvive(BlockState state, WorldView worldView, BlockPos pos) {
|
||||
BlockPos blockPos = pos.up();
|
||||
BlockState blockState = worldView.getBlockState(blockPos);
|
||||
if (blockState.isOf(Blocks.SNOW) && (Integer)blockState.get(SnowBlock.LAYERS) == 1) {
|
||||
return true;
|
||||
} else if (blockState.getFluidState().getLevel() == 8) {
|
||||
return false;
|
||||
} else {
|
||||
int i = ChunkLightProvider.getRealisticOpacity(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getOpacity(worldView, blockPos));
|
||||
return i < 5;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@ import ru.betterend.world.biome.BiomePaintedMountains;
|
|||
import ru.betterend.world.biome.BiomeShadowForest;
|
||||
import ru.betterend.world.biome.BiomeSulphurSprings;
|
||||
import ru.betterend.world.biome.BiomeUmbrellaJungle;
|
||||
import ru.betterend.world.biome.DragonGraveyardsBiome;
|
||||
import ru.betterend.world.biome.EndBiome;
|
||||
import ru.betterend.world.biome.GlowingGrasslandsBiome;
|
||||
import ru.betterend.world.generator.BELayerRandomSource;
|
||||
|
@ -85,6 +86,7 @@ public class EndBiomes {
|
|||
public static final EndBiome SULPHUR_SPRINGS = registerBiome(new BiomeSulphurSprings(), BiomeType.LAND);
|
||||
public static final EndBiome UMBRELLA_JUNGLE = registerBiome(new BiomeUmbrellaJungle(), BiomeType.LAND);
|
||||
public static final EndBiome GLOWING_GRASSLANDS = registerBiome(new GlowingGrasslandsBiome(), BiomeType.LAND);
|
||||
public static final EndBiome DRAGON_GRAVEYARDS = registerBiome(new DragonGraveyardsBiome(), BiomeType.LAND);
|
||||
|
||||
// Better End Void
|
||||
public static final EndBiome ICE_STARFIELD = registerBiome(new BiomeIceStarfield(), BiomeType.VOID);
|
||||
|
|
|
@ -67,6 +67,7 @@ import ru.betterend.blocks.MissingTileBlock;
|
|||
import ru.betterend.blocks.MossyGlowshroomCapBlock;
|
||||
import ru.betterend.blocks.MossyGlowshroomHymenophoreBlock;
|
||||
import ru.betterend.blocks.MossyGlowshroomSaplingBlock;
|
||||
import ru.betterend.blocks.MossyObsidian;
|
||||
import ru.betterend.blocks.MurkweedBlock;
|
||||
import ru.betterend.blocks.NeedlegrassBlock;
|
||||
import ru.betterend.blocks.PedestalVanilla;
|
||||
|
@ -133,6 +134,8 @@ public class EndBlocks {
|
|||
public static final Block AMBER_MOSS_PATH = registerBlock("amber_moss_path", new EndPathBlock(AMBER_MOSS));
|
||||
public static final Block JUNGLE_MOSS_PATH = registerBlock("jungle_moss_path", new EndPathBlock(JUNGLE_MOSS));
|
||||
|
||||
public static final Block MOSSY_OBSIDIAN = registerBlock("mossy_obsidian", new MossyObsidian());
|
||||
|
||||
// Rocks //
|
||||
public static final StoneMaterial FLAVOLITE = new StoneMaterial("flavolite", MaterialColor.SAND);
|
||||
public static final StoneMaterial VIOLECITE = new StoneMaterial("violecite", MaterialColor.PURPLE);
|
||||
|
|
|
@ -37,9 +37,12 @@ import ru.betterend.world.features.bushes.BushFeature;
|
|||
import ru.betterend.world.features.bushes.Lumecorn;
|
||||
import ru.betterend.world.features.bushes.TenaneaBushFeature;
|
||||
import ru.betterend.world.features.terrain.EndLakeFeature;
|
||||
import ru.betterend.world.features.terrain.FallenPillarFeature;
|
||||
import ru.betterend.world.features.terrain.FloatingSpireFeature;
|
||||
import ru.betterend.world.features.terrain.GeyserFeature;
|
||||
import ru.betterend.world.features.terrain.IceStarFeature;
|
||||
import ru.betterend.world.features.terrain.ObsidianBoulderFeature;
|
||||
import ru.betterend.world.features.terrain.ObsidianPillarBasementFeature;
|
||||
import ru.betterend.world.features.terrain.RoundCaveFeature;
|
||||
import ru.betterend.world.features.terrain.SpireFeature;
|
||||
import ru.betterend.world.features.terrain.SulphurHillFeature;
|
||||
|
@ -157,6 +160,9 @@ public class EndFeatures {
|
|||
public static final EndFeature ICE_STAR_SMALL = EndFeature.makeRawGenFeature("ice_star_small", new IceStarFeature(3, 5, 7, 12), 8);
|
||||
public static final EndFeature SURFACE_VENT = EndFeature.makeChansedFeature("surface_vent", new SurfaceVentFeature(), 4);
|
||||
public static final EndFeature SULPHUR_HILL = EndFeature.makeChansedFeature("sulphur_hill", new SulphurHillFeature(), 8);
|
||||
public static final EndFeature OBSIDIAN_PILLAR_BASEMENT = EndFeature.makeChansedFeature("obsidian_pillar_basement", new ObsidianPillarBasementFeature(), 8);
|
||||
public static final EndFeature OBSIDIAN_BOULDER = EndFeature.makeChansedFeature("obsidian_boulder", new ObsidianBoulderFeature(), 10);
|
||||
public static final EndFeature FALLEN_PILLAR = EndFeature.makeChansedFeature("fallen_pillar", new FallenPillarFeature(), 20);
|
||||
|
||||
// Ores //
|
||||
public static final EndFeature THALLASIUM_ORE = EndFeature.makeOreFeature("thallasium_ore", EndBlocks.THALLASIUM.ore, 12, 6, 0, 16, 128);
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Random;
|
|||
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import ru.betterend.util.sdf.operator.SDFRotation;
|
||||
|
||||
public class MHelper {
|
||||
public static final float PI2 = (float) (Math.PI * 2);
|
||||
|
@ -325,11 +326,17 @@ public class MHelper {
|
|||
return vec;
|
||||
}
|
||||
|
||||
public static float angle(Vector3f vec1, Vector3f vec2)
|
||||
{
|
||||
public static float angle(Vector3f vec1, Vector3f vec2) {
|
||||
float dot = vec1.getX() * vec2.getX() + vec1.getY() * vec2.getY() + vec1.getZ() * vec2.getZ();
|
||||
float length1 = lengthSqr(vec1.getX(), vec1.getY(), vec1.getZ());
|
||||
float length2 = lengthSqr(vec2.getX(), vec2.getY(), vec2.getZ());
|
||||
return (float) Math.acos(dot / Math.sqrt(length1 * length2));
|
||||
}
|
||||
|
||||
public static Vector3f randomHorizontal(Random random) {
|
||||
float angleY = MHelper.randRange(0, MHelper.PI2, random);
|
||||
float vx = (float) Math.sin(angleY);
|
||||
float vz = (float) Math.cos(angleY);
|
||||
return new Vector3f(vx, 0, vz);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package ru.betterend.world.biome;
|
||||
|
||||
import net.minecraft.entity.EntityType;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.registry.EndFeatures;
|
||||
import ru.betterend.registry.EndSounds;
|
||||
|
||||
public class DragonGraveyardsBiome extends EndBiome {
|
||||
public DragonGraveyardsBiome() {
|
||||
super(new BiomeDefinition("dragon_graveyards")
|
||||
.setGenChance(0.1F)
|
||||
.setFogColor(244, 46, 79)
|
||||
.setFogDensity(1.1F)
|
||||
.setMusic(EndSounds.MUSIC_OPENSPACE)
|
||||
.setLoop(EndSounds.AMBIENT_GLOWING_GRASSLANDS)
|
||||
.setSurface(EndBlocks.CAVE_MOSS)
|
||||
.setWaterAndFogColor(203, 59, 167)
|
||||
.setPlantsColor(244, 46, 79)
|
||||
.addFeature(EndFeatures.OBSIDIAN_PILLAR_BASEMENT)
|
||||
.addFeature(EndFeatures.FALLEN_PILLAR)
|
||||
.addFeature(EndFeatures.OBSIDIAN_BOULDER)
|
||||
.addMobSpawn(EntityType.ENDERMAN, 50, 1, 2));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
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.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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.MHelper;
|
||||
import ru.betterend.util.sdf.SDF;
|
||||
import ru.betterend.util.sdf.operator.SDFDisplacement;
|
||||
import ru.betterend.util.sdf.operator.SDFRotation;
|
||||
import ru.betterend.util.sdf.operator.SDFTranslate;
|
||||
import ru.betterend.util.sdf.primitive.SDFCappedCone;
|
||||
import ru.betterend.world.features.DefaultFeature;
|
||||
|
||||
public class FallenPillarFeature extends DefaultFeature {
|
||||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
|
||||
pos = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)));
|
||||
if (!world.getBlockState(pos.down(5)).isIn(EndTags.GEN_TERRAIN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float height = MHelper.randRange(20F, 40F, random);
|
||||
float radius = MHelper.randRange(2F, 4F, random);
|
||||
SDF pillar = new SDFCappedCone().setRadius1(radius).setRadius2(radius).setHeight(height * 0.5F).setBlock(Blocks.OBSIDIAN);
|
||||
pillar = new SDFTranslate().setTranslate(0, radius * 0.5F - 2, 0).setSource(pillar);
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong());
|
||||
pillar = new SDFDisplacement().setFunction((vec) -> {
|
||||
return (float) (noise.eval(vec.getX() * 0.3, vec.getY() * 0.3, vec.getZ() * 0.3) * 0.5F);
|
||||
}).setSource(pillar);
|
||||
Vector3f vec = MHelper.randomHorizontal(random);
|
||||
float angle = (float) random.nextGaussian() * 0.05F + (float) Math.PI;
|
||||
pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar);
|
||||
|
||||
BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.getDefaultState();
|
||||
pillar.addPostProcess((info) -> {
|
||||
if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) {
|
||||
return mossy;
|
||||
}
|
||||
return info.getState();
|
||||
}).setReplaceFunction((state) -> {
|
||||
return state.getMaterial().isReplaceable() || state.isIn(EndTags.GEN_TERRAIN) || state.getMaterial().equals(Material.PLANT);
|
||||
}).fillRecursive(world, pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
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.util.math.BlockPos;
|
||||
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.MHelper;
|
||||
import ru.betterend.util.sdf.SDF;
|
||||
import ru.betterend.util.sdf.operator.SDFDisplacement;
|
||||
import ru.betterend.util.sdf.operator.SDFScale3D;
|
||||
import ru.betterend.util.sdf.primitive.SDFSphere;
|
||||
import ru.betterend.world.features.DefaultFeature;
|
||||
|
||||
public class ObsidianBoulderFeature extends DefaultFeature {
|
||||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
|
||||
pos = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)));
|
||||
if (!world.getBlockState(pos.down()).isIn(EndTags.END_GROUND)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = MHelper.randRange(1, 5, random);
|
||||
for (int i = 0; i < count; i++) {
|
||||
BlockPos p = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16) - 8, pos.getY(), pos.getZ() + random.nextInt(16) - 8));
|
||||
makeBoulder(world, p, random);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void makeBoulder(StructureWorldAccess world, BlockPos pos, Random random) {
|
||||
if (!world.getBlockState(pos.down()).isIn(EndTags.END_GROUND)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float radius = MHelper.randRange(1F, 5F, random);
|
||||
SDF sphere = new SDFSphere().setRadius(radius).setBlock(Blocks.OBSIDIAN);
|
||||
float sx = MHelper.randRange(0.7F, 1.3F, random);
|
||||
float sy = MHelper.randRange(0.7F, 1.3F, random);
|
||||
float sz = MHelper.randRange(0.7F, 1.3F, random);
|
||||
sphere = new SDFScale3D().setScale(sx, sy, sz).setSource(sphere);
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong());
|
||||
sphere = new SDFDisplacement().setFunction((vec) -> {
|
||||
return (float) (noise.eval(vec.getX() * 0.2, vec.getY() * 0.2, vec.getZ() * 0.2) * 1.5F);
|
||||
}).setSource(sphere);
|
||||
|
||||
BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.getDefaultState();
|
||||
sphere.addPostProcess((info) -> {
|
||||
if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) {
|
||||
return mossy;
|
||||
}
|
||||
return info.getState();
|
||||
}).setReplaceFunction((state) -> {
|
||||
return state.getMaterial().isReplaceable() || state.isIn(EndTags.GEN_TERRAIN) || state.getMaterial().equals(Material.PLANT);
|
||||
}).fillRecursive(world, pos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
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.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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.MHelper;
|
||||
import ru.betterend.util.sdf.SDF;
|
||||
import ru.betterend.util.sdf.operator.SDFDisplacement;
|
||||
import ru.betterend.util.sdf.operator.SDFRotation;
|
||||
import ru.betterend.util.sdf.operator.SDFSubtraction;
|
||||
import ru.betterend.util.sdf.operator.SDFTranslate;
|
||||
import ru.betterend.util.sdf.primitive.SDFCappedCone;
|
||||
import ru.betterend.util.sdf.primitive.SDFFlatland;
|
||||
import ru.betterend.world.features.DefaultFeature;
|
||||
|
||||
public class ObsidianPillarBasementFeature extends DefaultFeature {
|
||||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
|
||||
pos = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)));
|
||||
if (!world.getBlockState(pos.down(5)).isIn(EndTags.GEN_TERRAIN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float height = MHelper.randRange(10F, 35F, random);
|
||||
float radius = MHelper.randRange(2F, 5F, random);
|
||||
SDF pillar = new SDFCappedCone().setRadius1(radius).setRadius2(radius).setHeight(height * 0.5F).setBlock(Blocks.OBSIDIAN);
|
||||
pillar = new SDFTranslate().setTranslate(0, height * 0.5F - 3, 0).setSource(pillar);
|
||||
SDF cut = new SDFFlatland().setBlock(Blocks.OBSIDIAN);
|
||||
OpenSimplexNoise noise = new OpenSimplexNoise(random.nextLong());
|
||||
cut = new SDFDisplacement().setFunction((vec) -> {
|
||||
return (float) (noise.eval(vec.getX() * 0.2, vec.getZ() * 0.2) * 3);
|
||||
}).setSource(cut);
|
||||
Vector3f vec = MHelper.randomHorizontal(random);
|
||||
float angle = random.nextFloat() * 0.5F + (float) Math.PI;
|
||||
cut = new SDFRotation().setRotation(vec, angle).setSource(cut);
|
||||
cut = new SDFTranslate().setTranslate(0, height * 0.7F - 3, 0).setSource(cut);
|
||||
pillar = new SDFSubtraction().setSourceA(pillar).setSourceB(cut);
|
||||
vec = MHelper.randomHorizontal(random);
|
||||
angle = random.nextFloat() * 0.2F;
|
||||
pillar = new SDFRotation().setRotation(vec, angle).setSource(pillar);
|
||||
|
||||
BlockState mossy = EndBlocks.MOSSY_OBSIDIAN.getDefaultState();
|
||||
pillar.addPostProcess((info) -> {
|
||||
if (info.getStateUp().isAir() && random.nextFloat() > 0.1F) {
|
||||
return mossy;
|
||||
}
|
||||
return info.getState();
|
||||
}).setReplaceFunction((state) -> {
|
||||
return state.getMaterial().isReplaceable() || state.isIn(EndTags.GEN_TERRAIN) || state.getMaterial().equals(Material.PLANT);
|
||||
}).fillRecursive(world, pos);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -158,10 +158,8 @@ public class RoundCaveFeature extends DefaultFeature {
|
|||
BlockPos down = pos.down(BlocksHelper.downRay(world, pos, 64) + 2);
|
||||
if (isReplaceable(world.getBlockState(down))) {
|
||||
SDF prism = new SDFHexPrism().setHeight(radius * MHelper.randRange(0.6F, 0.75F, random)).setRadius(MHelper.randRange(1.7F, 3F, random)).setBlock(EndBlocks.AURORA_CRYSTAL);
|
||||
float angleY = MHelper.randRange(0, MHelper.PI2, random);
|
||||
float vx = (float) Math.sin(angleY);
|
||||
float vz = (float) Math.sin(angleY);
|
||||
prism = new SDFRotation().setRotation(new Vector3f(vx, 0, vz), random.nextFloat()).setSource(prism);
|
||||
Vector3f vec = MHelper.randomHorizontal(random);
|
||||
prism = new SDFRotation().setRotation(vec, random.nextFloat()).setSource(prism);
|
||||
prism.setReplaceFunction((bState) -> {
|
||||
return bState.getMaterial().isReplaceable()
|
||||
|| bState.isIn(EndTags.GEN_TERRAIN)
|
||||
|
|
|
@ -19,7 +19,7 @@ public class SurfaceVentFeature extends DefaultFeature {
|
|||
@Override
|
||||
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
|
||||
pos = getPosOnSurface(world, new BlockPos(pos.getX() + random.nextInt(16), pos.getY(), pos.getZ() + random.nextInt(16)));
|
||||
if (pos.getY() < 57) {
|
||||
if (!world.getBlockState(pos.down(3)).isIn(EndTags.GEN_TERRAIN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue