geforkt von Mirrors/FastAsyncWorldEdit
Merge Moo0's data flag for distr.
Also added data flag to //count. //count -d 35 will now only search for white wool. //count 35:5 will only search for green wool. //count 35 will work as normal. //count 35:-1 will also work.
Dieser Commit ist enthalten in:
Ursprung
c2154b0f86
Commit
d78bbc4f68
@ -20,10 +20,6 @@
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
|
||||
import com.sk89q.worldedit.blocks.*;
|
||||
import com.sk89q.worldedit.data.*;
|
||||
import com.sk89q.worldedit.schematic.SchematicFormat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -32,6 +28,10 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.data.DataException;
|
||||
import com.sk89q.worldedit.schematic.SchematicFormat;
|
||||
|
||||
/**
|
||||
* The clipboard remembers the state of a cuboid region.
|
||||
*
|
||||
@ -459,4 +459,43 @@ public class CuboidClipboard {
|
||||
|
||||
return distribution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block distribution inside a clipboard with data values.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
// TODO reduce code duplication
|
||||
public List<Countable<BaseBlock>> getBlockDistributionWithData() {
|
||||
List<Countable<BaseBlock>> distribution = new ArrayList<Countable<BaseBlock>>();
|
||||
Map<BaseBlock, Countable<BaseBlock>> map = new HashMap<BaseBlock, Countable<BaseBlock>>();
|
||||
|
||||
int maxX = getWidth();
|
||||
int maxY = getHeight();
|
||||
int maxZ = getLength();
|
||||
|
||||
for (int x = 0; x < maxX; ++x) {
|
||||
for (int y = 0; y < maxY; ++y) {
|
||||
for (int z = 0; z < maxZ; ++z) {
|
||||
|
||||
int id = data[x][y][z].getId();
|
||||
int meta = data[x][y][z].getData();
|
||||
BaseBlock blk = new BaseBlock(id, meta);
|
||||
|
||||
if (map.containsKey(blk)) {
|
||||
map.get(blk).increment();
|
||||
} else {
|
||||
Countable<BaseBlock> c = new Countable<BaseBlock>(blk, 1);
|
||||
map.put(blk, c);
|
||||
distribution.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(distribution);
|
||||
// Collections.reverse(distribution);
|
||||
|
||||
return distribution;
|
||||
}
|
||||
}
|
||||
|
@ -525,16 +525,40 @@ public class EditSession {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int countBlock(Region region, Set<Integer> searchIDs) {
|
||||
Set<BaseBlock> passOn = new HashSet<BaseBlock>();
|
||||
for (Integer i : searchIDs) {
|
||||
passOn.add(new BaseBlock(i, -1));
|
||||
}
|
||||
return countBlocks(region, passOn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of blocks of a list of types in a region.
|
||||
*
|
||||
* @param region
|
||||
* @param searchIDs
|
||||
* @param searchBlocks
|
||||
* @return
|
||||
*/
|
||||
public int countBlocks(Region region, Set<Integer> searchIDs) {
|
||||
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
|
||||
int count = 0;
|
||||
|
||||
// allow -1 data in the searchBlocks to match any type
|
||||
Set<BaseBlock> newSet = new HashSet<BaseBlock>() {
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
for (BaseBlock b : this.toArray(new BaseBlock[this.size()])) {
|
||||
if (o instanceof BaseBlock) {
|
||||
if (b.equalsFuzzy((BaseBlock) o)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
newSet.addAll(searchBlocks);
|
||||
|
||||
if (region instanceof CuboidRegion) {
|
||||
// Doing this for speed
|
||||
Vector min = region.getMinimumPoint();
|
||||
@ -552,7 +576,8 @@ public class EditSession {
|
||||
for (int z = minZ; z <= maxZ; ++z) {
|
||||
Vector pt = new Vector(x, y, z);
|
||||
|
||||
if (searchIDs.contains(getBlockType(pt))) {
|
||||
BaseBlock compare = new BaseBlock(getBlockType(pt), getBlockData(pt));
|
||||
if (newSet.contains(compare)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
@ -560,7 +585,8 @@ public class EditSession {
|
||||
}
|
||||
} else {
|
||||
for (Vector pt : region) {
|
||||
if (searchIDs.contains(getBlockType(pt))) {
|
||||
BaseBlock compare = new BaseBlock(getBlockType(pt), getBlockData(pt));
|
||||
if (newSet.contains(compare)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
@ -2671,6 +2697,65 @@ public class EditSession {
|
||||
return distribution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block distribution (with data values) inside a region.
|
||||
*
|
||||
* @param region
|
||||
* @return
|
||||
*/
|
||||
// TODO reduce code duplication - probably during ops-redux
|
||||
public List<Countable<BaseBlock>> getBlockDistributionWithData(Region region) {
|
||||
List<Countable<BaseBlock>> distribution = new ArrayList<Countable<BaseBlock>>();
|
||||
Map<BaseBlock, Countable<BaseBlock>> map = new HashMap<BaseBlock, Countable<BaseBlock>>();
|
||||
|
||||
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 blk = new BaseBlock(getBlockType(pt), getBlockData(pt));
|
||||
|
||||
if (map.containsKey(blk)) {
|
||||
map.get(blk).increment();
|
||||
} else {
|
||||
Countable<BaseBlock> c = new Countable<BaseBlock>(blk, 1);
|
||||
map.put(blk, c);
|
||||
distribution.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Vector pt : region) {
|
||||
BaseBlock blk = new BaseBlock(getBlockType(pt), getBlockData(pt));
|
||||
|
||||
if (map.containsKey(blk)) {
|
||||
map.get(blk).increment();
|
||||
} else {
|
||||
Countable<BaseBlock> c = new Countable<BaseBlock>(blk, 1);
|
||||
map.put(blk, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(distribution);
|
||||
// Collections.reverse(distribution);
|
||||
|
||||
return distribution;
|
||||
}
|
||||
|
||||
public int makeShape(final Region region, final Vector zero, final Vector unit, final Pattern pattern, final String expressionString, final boolean hollow) throws ExpressionException, MaxChangedBlocksException {
|
||||
final Expression expression = Expression.compile(expressionString, "x", "y", "z", "type", "data");
|
||||
expression.optimize();
|
||||
@ -2855,4 +2940,5 @@ public class EditSession {
|
||||
}
|
||||
} // while
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.data.ChunkStore;
|
||||
import com.sk89q.worldedit.regions.CuboidRegionSelector;
|
||||
@ -562,61 +563,94 @@ public class SelectionCommands {
|
||||
aliases = { "/count" },
|
||||
usage = "<block>",
|
||||
desc = "Counts the number of a certain type of block",
|
||||
flags = "d",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.analysis.count")
|
||||
public void count(CommandContext args, LocalSession session, LocalPlayer player,
|
||||
EditSession editSession) throws WorldEditException {
|
||||
|
||||
Set<Integer> searchIDs = we.getBlockIDs(player,
|
||||
args.getString(0), true);
|
||||
player.print("Counted: " +
|
||||
editSession.countBlocks(session.getSelection(player.getWorld()), searchIDs));
|
||||
|
||||
boolean useData = args.hasFlag('d');
|
||||
if (args.getString(0).contains(":")) {
|
||||
useData = true; //override d flag, if they specified data they want it
|
||||
}
|
||||
if (useData) {
|
||||
Set<BaseBlock> searchBlocks = we.getBlocks(player, args.getString(0), true);
|
||||
int count = editSession.countBlocks(session.getSelection(player.getWorld()), searchBlocks);
|
||||
player.print("Counted: " + count);
|
||||
} else {
|
||||
Set<Integer> searchIDs = we.getBlockIDs(player, args.getString(0), true);
|
||||
int count = editSession.countBlock(session.getSelection(player.getWorld()), searchIDs);
|
||||
player.print("Counted: " + count);
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/distr" },
|
||||
usage = "",
|
||||
desc = "Get the distribution of blocks in the selection",
|
||||
desc = "Get the distribution of blocks in the selection",
|
||||
help =
|
||||
"Gets the distribution of blocks in the selection.\n" +
|
||||
"The -c flag gets the distribution of your clipboard.",
|
||||
flags = "c",
|
||||
"The -c flag gets the distribution of your clipboard.\n" +
|
||||
"The -d flag separates blocks by data",
|
||||
flags = "cd",
|
||||
min = 0,
|
||||
max = 0
|
||||
)
|
||||
@CommandPermissions("worldedit.analysis.distr")
|
||||
@CommandPermissions("worldedit.analysis.distr")
|
||||
public void distr(CommandContext args, LocalSession session, LocalPlayer player,
|
||||
EditSession editSession) throws WorldEditException {
|
||||
|
||||
List<Countable<Integer>> distribution;
|
||||
|
||||
int size;
|
||||
|
||||
boolean useData = args.hasFlag('d');
|
||||
List<Countable<Integer>> distribution = null;
|
||||
List<Countable<BaseBlock>> distributionData = null;
|
||||
|
||||
if (args.hasFlag('c')) {
|
||||
CuboidClipboard clip = session.getClipboard();
|
||||
distribution = clip.getBlockDistribution();
|
||||
size = clip.getHeight() * clip.getLength() * clip.getWidth();
|
||||
if (useData) {
|
||||
distributionData = clip.getBlockDistributionWithData();
|
||||
} else {
|
||||
distribution = clip.getBlockDistribution();
|
||||
}
|
||||
size = clip.getHeight() * clip.getLength() * clip.getWidth();
|
||||
} else {
|
||||
distribution = editSession
|
||||
.getBlockDistribution(session.getSelection(player.getWorld()));
|
||||
if (useData) {
|
||||
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));
|
||||
} else {
|
||||
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()));
|
||||
}
|
||||
size = session.getSelection(player.getWorld()).getArea();
|
||||
}
|
||||
|
||||
if (distribution.size() <= 0) { // *Should* always be true
|
||||
|
||||
if ((useData && distributionData.size() <= 0)
|
||||
|| (!useData && distribution.size() <= 0)) { // *Should* always be false
|
||||
player.printError("No blocks counted.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
player.print("# total blocks: " + size);
|
||||
|
||||
for (Countable<Integer> c : distribution) {
|
||||
BlockType block = BlockType.fromID(c.getID());
|
||||
String str = String.format("%-7s (%.3f%%) %s #%d",
|
||||
String.valueOf(c.getAmount()),
|
||||
c.getAmount() / (double) size * 100,
|
||||
block == null ? "Unknown" : block.getName(), c.getID());
|
||||
player.print(str);
|
||||
if (useData) {
|
||||
for (Countable<BaseBlock> c : distributionData) {
|
||||
String name = BlockType.fromID(c.getID().getId()).getName();
|
||||
String str = String.format("%-7s (%.3f%%) %s #%d:%d",
|
||||
String.valueOf(c.getAmount()),
|
||||
c.getAmount() / (double) size * 100,
|
||||
name == null ? "Unknown" : name,
|
||||
c.getID().getType(), c.getID().getData());
|
||||
player.print(str);
|
||||
}
|
||||
} else {
|
||||
for (Countable<Integer> c : distribution) {
|
||||
BlockType block = BlockType.fromID(c.getID());
|
||||
String str = String.format("%-7s (%.3f%%) %s #%d",
|
||||
String.valueOf(c.getAmount()),
|
||||
c.getAmount() / (double) size * 100,
|
||||
block == null ? "Unknown" : block.getName(), c.getID());
|
||||
player.print(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren