mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-01-09 17:27:38 +00:00
Added support for stretched cylinders and brought their profile in line with that of the central layer of a sphere of the same x/z radius.
This commit is contained in:
parent
318e81886c
commit
58be9d9be4
@ -1794,157 +1794,22 @@ public class EditSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to draw the cylinder.
|
* Makes a sphere or ellipsoid.
|
||||||
*
|
*
|
||||||
* @param center
|
* @param pos Center of the sphere or ellipsoid
|
||||||
* @param x
|
* @param block The block pattern to use
|
||||||
* @param z
|
* @param radiusX The cylinder's largest north/south extent
|
||||||
* @param height
|
* @param radiusZ The cylinder's largest east/west extent
|
||||||
* @param block
|
* @param height The cylinder's up/down extent. If negative, extend downward.
|
||||||
|
* @param filled If false, only a shell will be generated.
|
||||||
|
* @return number of blocks changed
|
||||||
* @throws MaxChangedBlocksException
|
* @throws MaxChangedBlocksException
|
||||||
*/
|
*/
|
||||||
private int makeHCylinderPoints(Vector center, int x, double z, int height,
|
public int makeCylinder(Vector pos, Pattern block, double radiusX, double radiusZ, int height, boolean filled) throws MaxChangedBlocksException {
|
||||||
Pattern block) throws MaxChangedBlocksException {
|
|
||||||
int ceilZ = (int) Math.ceil(z);
|
|
||||||
int affected = 0;
|
int affected = 0;
|
||||||
|
|
||||||
if (x == 0) {
|
radiusX += 0.5;
|
||||||
for (int y = 0; y < height; ++y) {
|
radiusZ += 0.5;
|
||||||
setBlock(center.add(0, y, ceilZ), block);
|
|
||||||
setBlock(center.add(0, y, -ceilZ), block);
|
|
||||||
setBlock(center.add(ceilZ, y, 0), block);
|
|
||||||
setBlock(center.add(-ceilZ, y, 0), block);
|
|
||||||
affected += 4;
|
|
||||||
}
|
|
||||||
} else if (x == z) {
|
|
||||||
for (int y = 0; y < height; ++y) {
|
|
||||||
setBlock(center.add(x, y, ceilZ), block);
|
|
||||||
setBlock(center.add(-x, y, ceilZ), block);
|
|
||||||
setBlock(center.add(x, y, -ceilZ), block);
|
|
||||||
setBlock(center.add(-x, y, -ceilZ), block);
|
|
||||||
affected += 4;
|
|
||||||
}
|
|
||||||
} else if (x < z) {
|
|
||||||
for (int y = 0; y < height; ++y) {
|
|
||||||
setBlock(center.add(x, y, ceilZ), block);
|
|
||||||
setBlock(center.add(-x, y, ceilZ), block);
|
|
||||||
setBlock(center.add(x, y, -ceilZ), block);
|
|
||||||
setBlock(center.add(-x, y, -ceilZ), block);
|
|
||||||
setBlock(center.add(ceilZ, y, x), block);
|
|
||||||
setBlock(center.add(-ceilZ, y, x), block);
|
|
||||||
setBlock(center.add(ceilZ, y, -x), block);
|
|
||||||
setBlock(center.add(-ceilZ, 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, Pattern block, double radius,
|
|
||||||
int height) throws MaxChangedBlocksException {
|
|
||||||
int x = 0;
|
|
||||||
double z = radius;
|
|
||||||
double d = (5 - radius * 4) / 4;
|
|
||||||
int affected = 0;
|
|
||||||
|
|
||||||
if (height == 0) {
|
|
||||||
return 0;
|
|
||||||
} else if (height < 0) {
|
|
||||||
height = -height;
|
|
||||||
pos = pos.subtract(0, height, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only do this check if height is negative --Elizabeth
|
|
||||||
if (height < 0 && pos.getBlockY() - height - 1 < 0) {
|
|
||||||
height = pos.getBlockY() + 1;
|
|
||||||
} else if (pos.getBlockY() + height - 1 > 127) {
|
|
||||||
height = 127 - pos.getBlockY() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
affected += makeHCylinderPoints(pos, x, z, height, block);
|
|
||||||
|
|
||||||
while (x < z) {
|
|
||||||
++x;
|
|
||||||
|
|
||||||
if (d >= 0) {
|
|
||||||
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, double z, int height,
|
|
||||||
Pattern block) throws MaxChangedBlocksException {
|
|
||||||
int ceilZ = (int) Math.ceil(z);
|
|
||||||
int affected = 0;
|
|
||||||
|
|
||||||
if (x == z) {
|
|
||||||
for (int y = 0; y < height; ++y) {
|
|
||||||
for (int z2 = -ceilZ; z2 <= ceilZ; ++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 = -ceilZ; z2 <= ceilZ; ++z2) {
|
|
||||||
setBlock(center.add(x2, y, z2), block);
|
|
||||||
++affected;
|
|
||||||
}
|
|
||||||
setBlock(center.add(ceilZ, y, x2), block);
|
|
||||||
setBlock(center.add(-ceilZ, 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, Pattern block, double radius, int height)
|
|
||||||
throws MaxChangedBlocksException {
|
|
||||||
int x = 0;
|
|
||||||
double z = radius;
|
|
||||||
double d = (5 - radius * 4) / 4;
|
|
||||||
int affected = 0;
|
|
||||||
|
|
||||||
if (height == 0) {
|
if (height == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1959,18 +1824,52 @@ public class EditSession {
|
|||||||
height = 127 - pos.getBlockY() + 1;
|
height = 127 - pos.getBlockY() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
affected += makeCylinderPoints(pos, x, z, height, block);
|
final double invRadiusX = 1 / radiusX;
|
||||||
|
final double invRadiusZ = 1 / radiusZ;
|
||||||
|
|
||||||
while (x < z) {
|
final int ceilRadiusX = (int) Math.ceil(radiusX);
|
||||||
++x;
|
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
|
||||||
|
|
||||||
if (d >= 0) {
|
double nextXn = 0;
|
||||||
d += 2 * (x - --z) + 1;
|
forX:
|
||||||
} else {
|
for (int x = 0; x <= ceilRadiusX; ++x) {
|
||||||
d += 2 * x + 1;
|
final double xn = nextXn;
|
||||||
|
nextXn = (x + 1) * invRadiusX;
|
||||||
|
double nextZn = 0;
|
||||||
|
forZ:
|
||||||
|
for (int z = 0; z <= ceilRadiusZ; ++z) {
|
||||||
|
final double zn = nextZn;
|
||||||
|
nextZn = (z + 1) * invRadiusZ;
|
||||||
|
|
||||||
|
double distanceSq = lengthSq(xn, zn);
|
||||||
|
if (distanceSq > 1) {
|
||||||
|
if (z == 0) {
|
||||||
|
break forX;
|
||||||
|
}
|
||||||
|
break forZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
affected += makeCylinderPoints(pos, x, z, height, block);
|
if (!filled) {
|
||||||
|
if (lengthSq(nextXn, zn) <= 1 && lengthSq(xn, nextZn) <= 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
if (setBlock(pos.add(x, y, z), block)) {
|
||||||
|
++affected;
|
||||||
|
}
|
||||||
|
if (setBlock(pos.add(-x, y, z), block)) {
|
||||||
|
++affected;
|
||||||
|
}
|
||||||
|
if (setBlock(pos.add(x, y, -z), block)) {
|
||||||
|
++affected;
|
||||||
|
}
|
||||||
|
if (setBlock(pos.add(-x, y, -z), block)) {
|
||||||
|
++affected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return affected;
|
return affected;
|
||||||
@ -2071,6 +1970,10 @@ public class EditSession {
|
|||||||
return (x * x) + (y * y) + (z * z);
|
return (x * x) + (y * y) + (z * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final double lengthSq(double x, double z) {
|
||||||
|
return (x * x) + (z * z);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes a pyramid.
|
* Makes a pyramid.
|
||||||
*
|
*
|
||||||
|
@ -39,7 +39,7 @@ import com.sk89q.worldedit.util.TreeGenerator;
|
|||||||
public class GenerationCommands {
|
public class GenerationCommands {
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/hcyl" },
|
aliases = { "/hcyl" },
|
||||||
usage = "<block> <radius> [height]",
|
usage = "<block> <radius>[,<radius>] [height]",
|
||||||
desc = "Generate a hollow cylinder",
|
desc = "Generate a hollow cylinder",
|
||||||
min = 2,
|
min = 2,
|
||||||
max = 3
|
max = 3
|
||||||
@ -51,17 +51,32 @@ public class GenerationCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Pattern block = we.getBlockPattern(player, args.getString(0));
|
Pattern block = we.getBlockPattern(player, args.getString(0));
|
||||||
double radius = Math.max(1, args.getDouble(1));
|
String[] radiuses = args.getString(1).split(",");
|
||||||
|
final double radiusX, radiusZ;
|
||||||
|
switch (radiuses.length) {
|
||||||
|
case 1:
|
||||||
|
radiusX = radiusZ = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
radiusX = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
radiusZ = Math.max(1, Double.parseDouble(radiuses[1]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
player.printError("You must either specify 1 or 2 radius values.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int height = args.argsLength() > 2 ? args.getInteger(2) : 1;
|
int height = args.argsLength() > 2 ? args.getInteger(2) : 1;
|
||||||
|
|
||||||
Vector pos = session.getPlacementPosition(player);
|
Vector pos = session.getPlacementPosition(player);
|
||||||
int affected = editSession.makeHollowCylinder(pos, block, radius, height);
|
int affected = editSession.makeCylinder(pos, block, radiusX, radiusZ, height, false);
|
||||||
player.print(affected + " block(s) have been created.");
|
player.print(affected + " block(s) have been created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = { "/cyl" },
|
aliases = { "/cyl" },
|
||||||
usage = "<block> <radius> [height]",
|
usage = "<block> <radius>[,<radius>] [height]",
|
||||||
desc = "Generate a cylinder",
|
desc = "Generate a cylinder",
|
||||||
min = 2,
|
min = 2,
|
||||||
max = 3
|
max = 3
|
||||||
@ -73,11 +88,26 @@ public class GenerationCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Pattern block = we.getBlockPattern(player, args.getString(0));
|
Pattern block = we.getBlockPattern(player, args.getString(0));
|
||||||
double radius = Math.max(1, args.getDouble(1));
|
String[] radiuses = args.getString(1).split(",");
|
||||||
|
final double radiusX, radiusZ;
|
||||||
|
switch (radiuses.length) {
|
||||||
|
case 1:
|
||||||
|
radiusX = radiusZ = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
radiusX = Math.max(1, Double.parseDouble(radiuses[0]));
|
||||||
|
radiusZ = Math.max(1, Double.parseDouble(radiuses[1]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
player.printError("You must either specify 1 or 2 radius values.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int height = args.argsLength() > 2 ? args.getInteger(2) : 1;
|
int height = args.argsLength() > 2 ? args.getInteger(2) : 1;
|
||||||
|
|
||||||
Vector pos = session.getPlacementPosition(player);
|
Vector pos = session.getPlacementPosition(player);
|
||||||
int affected = editSession.makeCylinder(pos, block, radius, height);
|
int affected = editSession.makeCylinder(pos, block, radiusX, radiusZ, height, true);
|
||||||
player.print(affected + " block(s) have been created.");
|
player.print(affected + " block(s) have been created.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,6 @@ public class CylinderBrush implements Brush {
|
|||||||
|
|
||||||
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
editSession.makeCylinder(pos, mat, size, height);
|
editSession.makeCylinder(pos, mat, size, size, height, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,6 @@ public class HollowCylinderBrush implements Brush {
|
|||||||
|
|
||||||
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
public void build(EditSession editSession, Vector pos, Pattern mat, double size)
|
||||||
throws MaxChangedBlocksException {
|
throws MaxChangedBlocksException {
|
||||||
editSession.makeHollowCylinder(pos, mat, size, height);
|
editSession.makeCylinder(pos, mat, size, size, height, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user