package net.torocraft.toroquest.generation; import java.util.Random; import net.minecraft.block.BlockBush; import net.minecraft.block.BlockStairs; 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.gen.feature.WorldGenerator; public class BastionsLairEntranceGenerator extends WorldGenerator { private final int boxRadius = 6; private final int radius = 5; private final int radiusSq = 5 * 5; private final int halfRadius = radius / 2; private final int innerRadiusSquared = (radius - 1) * radius; private int bottom; private BlockPos entrancePosition; private BlockPos origin; private int magSq; private int surface; private int x, y, z; private World world; private Random rand; private IBlockState block; private EnumFacing entranceFacing; @Override public boolean generate(World world, Random rand, BlockPos entrancePosition) { this.world = world; this.rand = rand; this.entrancePosition = entrancePosition; origin = entrancePosition; findSurface(entrancePosition); genEntrance(); return true; } public void setEntrance(EnumFacing facing) { this.entranceFacing = facing; } private void findSurface(BlockPos start) { int surfaceGlobal = world.getActualHeight(); IBlockState blockState; while (surfaceGlobal > 0) { surfaceGlobal--; blockState = world.getBlockState(new BlockPos(start.getX(), surfaceGlobal, start.getZ())); if (isLiquid(blockState) || isGroundBlock(blockState)) { break; } } surface = surfaceGlobal - origin.getY(); if (surface < 5) { surface = 5; } } private boolean isLiquid(IBlockState blockState) { return blockState.getBlock() == Blocks.WATER || blockState.getBlock() == Blocks.LAVA; } private boolean isGroundBlock(IBlockState blockState) { if (blockState.getBlock() == Blocks.LEAVES || blockState.getBlock() == Blocks.LEAVES2 || blockState.getBlock() == Blocks.LOG || blockState.getBlock() instanceof BlockBush) { return false; } return blockState.isOpaqueCube(); } private void genEntrance() { for (y = -20; y <= surface + 5; y++) { for (x = -boxRadius; x <= boxRadius; x++) { for (z = -boxRadius; z <= boxRadius; z++) { magSq = (x * x) + (z * z); chooseAndPlaceBlock(); } } } } protected void chooseAndPlaceBlock() { if (isOutside()) { block = null; } else if (isStairs()) { block = getStairBlock(); } else if (isWall() && !isEntrance()) { block = Blocks.STONEBRICK.getDefaultState(); } else if (isFloor()) { block = Blocks.STONE.getDefaultState(); } else { block = Blocks.AIR.getDefaultState(); } placeBlock(); } private boolean isFloor() { return (y < surface && y % 8 == 0) || y == surface; } private boolean isStairs() { return Math.abs(x) < 2 && Math.abs(z) < 2; } private IBlockState getStairBlock() { BlockStairs stairsBlock = (BlockStairs) Blocks.STONE_BRICK_STAIRS; if (y > surface) { return Blocks.AIR.getDefaultState(); } if (y < 1) { return Blocks.STONE.getDefaultState(); } if (x == 0 && z == 0) { return Blocks.STONE.getDefaultState(); } int yAdj = (y + 1) % 4; switch (yAdj) { case 0: if (x == 1 && z == 0) { return stairsBlock.getStateFromMeta(2); } if (x == 1 && z == 1) { return Blocks.STONEBRICK.getDefaultState(); } break; case 1: if (x == 0 && z == 1) { return stairsBlock.getStateFromMeta(1); } if (x == -1 && z == 1) { return Blocks.STONEBRICK.getDefaultState(); } break; case 2: if (x == -1 && z == 0) { return stairsBlock.getStateFromMeta(3); } if (x == -1 && z == -1) { return Blocks.STONEBRICK.getDefaultState(); } break; case 3: if (x == 0 && z == -1) { return stairsBlock.getStateFromMeta(0); } if (x == 1 && z == -1) { return Blocks.STONEBRICK.getDefaultState(); } break; default: break; } return Blocks.AIR.getDefaultState(); } private boolean isEntrance() { if (y > 5 || y < 1) { return false; } switch (entranceFacing) { case EAST: return x > halfRadius; case NORTH: return z > halfRadius; case SOUTH: return z < -halfRadius; case WEST: return x < -halfRadius; default: return false; } } private boolean isWall() { return magSq >= innerRadiusSquared && y <= surface + 1; } private boolean isOutside() { return magSq > radiusSq + 5; } protected void placeBlock() { if (block == null) { return; } setBlockAndNotifyAdequately(world, origin.add(x, y, z), block); } }