public void generateBranches( World world, Random rand, int x, int y, int z, int height, double radius) { int branchCount = BRANCHES_BASE_NUMBER + rand.nextInt(BRANCHES_EXTRA); double curAngle = 0.0D; double[] average = {0, 0, 0}; int[] start = {x, y, z}; Queue<int[]> branches = new LinkedList<int[]>(); // Generate the branches for (int i = 0; i < branchCount; i++) { // Get the branch radius and height double angle = (rand.nextInt(50) + 35) / 90.0D; double thisHeight = (height + 1) * Math.sin(angle) / 1.3; double thisRadius = radius * Math.cos(angle); // Get the branch rotation curAngle += (rand.nextInt(360 / branchCount) + (360 / branchCount)) / 90.0D; // + (360.0D/branchCount) / 180.0D ; int x1 = (int) ((thisRadius) * Math.cos(curAngle)); int z1 = (int) ((thisRadius) * Math.sin(curAngle)); // Add the the average count average[0] += x1; average[1] += thisHeight; average[2] += z1; // Add to the branch list int[] node = new int[] {x1 + x, (int) thisHeight + y, z1 + z}; // Add the branch end for leaf generation branches.add(node); // Generate the branch placeBlockLine(start, node, TreeBlock.TRUNK.get(), world); } // Place the branch tips Iterator<int[]> itt = branches.iterator(); while (itt.hasNext()) { int[] cluster = itt.next(); generateLeafCluster(world, cluster[0], cluster[1], cluster[2], 2, 1, TreeBlock.LEAVES.get()); } // Calculate the center position average[0] /= branchCount; average[1] = (branchCount / average[1]) + 2.3D; average[2] /= branchCount; // Generate the canopy generateCanopy( world, rand, average[0] + x, y, average[2] + z, radius, height, TreeBlock.LEAVES.get()); // Generate the center cone generateVerticalCone(world, x, y, z, height - 1, .75, 2, TreeBlock.LEAVES.get()); }
private boolean generateTree(World world, Random rand, int x, int y, int z) { final int below = world.getBlockId(x, y - 1, z); final int height = rand.nextInt(BASE_HEIGHT_VARIANCE) + BASE_HEIGHT; int width = CANOPY_WIDTH + rand.nextInt(CANOPY_WIDTH_VARIANCE); final int chunkCheck = width + 1; // Make sure that a tree can grow on the soil if (!TreeSoilRegistry.isValidSoil(Integer.valueOf(world.getBlockId(x, y - 1, z))) || !TreeSoilRegistry.isValidSoil(Integer.valueOf(world.getBlockId(x + 1, y - 1, z))) || !TreeSoilRegistry.isValidSoil(Integer.valueOf(world.getBlockId(x, y - 1, z + 1))) || !TreeSoilRegistry.isValidSoil(Integer.valueOf(world.getBlockId(x + 1, y - 1, z + 1)))) return false; // make sure that we have room to grow the tree if (y >= 256 - height - 4) return false; // Make sure that the tree can fit in the world if (y < 1 || y + height + 4 > 256) return false; // Make sure the cunks are loaded if (!world.checkChunksExist( x - chunkCheck, y - chunkCheck, z - chunkCheck, x + chunkCheck, y + chunkCheck, z + chunkCheck)) return false; // Draw the main trunk if (place2x2Trunk( x, y, z, (int) (height * TRUNK_HEIGHT_PERCENT), TreeBlock.TRUNK.get(), world)) { // Draw the knees generateKnees(world, rand, x, y, z); // Generate the branches generateBranches(world, rand, x, y, z, height, width); // Place the topper leaves generateLeafCluster( world, x, (int) (height * TRUNK_HEIGHT_PERCENT) + y, z, 4 + rand.nextInt(CLUSTER_HEIGHT_VARIANCE), 4 + rand.nextInt(CLUSTER_DIAMATER_VARIANCE), TreeBlock.LEAVES.get()); // We generated a tree return true; } return false; }
private void growLeafNode(World world, int x, int y, int z) { for (int xOffset = -3; xOffset <= 3; xOffset++) for (int zOffset = -3; zOffset <= 3; zOffset++) { if ((Math.abs(xOffset) != 3 || Math.abs(zOffset) != 3) && (Math.abs(xOffset) != 3 || Math.abs(zOffset) != 2) && (Math.abs(xOffset) != 2 || Math.abs(zOffset) != 3) && (xOffset != 0 || zOffset != 0)) if (world.getBlockId(x + xOffset, y, z + zOffset) == 0) setBlockAndMetadata( world, x + xOffset, y, z + zOffset, TreeBlock.LEAVES.getID(), TreeBlock.LEAVES.getMetadata()); if (Math.abs(xOffset) >= 3 || Math.abs(zOffset) >= 3 || Math.abs(xOffset) == 2 && Math.abs(zOffset) == 2) continue; if (world.getBlockId(x + xOffset, y - 1, z + zOffset) == 0) setBlockAndMetadata( world, x + xOffset, y - 1, z + zOffset, TreeBlock.LEAVES.getID(), TreeBlock.LEAVES.getMetadata()); if (world.getBlockId(x + xOffset, y + 1, z + zOffset) != 0) continue; setBlockAndMetadata( world, x + xOffset, y + 1, z + zOffset, TreeBlock.LEAVES.getID(), TreeBlock.LEAVES.getMetadata()); } }
public void generateBranches( World world, Random rand, int x, int y, int z, int height, int width) { int branchCount = BRANCHES_BASE_NUMBER + rand.nextInt(BRANCHES_EXTRA); // Make sure that the width is even width = (width % 2 == 1) ? width + 1 : width; // Cache the offset int offset = width / 2; // The max distance for branches to generate int branchStart = (int) (height * TRUNK_BRANCHES_START); int maxBranchHeight = height - ((int) (height * TRUNK_BRANCHES_START)) - 3; int trunkStart = (int) (height * TRUNK_HEIGHT_PERCENT); int trunkRange = height - trunkStart; int[] start = {0, 0, 0}; int[] end = {0, 0, 0}; Queue<int[]> branches = new LinkedList<int[]>(); // generate the corner markers // setBlockAndMetadata(world, x-width, y + 10, z-width, TreeBlock.TRUNK.getID(), 0); // setBlockAndMetadata(world, x-width, y + 10, z+width, TreeBlock.TRUNK.getID(), 0); // setBlockAndMetadata(world, x+width, y + 10, z-width, TreeBlock.TRUNK.getID(), 0); // setBlockAndMetadata(world, x+width, y + 10, z+width, TreeBlock.TRUNK.getID(), 0); // Generate some test branches for (int branch = 0; branch < branchCount; branch++) { // The end position end[0] = rand.nextInt(width + 1) - offset + x; end[1] = rand.nextInt(maxBranchHeight) + branchStart + y; end[2] = rand.nextInt(width + 1) - offset + z; // Max of tree height // Min of branch start start[1] = Math.max( branchStart + y, Math.min(height, rand.nextInt(Math.max(end[1] - branchStart - y, 1)) + y)); if (end[0] > x && end[2] > z) { start[0] = x + 1; start[2] = z + 1; } else if (end[0] > x) { start[0] = x + 1; start[2] = z; } else if (end[2] > z) { start[0] = x; start[2] = z + 1; } else { start[0] = x; start[2] = z; } // Place the branch placeBlockLine(start, end, TreeBlock.KNEE_LOG.get(), world); int[] node = new int[] {end[0], end[1], end[2]}; // Add the branch end for leaf generation branches.add(node); } // Generate the leaf clusters Iterator<int[]> itt = branches.iterator(); while (itt.hasNext()) { int[] cluster = itt.next(); generateLeafCluster( world, cluster[0], cluster[1], cluster[2], CLUSTER_HEIGHT + rand.nextInt(CLUSTER_HEIGHT_VARIANCE), CLUSTER_DIAMATER + rand.nextInt(CLUSTER_DIAMATER_VARIANCE), TreeBlock.LEAVES.get()); } }