Added cone generation command (#2251)

* Added cone generation command

* Fix formatting problems

---------

Co-authored-by: Madeline Miller <mnmiller1@me.com>
This commit is contained in:
Chris Lang 2023-07-15 00:22:45 -07:00 committed by GitHub
parent ac7e45e246
commit 00849939c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 0 deletions

View File

@ -1776,6 +1776,79 @@ public int makeCylinder(BlockVector3 pos, Pattern block, double radiusX, double
return affected; return affected;
} }
/**
* Makes a cone.
*
* @param pos Center of the cone
* @param block The block pattern to use
* @param radiusX The cone's largest north/south extent
* @param radiusZ The cone's largest east/west extent
* @param height The cone's up/down extent. If negative, extend downward.
* @param filled If false, only a shell will be generated.
* @param thickness The cone's wall thickness, if it's hollow.
* @return number of blocks changed
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int makeCone(BlockVector3 pos, Pattern block, double radiusX, double radiusZ, int height, boolean filled,
double thickness) throws MaxChangedBlocksException {
int affected = 0;
final int ceilRadiusX = (int) Math.ceil(radiusX);
final int ceilRadiusZ = (int) Math.ceil(radiusZ);
for (int y = 0; y < height; ++y) {
forX:
for (int x = 0; x <= ceilRadiusX; ++x) {
forZ:
for (int z = 0; z <= ceilRadiusZ; ++z) {
double xSquaredOverRadiusX = Math.pow(x, 2) / Math.pow(radiusX, 2);
double zSquaredOverRadiusZ = Math.pow(z, 2) / Math.pow(radiusZ, 2);
double ySquaredMinusHeightOverHeightSquared = Math.pow(y - height, 2)
/ Math.pow(height, 2);
double distanceFromOriginMinusHeightSquared = xSquaredOverRadiusX + zSquaredOverRadiusZ
- ySquaredMinusHeightOverHeightSquared;
if (distanceFromOriginMinusHeightSquared > 1) {
if (z == 0) {
break forX;
}
break forZ;
}
if (!filled) {
double xNext = Math.pow(x + thickness, 2) / Math.pow(radiusX, 2)
+ zSquaredOverRadiusZ - ySquaredMinusHeightOverHeightSquared;
double yNext = xSquaredOverRadiusX + zSquaredOverRadiusZ
- Math.pow(y + thickness - height, 2) / Math.pow(height, 2);
double zNext = xSquaredOverRadiusX + Math.pow(z + thickness, 2)
/ Math.pow(radiusZ, 2) - ySquaredMinusHeightOverHeightSquared;
if (xNext <= 0 && zNext <= 0 && (yNext <= 0 && y + thickness != height)) {
continue;
}
}
if (distanceFromOriginMinusHeightSquared <= 0) {
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;
}
/** /**
* Makes a sphere. * Makes a sphere.
* *

View File

@ -132,6 +132,49 @@ public int cyl(Actor actor, LocalSession session, EditSession editSession,
return affected; return affected;
} }
@Command(
name = "/cone",
desc = "Generates a cone."
)
@CommandPermissions("worldedit.generation.cone")
@Logging(PLACEMENT)
public int cone(Actor actor, LocalSession session, EditSession editSession,
@Arg(desc = "The pattern of blocks to generate")
Pattern pattern,
@Arg(desc = "The radii of the cone. 1st is N/S, 2nd is E/W")
@Radii(2)
List<Double> radii,
@Arg(desc = "The height of the cone", def = "1")
int height,
@Switch(name = 'h', desc = "Make a hollow cone")
boolean hollow,
@Arg(desc = "Thickness of the hollow cone", def = "1")
double thickness
) throws WorldEditException {
double radiusX;
double radiusZ;
switch (radii.size()) {
case 1 -> radiusX = radiusZ = Math.max(1, radii.get(0));
case 2 -> {
radiusX = Math.max(1, radii.get(0));
radiusZ = Math.max(1, radii.get(1));
}
default -> {
actor.printError(TranslatableComponent.of("worldedit.cone.invalid-radius"));
return 0;
}
}
worldEdit.checkMaxRadius(radiusX);
worldEdit.checkMaxRadius(radiusZ);
worldEdit.checkMaxRadius(height);
BlockVector3 pos = session.getPlacementPosition(actor);
int affected = editSession.makeCone(pos, pattern, radiusX, radiusZ, height, !hollow, thickness);
actor.printInfo(TranslatableComponent.of("worldedit.cone.created", TextComponent.of(affected)));
return affected;
}
@Command( @Command(
name = "/hsphere", name = "/hsphere",
desc = "Generates a hollow sphere." desc = "Generates a hollow sphere."

View File

@ -250,6 +250,8 @@
"worldedit.up.obstructed": "You would hit something above you.", "worldedit.up.obstructed": "You would hit something above you.",
"worldedit.up.moved": "Woosh!", "worldedit.up.moved": "Woosh!",
"worldedit.cone.invalid-radius": "You must either specify 1 or 2 radius values.",
"worldedit.cone.created": "{0} blocks have been created.",
"worldedit.cyl.invalid-radius": "You must either specify 1 or 2 radius values.", "worldedit.cyl.invalid-radius": "You must either specify 1 or 2 radius values.",
"worldedit.cyl.created": "{0} blocks have been created.", "worldedit.cyl.created": "{0} blocks have been created.",
"worldedit.sphere.invalid-radius": "You must either specify 1 or 3 radius values.", "worldedit.sphere.invalid-radius": "You must either specify 1 or 3 radius values.",