package slimeknights.tconstruct.world.worldgen; import net.minecraft.block.Block; import net.minecraft.block.BlockVine; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.IChunkGenerator; import net.minecraft.world.chunk.IChunkProvider; import net.minecraftforge.fml.common.IWorldGenerator; import java.util.Random; import slimeknights.tconstruct.world.TinkerWorld; public class SlimeTreeGenerator implements IWorldGenerator { public final int minTreeHeight; public final int treeHeightRange; public final IBlockState log; public final IBlockState leaves; public final IBlockState vine; public final boolean seekHeight; public SlimeTreeGenerator(int treeHeight, int treeRange, IBlockState log, IBlockState leaves, IBlockState vine, boolean seekHeight) { this.minTreeHeight = treeHeight; this.treeHeightRange = treeRange; this.log = log; this.leaves = leaves; this.vine = vine; this.seekHeight = seekHeight; } public SlimeTreeGenerator(int treeHeight, int treeRange, IBlockState log, IBlockState leaves, IBlockState vine) { this(treeHeight, treeRange, log, leaves, vine, true); } @Override public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) { } public void generateTree(Random random, World world, BlockPos pos) { int height = random.nextInt(this.treeHeightRange) + this.minTreeHeight; boolean flag = true; if(seekHeight) { pos = findGround(world, pos); if(pos.getY() < 0) { return; } } int yPos = pos.getY(); if(yPos >= 1 && yPos + height + 1 <= 256) { IBlockState state = world.getBlockState(pos.down()); Block soil = state.getBlock(); boolean isSoil = (soil != null && soil.canSustainPlant(state, world, pos.down(), EnumFacing.UP, TinkerWorld.slimeSapling)); if(isSoil) { soil.onPlantGrow(state, world, pos.down(), pos); placeCanopy(world, random, pos, height); placeTrunk(world, pos, height); } } } BlockPos findGround(World world, BlockPos pos) { do { IBlockState state = world.getBlockState(pos); Block heightID = state.getBlock(); IBlockState up = world.getBlockState(pos.up()); if((heightID == TinkerWorld.slimeDirt || heightID == TinkerWorld.slimeGrass) && !up.getBlock().isOpaqueCube(up)) { return pos.up(); } pos = pos.down(); } while(pos.getY() > 0); return pos; } void placeCanopy(World world, Random random, BlockPos pos, int height) { pos = pos.up(height); for(int i = 0; i < 4; i++) { placeDiamondLayer(world, pos.down(i), i + 1); } IBlockState air = Blocks.AIR.getDefaultState(); pos = pos.down(); this.setBlockAndMetadata(world, pos.add(+4, 0, 0), air); this.setBlockAndMetadata(world, pos.add(-4, 0, 0), air); this.setBlockAndMetadata(world, pos.add( 0, 0, +4), air); this.setBlockAndMetadata(world, pos.add( 0, 0, -4), air); this.setBlockAndMetadata(world, pos.add(+1, 0, +1), air); this.setBlockAndMetadata(world, pos.add(+1, 0, -1), air); this.setBlockAndMetadata(world, pos.add(-1, 0, +1), air); this.setBlockAndMetadata(world, pos.add(-1, 0, -1), air); //Drippers pos = pos.down(); this.setBlockAndMetadata(world, pos.add(+3, 0, 0), leaves); this.setBlockAndMetadata(world, pos.add(-3, 0, 0), leaves); this.setBlockAndMetadata(world, pos.add( 0, 0, -3), leaves); this.setBlockAndMetadata(world, pos.add( 0, 0, +3), leaves); this.setBlockAndMetadata(world, pos.add(+2, 0, +2), leaves); this.setBlockAndMetadata(world, pos.add(+2, 0, -2), leaves); this.setBlockAndMetadata(world, pos.add(-2, 0, +2), leaves); this.setBlockAndMetadata(world, pos.add(-2, 0, -2), leaves); pos = pos.down(); this.setBlockAndMetadata(world, pos.add(+3, 0, 0), leaves); this.setBlockAndMetadata(world, pos.add(-3, 0, 0), leaves); this.setBlockAndMetadata(world, pos.add( 0, 0, -3), leaves); this.setBlockAndMetadata(world, pos.add( 0, 0, +3), leaves); this.setBlockAndMetadata(world, pos.add(+2, 0, +2), leaves); this.setBlockAndMetadata(world, pos.add(+2, 0, -2), leaves); this.setBlockAndMetadata(world, pos.add(-2, 0, +2), leaves); this.setBlockAndMetadata(world, pos.add(-2, 0, -2), leaves); // vines, woo if(vine != null) { pos = pos.down(); this.setBlockAndMetadata(world, pos.add(+3, 0, 0), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add(-3, 0, 0), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add( 0, 0, -3), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add( 0, 0, +3), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add(+2, 0, +2), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add(+2, 0, -2), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add(-2, 0, +2), getRandomizedVine(random)); this.setBlockAndMetadata(world, pos.add(-2, 0, -2), getRandomizedVine(random)); } } protected IBlockState getRandomizedVine(Random random) { IBlockState state = vine; PropertyBool[] sides = new PropertyBool[]{BlockVine.NORTH, BlockVine.EAST, BlockVine.SOUTH, BlockVine.WEST}; for(PropertyBool side : sides) { state = state.withProperty(side, false); } for(int i = random.nextInt(3) + 1; i > 0; i--) { state = state.withProperty(sides[random.nextInt(sides.length)], true); } return state; } protected void placeDiamondLayer(World world, BlockPos pos, int range) { for(int x = -range; x <= range; x++) { for(int z = -range; z <= range; z++) { if(Math.abs(x) + Math.abs(z) <= range) { this.setBlockAndMetadata(world, pos.add(x, 0, z), leaves); } } } } protected void placeTrunk(World world, BlockPos pos, int height) { while(height >= 0) { IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); if(block.isAir(state, world, pos) || block.isReplaceable(world, pos) || block.isLeaves(state, world, pos)) { this.setBlockAndMetadata(world, pos, log); } pos = pos.up(); height--; } } protected void setBlockAndMetadata(World world, BlockPos pos, IBlockState stateNew) { IBlockState state = world.getBlockState(pos); Block block = state.getBlock(); if(block.isAir(state, world, pos) || block.canPlaceBlockAt(world, pos) || world.getBlockState(pos) == leaves) { world.setBlockState(pos, stateNew, 2); } } }