mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
Added pattern support to //replace and //fill.
This commit is contained in:
parent
ff7df41823
commit
06d87a84cc
@ -414,6 +414,94 @@ public class EditSession {
|
||||
return affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills an area recursively in the X/Z directions.
|
||||
*
|
||||
* @param x
|
||||
* @param z
|
||||
* @param origin
|
||||
* @param pattern
|
||||
* @param radius
|
||||
* @param depth
|
||||
* @return number of blocks affected
|
||||
*/
|
||||
public int fillXZ(int x, int z, Vector origin, Pattern pattern,
|
||||
int radius, int depth)
|
||||
throws MaxChangedBlocksException {
|
||||
|
||||
int affected = 0;
|
||||
int originX = origin.getBlockX();
|
||||
int originY = origin.getBlockY();
|
||||
int originZ = origin.getBlockZ();
|
||||
|
||||
HashSet<BlockVector> visited = new HashSet<BlockVector>();
|
||||
Stack<BlockVector> queue = new Stack<BlockVector>();
|
||||
|
||||
queue.push(new BlockVector(x, 0, z));
|
||||
|
||||
while (!queue.empty()) {
|
||||
BlockVector pt = queue.pop();
|
||||
int cx = pt.getBlockX();
|
||||
int cz = pt.getBlockZ();
|
||||
|
||||
if (visited.contains(pt)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
visited.add(pt);
|
||||
|
||||
double dist = Math.sqrt(Math.pow(originX - cx, 2)
|
||||
+ Math.pow(originZ - cz, 2));
|
||||
int minY = originY - depth + 1;
|
||||
|
||||
if (dist > radius) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getBlock(new Vector(cx, originY, cz)).isAir()) {
|
||||
affected += fillY(cx, originY, cz, pattern, minY);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
queue.push(new BlockVector(cx + 1, 0, cz));
|
||||
queue.push(new BlockVector(cx - 1, 0, cz));
|
||||
queue.push(new BlockVector(cx, 0, cz + 1));
|
||||
queue.push(new BlockVector(cx, 0, cz - 1));
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively fills a block and below until it hits another block.
|
||||
*
|
||||
* @param x
|
||||
* @param cy
|
||||
* @param z
|
||||
* @param pattern
|
||||
* @param minY
|
||||
* @throws MaxChangedBlocksException
|
||||
* @return
|
||||
*/
|
||||
private int fillY(int x, int cy, int z, Pattern pattern, int minY)
|
||||
throws MaxChangedBlocksException {
|
||||
int affected = 0;
|
||||
|
||||
for (int y = cy; y >= minY; y--) {
|
||||
Vector pt = new Vector(x, y, z);
|
||||
|
||||
if (getBlock(pt).isAir()) {
|
||||
setBlock(pt, pattern.next(pt));
|
||||
affected++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove blocks above.
|
||||
*
|
||||
@ -661,6 +749,64 @@ public class EditSession {
|
||||
return affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all the blocks of a type inside a region to another block type.
|
||||
*
|
||||
* @param region
|
||||
* @param fromBlockType -1 for non-air
|
||||
* @param pattern
|
||||
* @return number of blocks affected
|
||||
* @throws MaxChangedBlocksException
|
||||
*/
|
||||
public int replaceBlocks(Region region, Set<Integer> fromBlockTypes,
|
||||
Pattern pattern)
|
||||
throws MaxChangedBlocksException {
|
||||
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);
|
||||
int curBlockType = getBlock(pt).getID();
|
||||
|
||||
if ((fromBlockTypes == null && curBlockType != 0) ||
|
||||
(fromBlockTypes != null &&
|
||||
fromBlockTypes.contains(curBlockType))) {
|
||||
if (setBlock(pt, pattern.next(pt))) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Vector pt : region) {
|
||||
int curBlockType = getBlock(pt).getID();
|
||||
|
||||
if (fromBlockTypes == null && curBlockType != 0 ||
|
||||
fromBlockTypes.contains(curBlockType)) {
|
||||
if (setBlock(pt, pattern.next(pt))) {
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make faces of the region (as if it was a cuboid if it's not).
|
||||
*
|
||||
|
@ -308,14 +308,15 @@ public class WorldEditListener extends PluginListener {
|
||||
* Get a list of blocks as a set.
|
||||
*
|
||||
* @param list
|
||||
* @params allBlocksAllowed
|
||||
* @return set
|
||||
*/
|
||||
public Set<Integer> getBlockIDs(String list) throws UnknownItemException,
|
||||
DisallowedItemException {
|
||||
public Set<Integer> getBlockIDs(String list, boolean allBlocksAllowed)
|
||||
throws UnknownItemException, DisallowedItemException {
|
||||
String[] items = list.split(",");
|
||||
Set<Integer> blocks = new HashSet<Integer>();
|
||||
for (String s : items) {
|
||||
blocks.add(getBlock(s).getID());
|
||||
blocks.add(getBlock(s, allBlocksAllowed).getID());
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
@ -725,14 +726,20 @@ public class WorldEditListener extends PluginListener {
|
||||
// Fill a hole
|
||||
} else if (split[0].equalsIgnoreCase("//fill")) {
|
||||
checkArgs(split, 2, 3, split[0]);
|
||||
BaseBlock block = getBlock(split[1]);
|
||||
Pattern pattern = getBlockPattern(split[1]);
|
||||
int radius = Math.max(1, Integer.parseInt(split[2]));
|
||||
checkMaxRadius(radius);
|
||||
int depth = split.length > 3 ? Math.max(1, Integer.parseInt(split[3])) : 1;
|
||||
|
||||
Vector pos = session.getPlacementPosition(player);
|
||||
int affected = editSession.fillXZ((int)pos.getX(), (int)pos.getZ(),
|
||||
pos, block, radius, depth);
|
||||
int affected = 0;
|
||||
if (pattern instanceof SingleBlockPattern) {
|
||||
affected = editSession.fillXZ((int)pos.getX(), (int)pos.getZ(),
|
||||
pos, ((SingleBlockPattern)pattern).getBlock(), radius, depth);
|
||||
} else {
|
||||
affected = editSession.fillXZ((int)pos.getX(), (int)pos.getZ(),
|
||||
pos, pattern, radius, depth);
|
||||
}
|
||||
player.print(affected + " block(s) have been created.");
|
||||
|
||||
return true;
|
||||
@ -936,17 +943,24 @@ public class WorldEditListener extends PluginListener {
|
||||
// Replace all blocks in the region
|
||||
} else if(split[0].equalsIgnoreCase("//replace")) {
|
||||
checkArgs(split, 1, 2, split[0]);
|
||||
|
||||
Set<Integer> from;
|
||||
BaseBlock to;
|
||||
Pattern to;
|
||||
if (split.length == 2) {
|
||||
from = null;
|
||||
to = getBlock(split[1], true);
|
||||
to = getBlockPattern(split[1]);
|
||||
} else {
|
||||
from = getBlockIDs(split[1]);
|
||||
to = getBlock(split[2]);
|
||||
from = getBlockIDs(split[1], true);
|
||||
to = getBlockPattern(split[2]);
|
||||
}
|
||||
|
||||
int affected = 0;
|
||||
if (to instanceof SingleBlockPattern) {
|
||||
affected = editSession.replaceBlocks(session.getRegion(), from,
|
||||
((SingleBlockPattern)to).getBlock());
|
||||
} else {
|
||||
affected = editSession.replaceBlocks(session.getRegion(), from, to);
|
||||
}
|
||||
|
||||
int affected = editSession.replaceBlocks(session.getRegion(), from, to);
|
||||
player.print(affected + " block(s) have been replaced.");
|
||||
|
||||
return true;
|
||||
@ -959,9 +973,9 @@ public class WorldEditListener extends PluginListener {
|
||||
BaseBlock to;
|
||||
if (split.length == 3) {
|
||||
from = null;
|
||||
to = getBlock(split[2], true);
|
||||
to = getBlock(split[2]);
|
||||
} else {
|
||||
from = getBlockIDs(split[2]);
|
||||
from = getBlockIDs(split[2], true);
|
||||
to = getBlock(split[3]);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user