diff --git a/src/EditSession.java b/src/EditSession.java index b70fa320d..e222d5bb6 100644 --- a/src/EditSession.java +++ b/src/EditSession.java @@ -822,7 +822,163 @@ public int fixWater(Vector pos, int radius) throws MaxChangedBlocksException { return affected; } - + + /** + * Helper method to draw the cylinder. + * + * @param center + * @param x + * @param z + * @param height + * @param block + * @throws MaxChangedBlocksException + */ + private int makeHCylinderPoints(Vector center, int x, int z, + int height, BaseBlock block) throws MaxChangedBlocksException { + int affected = 0; + + if (x == 0) { + for (int y = 0; y < height; y++) { + setBlock(center.add(0, y, z), block); + setBlock(center.add(0, y, -z), block); + setBlock(center.add(z, y, 0), block); + setBlock(center.add(-z, y, 0), block); + affected += 4; + } + } else if (x == z) { + for (int y = 0; y < height; y++) { + setBlock(center.add(x, y, z), block); + setBlock(center.add(-x, y, z), block); + setBlock(center.add(x, y, -z), block); + setBlock(center.add(-x, y, -z), block); + affected += 4; + } + } else if (x < z) { + for (int y = 0; y < height; y++) { + setBlock(center.add(x, y, z), block); + setBlock(center.add(-x, y, z), block); + setBlock(center.add(x, y, -z), block); + setBlock(center.add(-x, y, -z), block); + setBlock(center.add(z, y, x), block); + setBlock(center.add(-z, y, x), block); + setBlock(center.add(z, y, -x), block); + setBlock(center.add(-z, y, -x), block); + affected += 8; + } + } + + return affected; + } + + /** + * Draw a hollow cylinder. + * + * @param pos + * @param block + * @param radius + * @param height + * @return number of blocks set + * @throws MaxChangedBlocksException + */ + public int makeHollowCylinder(Vector pos, BaseBlock block, + int radius, int height) throws MaxChangedBlocksException { + int x = 0; + int z = radius; + int d = (5 - radius * 4) / 4; + int affected = 0; + + affected += makeHCylinderPoints(pos, x, z, height, block); + + while (x < z) { + x++; + + if (d >= 0) { + z--; + d += 2 * (x - z) + 1; + } else { + d += 2 * x + 1; + } + + affected += makeHCylinderPoints(pos, x, z, height, block); + } + + return affected; + } + + /** + * Helper method to draw the cylinder. + * + * @param center + * @param x + * @param z + * @param height + * @param block + * @throws MaxChangedBlocksException + */ + private int makeCylinderPoints(Vector center, int x, int z, + int height, BaseBlock block) throws MaxChangedBlocksException { + int affected = 0; + + if (x == z) { + for (int y = 0; y < height; y++) { + for (int z2 = -z; z2 <= z; z2++) { + setBlock(center.add(x, y, z2), block); + setBlock(center.add(-x, y, z2), block); + affected += 2; + } + } + } else if (x < z) { + for (int y = 0; y < height; y++) { + for (int x2 = -x; x2 <= x; x2++) { + for (int z2 = -z; z2 <= z; z2++) { + setBlock(center.add(x2, y, z2), block); + affected++; + } + setBlock(center.add(z, y, x2), block); + setBlock(center.add(-z, y, x2), block); + affected += 2; + } + } + } + + return affected; + } + + /** + * Draw a filled cylinder. + * + * @param pos + * @param block + * @param radius + * @param height + * @return number of blocks set + * @throws MaxChangedBlocksException + */ + public int makeCylinder(Vector pos, BaseBlock block, + int radius, int height) throws MaxChangedBlocksException { + int x = 0; + int z = radius; + int d = (5 - radius * 4) / 4; + int affected = 0; + + affected += makeCylinderPoints(pos, x, z, height, block); + + while (x < z) { + x++; + + if (d >= 0) { + z--; + d += 2 * (x - z) + 1; + } else { + d += 2 * x + 1; + } + + affected += makeCylinderPoints(pos, x, z, height, block); + } + + return affected; + } + /** * Set a block by chance. diff --git a/src/WorldEdit.java b/src/WorldEdit.java index bc38ece23..06dc044dc 100644 --- a/src/WorldEdit.java +++ b/src/WorldEdit.java @@ -141,6 +141,8 @@ private WorldEdit() { commands.put("//expand", " [Num] - Expands the selection"); commands.put("//contract", " [Num] - Contracts the selection"); commands.put("//rotate", "[Angle] - Rotate the clipboard"); + commands.put("//hcyl", "[ID] [Radius] - Create a vertical hollow cylinder"); + commands.put("//cyl", "[ID] [Radius] - Create a vertical cylinder"); commands.put("/fixwater", "[Radius] - Level nearby pools of water"); commands.put("/forestgen", " - Make an ugly pine tree forest"); commands.put("/unstuck", "Go up to the first free spot"); @@ -404,6 +406,33 @@ public boolean performCommand(WorldEditPlayer player, return true; + // Draw a hollow cylinder + } else if (split[0].equalsIgnoreCase("//hcyl")) { + checkArgs(split, 2, 3, split[0]); + BaseBlock block = getBlock(split[1]); + int radius = Math.max(1, Integer.parseInt(split[2])); + int height = split.length > 3 ? Math.max(1, Integer.parseInt(split[3])) : 1; + + Vector pos = session.getPlacementPosition(player); + int affected = editSession.makeHollowCylinder(pos, block, radius, height); + player.print(affected + " block(s) have been created."); + + return true; + + // Draw a filled cylinder + } else if (split[0].equalsIgnoreCase("//cyl")) { + checkArgs(split, 2, 3, split[0]); + BaseBlock block = getBlock(split[1]); + int radius = Math.max(1, Integer.parseInt(split[2])); + int height = split.length > 3 ? Math.max(1, Integer.parseInt(split[3])) : 1; + + Vector pos = session.getPlacementPosition(player); + int affected = editSession.makeCylinder(pos, block, radius, height); + player.findFreePosition(); + player.print(affected + " block(s) have been created."); + + return true; + // Fill a hole } else if (split[0].equalsIgnoreCase("//fill")) { checkArgs(split, 2, 3, split[0]);