Add direction argument to fill
This commit is contained in:
parent
65442c886a
commit
803c84a621
@ -106,6 +106,7 @@ import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.util.RegionOffset;
|
||||
import com.sk89q.worldedit.function.visitor.DirectionalVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
|
||||
import com.sk89q.worldedit.function.visitor.LayerVisitor;
|
||||
@ -1446,6 +1447,43 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
return this.changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills an area recursively in the X/Z directions.
|
||||
*
|
||||
* @param origin the location to start from
|
||||
* @param pattern the block to fill with
|
||||
* @param radius the radius of the spherical area to fill
|
||||
* @param depth the maximum depth, starting from the origin
|
||||
* @param direction the direction to fill
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
public int fillDirection(final Vector origin, final Pattern pattern, final double radius, final int depth, Vector direction) {
|
||||
checkNotNull(origin);
|
||||
checkNotNull(pattern);
|
||||
checkArgument(radius >= 0, "radius >= 0");
|
||||
checkArgument(depth >= 1, "depth >= 1");
|
||||
initTransform(origin);
|
||||
if (direction.equals(new Vector(0, -1, 0))) {
|
||||
System.out.println("Fill down");
|
||||
return fillXZ(origin, pattern, radius, depth, false);
|
||||
}
|
||||
final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), Masks.negate(new ExistingBlockMask(EditSession.this)));
|
||||
|
||||
// Want to replace blocks
|
||||
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
|
||||
|
||||
// Pick how we're going to visit blocks
|
||||
RecursiveVisitor visitor = new DirectionalVisitor(mask, replace, origin, direction, (int) (radius * 2 + 1), this);
|
||||
|
||||
// Start at the origin
|
||||
visitor.visit(origin);
|
||||
|
||||
// Execute
|
||||
Operations.completeBlindly(visitor);
|
||||
return this.changes = visitor.getAffected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills an area recursively in the X/Z directions.
|
||||
*
|
||||
@ -1502,64 +1540,6 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
return this.changes = visitor.getAffected();
|
||||
}
|
||||
|
||||
// public int fillDirection(final Vector origin, PlayerDirection direction, final Pattern pattern, final double radius, final int depth, final boolean recursive) {
|
||||
// checkNotNull(origin);
|
||||
// checkNotNull(pattern);
|
||||
// checkArgument(radius >= 0, "radius >= 0");
|
||||
// checkArgument(depth >= 1, "depth >= 1");
|
||||
//
|
||||
// Vector dirVec = direction.vector();
|
||||
// BlockVector min = origin.toBlockVector();
|
||||
// BlockVector max = origin.toBlockVector();
|
||||
//
|
||||
// CuboidRegion cuboid = new CuboidRegion(new Vector(), new Vector());
|
||||
// switch (direction) {
|
||||
// case NORTH:
|
||||
// break;
|
||||
// case NORTH_EAST:
|
||||
// break;
|
||||
// case EAST:
|
||||
// break;
|
||||
// case SOUTH_EAST:
|
||||
// break;
|
||||
// case SOUTH:
|
||||
// break;
|
||||
// case SOUTH_WEST:
|
||||
// break;
|
||||
// case WEST:
|
||||
// break;
|
||||
// case NORTH_WEST:
|
||||
// break;
|
||||
// case UP:
|
||||
// break;
|
||||
// case DOWN:
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// final MaskIntersection mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), new BoundedHeightMask(Math.max(
|
||||
// (origin.getBlockY() - depth) + 1, 0), Math.min(EditSession.this.getMaximumPoint().getBlockY(), origin.getBlockY())), Masks.negate(new ExistingBlockMask(EditSession.this)));
|
||||
//
|
||||
// // Want to replace blocks
|
||||
// final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
|
||||
//
|
||||
// // Pick how we're going to visit blocks
|
||||
// RecursiveVisitor visitor;
|
||||
// if (recursive) {
|
||||
// visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), this);
|
||||
// } else {
|
||||
// visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1), this);
|
||||
// }
|
||||
//
|
||||
// // Start at the origin
|
||||
// visitor.visit(origin);
|
||||
//
|
||||
// // Execute
|
||||
// Operations.completeBlindly(visitor);
|
||||
// return this.changes = visitor.getAffected();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Remove a cuboid above the given position with a given apothem and a given height.
|
||||
*
|
||||
|
@ -57,6 +57,7 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.visitor.EntityVisitor;
|
||||
import com.sk89q.worldedit.internal.annotation.Direction;
|
||||
import com.sk89q.worldedit.internal.expression.Expression;
|
||||
import com.sk89q.worldedit.internal.expression.ExpressionException;
|
||||
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
|
||||
@ -175,19 +176,15 @@ public class UtilityCommands extends MethodCommands {
|
||||
usage = "<pattern> <radius> [depth]",
|
||||
desc = "Fill a hole",
|
||||
min = 2,
|
||||
max = 3
|
||||
max = 4
|
||||
)
|
||||
@CommandPermissions("worldedit.fill")
|
||||
@Logging(PLACEMENT)
|
||||
public void fill(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth) throws WorldEditException {
|
||||
public void fill(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth, @Optional("down") @Direction Vector direction) throws WorldEditException {
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
Vector pos = session.getPlacementPosition(player);
|
||||
int affected = 0;
|
||||
if (pattern instanceof BaseBlock) {
|
||||
affected = editSession.fillXZ(pos, ((BaseBlock) pattern), radius, (int) depth, false);
|
||||
} else {
|
||||
affected = editSession.fillXZ(pos, pattern, radius, (int) depth, false);
|
||||
}
|
||||
int affected;
|
||||
affected = editSession.fillDirection(pos, pattern, radius, (int) depth, direction);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
|
||||
}
|
||||
|
||||
@ -203,12 +200,7 @@ public class UtilityCommands extends MethodCommands {
|
||||
public void fillr(Player player, LocalSession session, EditSession editSession, Pattern pattern, double radius, @Optional("1") double depth) throws WorldEditException {
|
||||
worldEdit.checkMaxRadius(radius);
|
||||
Vector pos = session.getPlacementPosition(player);
|
||||
int affected;
|
||||
if (pattern instanceof BaseBlock) {
|
||||
affected = editSession.fillXZ(pos, ((BaseBlock) pattern), radius, (int) depth, true);
|
||||
} else {
|
||||
affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true);
|
||||
}
|
||||
int affected = editSession.fillXZ(pos, pattern, radius, (int) depth, true);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.sk89q.worldedit.MutableBlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Visits adjacent points on the same X-Z plane as long as the points
|
||||
* pass the given mask, and then executes the provided region
|
||||
* function on the entire column.
|
||||
* <p>
|
||||
* <p>This is used by {@code //fill}.</p>
|
||||
*/
|
||||
public class DirectionalVisitor extends RecursiveVisitor {
|
||||
|
||||
private final Vector origin;
|
||||
private final Vector dirVec;
|
||||
|
||||
public DirectionalVisitor(Mask mask, RegionFunction function, Vector origin, Vector direction) {
|
||||
this(mask, function, origin, direction, Integer.MAX_VALUE, null);
|
||||
}
|
||||
|
||||
public DirectionalVisitor(Mask mask, RegionFunction function, Vector origin, Vector direction, int distance, HasFaweQueue hasFaweQueue) {
|
||||
super(mask, function, distance, hasFaweQueue);
|
||||
checkNotNull(mask);
|
||||
this.origin = origin;
|
||||
this.dirVec = new MutableBlockVector(direction);
|
||||
final Collection<Vector> directions = this.getDirections();
|
||||
directions.clear();
|
||||
directions.add(new Vector(1, 0, 0));
|
||||
directions.add(new Vector(-1, 0, 0));
|
||||
directions.add(new Vector(0, 0, 1));
|
||||
directions.add(new Vector(0, 0, -1));
|
||||
directions.add(new Vector(0, -1, 0));
|
||||
directions.add(new Vector(0, 1, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisitable(final Vector from, final Vector to) {
|
||||
int dx = to.getBlockX() - from.getBlockX();
|
||||
int dz = to.getBlockZ() - from.getBlockZ();
|
||||
int dy = to.getBlockY() - from.getBlockY();
|
||||
|
||||
if (dx != 0) {
|
||||
if (dirVec.getBlockX() != 0 && dirVec.getBlockX() != dx) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (dy != 0) {
|
||||
if (dirVec.getBlockY() != 0 && dirVec.getBlockY() != dy) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (dz != 0) {
|
||||
if (dirVec.getBlockZ() != 0 && dirVec.getBlockZ() != dz) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return super.isVisitable(from, to);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user