Converted /removenear, //replace to visitors.

This commit is contained in:
sk89q 2014-03-27 20:48:36 -07:00
parent 2311964b82
commit 5cfc05c616

View File

@ -791,16 +791,19 @@ public class EditSession {
/** /**
* Fills an area recursively in the X/Z directions. * Fills an area recursively in the X/Z directions.
* *
* @param origin * @param origin the origin to start the fill from
* @param pattern the pattern to fill with * @param pattern the pattern to fill with
* @param radius the radius of the spherical area to fill * @param radius the radius of the spherical area to fill, with 0 as the smallest radius
* @param depth the maximum depth, starting from the origin * @param depth the maximum depth, starting from the origin, with 1 as the smallest depth
* @param recursive whether a breadth-first search should be performed * @param recursive whether a breadth-first search should be performed
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive) public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
throws MaxChangedBlocksException { checkNotNull(origin, "origin must not be null");
checkNotNull(pattern, "pattern must not be null");
checkArgument(radius >= 0, "radius >= 0");
checkArgument(depth >= 1, "depth >= 1");
CombinedMask mask = new CombinedMask( CombinedMask mask = new CombinedMask(
new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))), new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))),
@ -831,10 +834,10 @@ public class EditSession {
* Remove a cuboid above the given position with a given apothem and a given height. * Remove a cuboid above the given position with a given apothem and a given height.
* *
* @param position base position * @param position base position
* @param apothem an apothem of the cuboid, where the minimum is 1 * @param apothem an apothem of the cuboid (on the XZ plane), where the minimum is 1
* @param height the height of the cuboid, where the minimum is 1 * @param height the height of the cuboid, where the minimum is 1
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int removeAbove(Vector position, int apothem, int height) throws MaxChangedBlocksException { public int removeAbove(Vector position, int apothem, int height) throws MaxChangedBlocksException {
checkNotNull(position, "position must not be null"); checkNotNull(position, "position must not be null");
@ -852,10 +855,10 @@ public class EditSession {
* Remove a cuboid below the given position with a given apothem and a given height. * Remove a cuboid below the given position with a given apothem and a given height.
* *
* @param position base position * @param position base position
* @param apothem an apothem of the cuboid, where the minimum is 1 * @param apothem an apothem of the cuboid (on the XZ plane), where the minimum is 1
* @param height the height of the cuboid, where the minimum is 1 * @param height the height of the cuboid, where the minimum is 1
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int removeBelow(Vector position, int apothem, int height) throws MaxChangedBlocksException { public int removeBelow(Vector position, int apothem, int height) throws MaxChangedBlocksException {
checkNotNull(position, "position must not be null"); checkNotNull(position, "position must not be null");
@ -870,41 +873,23 @@ public class EditSession {
} }
/** /**
* Remove nearby blocks of a type. * Remove blocks of a certain type nearby a given position.
* *
* @param pos * @param position center position of cuboid
* @param blockType * @param blockType the block type to match
* @param size * @param apothem an apothem of the cuboid, where the minimum is 1
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int removeNear(Vector pos, int blockType, int size) public int removeNear(Vector position, int blockType, int apothem) throws MaxChangedBlocksException {
throws MaxChangedBlocksException { checkNotNull(position, "position must not be null");
int affected = 0; checkArgument(apothem >= 1, "apothem >= 1");
BaseBlock air = new BaseBlock(BlockID.AIR);
int minX = pos.getBlockX() - size; Mask mask = new FuzzyBlockMask(new BaseBlock(blockType, -1));
int maxX = pos.getBlockX() + size; Vector adjustment = new Vector(1, 1, 1).multiply(apothem - 1);
int minY = Math.max(0, pos.getBlockY() - size); Region region = new CuboidRegion(position.add(adjustment.multiply(-1)), position.add(adjustment));
int maxY = Math.min(world.getMaxY(), pos.getBlockY() + size); Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
int minZ = pos.getBlockZ() - size; return replaceBlocks(region, mask, pattern);
int maxZ = pos.getBlockZ() + size;
for (int x = minX; x <= maxX; ++x) {
for (int y = minY; y <= maxY; ++y) {
for (int z = minZ; z <= maxZ; ++z) {
Vector p = new Vector(x, y, z);
if (getBlockType(p) == blockType) {
if (setBlock(p, air)) {
++affected;
}
}
}
}
}
return affected;
} }
/** /**
@ -930,6 +915,7 @@ public class EditSession {
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException { public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region, "region must not be null"); checkNotNull(region, "region must not be null");
checkNotNull(pattern, "pattern must not be null"); checkNotNull(pattern, "pattern must not be null");
BlockReplace replace = new BlockReplace(this, pattern); BlockReplace replace = new BlockReplace(this, pattern);
RegionVisitor visitor = new RegionVisitor(region, replace); RegionVisitor visitor = new RegionVisitor(region, replace);
OperationHelper.completeLegacy(visitor); OperationHelper.completeLegacy(visitor);
@ -937,174 +923,54 @@ public class EditSession {
} }
/** /**
* Replaces all the blocks of a type inside a region to another block type. * Replaces all the blocks matching a given filter, within a given region, to a block
* returned by a given pattern.
* *
* @param region * @param region the region to replace the blocks within
* @param fromBlockTypes -1 for non-air * @param filter a list of block types to match, or null to use {@link com.sk89q.worldedit.masks.ExistingBlockMask}
* @param toBlock * @param replacement the replacement block
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int replaceBlocks(Region region, Set<BaseBlock> fromBlockTypes, BaseBlock toBlock) throws MaxChangedBlocksException { public int replaceBlocks(Region region, Set<BaseBlock> filter, BaseBlock replacement) throws MaxChangedBlocksException {
Set<BaseBlock> definiteBlockTypes = new HashSet<BaseBlock>(); return replaceBlocks(region, filter, new SingleBlockPattern(replacement));
Set<Integer> fuzzyBlockTypes = new HashSet<Integer>();
if (fromBlockTypes != null) {
for (BaseBlock block : fromBlockTypes) {
if (block.getData() == -1) {
fuzzyBlockTypes.add(block.getType());
} else {
definiteBlockTypes.add(block);
}
}
}
int affected = 0;
if (region instanceof CuboidRegion) {
// Doing this for speed
Vector min = region.getMinimumPoint();
Vector max = region.getMaximumPoint();
int minX = min.getBlockX();
int minY = min.getBlockY();
int minZ = min.getBlockZ();
int maxX = max.getBlockX();
int maxY = max.getBlockY();
int maxZ = max.getBlockZ();
for (int x = minX; x <= maxX; ++x) {
for (int y = minY; y <= maxY; ++y) {
for (int z = minZ; z <= maxZ; ++z) {
Vector pt = new Vector(x, y, z);
BaseBlock curBlockType = getBlock(pt);
if (fromBlockTypes == null) {
//replace <to-block>
if (curBlockType.isAir()) {
continue;
}
} else {
//replace <from-block> <to-block>
if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
continue;
}
}
if (setBlock(pt, toBlock)) {
++affected;
}
}
}
}
} else {
for (Vector pt : region) {
BaseBlock curBlockType = getBlock(pt);
if (fromBlockTypes == null) {
//replace <to-block>
if (curBlockType.isAir()) {
continue;
}
} else {
//replace <from-block> <to-block>
if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
continue;
}
}
if (setBlock(pt, toBlock)) {
++affected;
}
}
}
return affected;
} }
/** /**
* Replaces all the blocks of a type inside a region to another block type. * Replaces all the blocks matching a given filter, within a given region, to a block
* returned by a given pattern.
* *
* @param region * @param region the region to replace the blocks within
* @param fromBlockTypes -1 for non-air * @param filter a list of block types to match, or null to use {@link com.sk89q.worldedit.masks.ExistingBlockMask}
* @param pattern * @param pattern the pattern that provides the new blocks
* @return number of blocks affected * @return number of blocks affected
* @throws MaxChangedBlocksException * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/ */
public int replaceBlocks(Region region, Set<BaseBlock> fromBlockTypes, Pattern pattern) throws MaxChangedBlocksException { public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
Set<BaseBlock> definiteBlockTypes = new HashSet<BaseBlock>(); Mask mask = filter == null ? new ExistingBlockMask() : new FuzzyBlockMask(filter);
Set<Integer> fuzzyBlockTypes = new HashSet<Integer>(); return replaceBlocks(region, mask, pattern);
if (fromBlockTypes != null) { }
for (BaseBlock block : fromBlockTypes) {
if (block.getData() == -1) {
fuzzyBlockTypes.add(block.getType());
} else {
definiteBlockTypes.add(block);
}
}
}
int affected = 0; /**
* Replaces all the blocks matching a given mask, within a given region, to a block
* returned by a given pattern.
*
* @param region the region to replace the blocks within
* @param mask the mask that blocks must match
* @param pattern the pattern that provides the new blocks
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region, "region must not be null");
checkNotNull(mask, "mask must not be null");
checkNotNull(pattern, "pattern must not be null");
if (region instanceof CuboidRegion) { BlockReplace replace = new BlockReplace(this, pattern);
// Doing this for speed RegionMaskFilter filter = new RegionMaskFilter(this, mask, replace);
Vector min = region.getMinimumPoint(); RegionVisitor visitor = new RegionVisitor(region, filter);
Vector max = region.getMaximumPoint(); OperationHelper.completeLegacy(visitor);
return visitor.getAffected();
int minX = min.getBlockX();
int minY = min.getBlockY();
int minZ = min.getBlockZ();
int maxX = max.getBlockX();
int maxY = max.getBlockY();
int maxZ = max.getBlockZ();
for (int x = minX; x <= maxX; ++x) {
for (int y = minY; y <= maxY; ++y) {
for (int z = minZ; z <= maxZ; ++z) {
Vector pt = new Vector(x, y, z);
BaseBlock curBlockType = getBlock(pt);
if (fromBlockTypes == null) {
//replace <to-block>
if (curBlockType.isAir()) {
continue;
}
} else {
//replace <from-block> <to-block>
if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
continue;
}
}
if (setBlock(pt, pattern.next(pt))) {
++affected;
}
}
}
}
} else {
for (Vector pt : region) {
BaseBlock curBlockType = getBlock(pt);
if (fromBlockTypes == null) {
//replace <to-block>
if (curBlockType.isAir()) {
continue;
}
} else {
//replace <from-block> <to-block>
if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
continue;
}
}
if (setBlock(pt, pattern.next(pt))) {
++affected;
}
}
}
return affected;
} }
public int center(Region region, Pattern pattern) public int center(Region region, Pattern pattern)