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;
|
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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -32,6 +28,10 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.
|
* The clipboard remembers the state of a cuboid region.
|
||||||
*
|
*
|
||||||
@ -459,4 +459,43 @@ public class CuboidClipboard {
|
|||||||
|
|
||||||
return distribution;
|
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;
|
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.
|
* Count the number of blocks of a list of types in a region.
|
||||||
*
|
*
|
||||||
* @param region
|
* @param region
|
||||||
* @param searchIDs
|
* @param searchBlocks
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int countBlocks(Region region, Set<Integer> searchIDs) {
|
public int countBlocks(Region region, Set<BaseBlock> searchBlocks) {
|
||||||
int count = 0;
|
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) {
|
if (region instanceof CuboidRegion) {
|
||||||
// Doing this for speed
|
// Doing this for speed
|
||||||
Vector min = region.getMinimumPoint();
|
Vector min = region.getMinimumPoint();
|
||||||
@ -552,7 +576,8 @@ public class EditSession {
|
|||||||
for (int z = minZ; z <= maxZ; ++z) {
|
for (int z = minZ; z <= maxZ; ++z) {
|
||||||
Vector pt = new Vector(x, y, 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;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -560,7 +585,8 @@ public class EditSession {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Vector pt : region) {
|
for (Vector pt : region) {
|
||||||
if (searchIDs.contains(getBlockType(pt))) {
|
BaseBlock compare = new BaseBlock(getBlockType(pt), getBlockData(pt));
|
||||||
|
if (newSet.contains(compare)) {
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2671,6 +2697,65 @@ public class EditSession {
|
|||||||
return distribution;
|
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 {
|
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");
|
final Expression expression = Expression.compile(expressionString, "x", "y", "z", "type", "data");
|
||||||
expression.optimize();
|
expression.optimize();
|
||||||
@ -2855,4 +2940,5 @@ public class EditSession {
|
|||||||
}
|
}
|
||||||
} // while
|
} // while
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ import com.sk89q.worldedit.Vector;
|
|||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
import com.sk89q.worldedit.data.ChunkStore;
|
import com.sk89q.worldedit.data.ChunkStore;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegionSelector;
|
import com.sk89q.worldedit.regions.CuboidRegionSelector;
|
||||||
@ -562,61 +563,94 @@ public class SelectionCommands {
|
|||||||
aliases = { "/count" },
|
aliases = { "/count" },
|
||||||
usage = "<block>",
|
usage = "<block>",
|
||||||
desc = "Counts the number of a certain type of block",
|
desc = "Counts the number of a certain type of block",
|
||||||
|
flags = "d",
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1
|
max = 1
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.analysis.count")
|
@CommandPermissions("worldedit.analysis.count")
|
||||||
public void count(CommandContext args, LocalSession session, LocalPlayer player,
|
public void count(CommandContext args, LocalSession session, LocalPlayer player,
|
||||||
EditSession editSession) throws WorldEditException {
|
EditSession editSession) throws WorldEditException {
|
||||||
|
|
||||||
Set<Integer> searchIDs = we.getBlockIDs(player,
|
boolean useData = args.hasFlag('d');
|
||||||
args.getString(0), true);
|
if (args.getString(0).contains(":")) {
|
||||||
player.print("Counted: " +
|
useData = true; //override d flag, if they specified data they want it
|
||||||
editSession.countBlocks(session.getSelection(player.getWorld()), searchIDs));
|
}
|
||||||
|
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(
|
@Command(
|
||||||
aliases = { "/distr" },
|
aliases = { "/distr" },
|
||||||
usage = "",
|
usage = "",
|
||||||
desc = "Get the distribution of blocks in the selection",
|
desc = "Get the distribution of blocks in the selection",
|
||||||
help =
|
help =
|
||||||
"Gets the distribution of blocks in the selection.\n" +
|
"Gets the distribution of blocks in the selection.\n" +
|
||||||
"The -c flag gets the distribution of your clipboard.",
|
"The -c flag gets the distribution of your clipboard.\n" +
|
||||||
flags = "c",
|
"The -d flag separates blocks by data",
|
||||||
|
flags = "cd",
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 0
|
max = 0
|
||||||
)
|
)
|
||||||
@CommandPermissions("worldedit.analysis.distr")
|
@CommandPermissions("worldedit.analysis.distr")
|
||||||
public void distr(CommandContext args, LocalSession session, LocalPlayer player,
|
public void distr(CommandContext args, LocalSession session, LocalPlayer player,
|
||||||
EditSession editSession) throws WorldEditException {
|
EditSession editSession) throws WorldEditException {
|
||||||
|
|
||||||
List<Countable<Integer>> distribution;
|
|
||||||
int size;
|
int size;
|
||||||
|
boolean useData = args.hasFlag('d');
|
||||||
|
List<Countable<Integer>> distribution = null;
|
||||||
|
List<Countable<BaseBlock>> distributionData = null;
|
||||||
|
|
||||||
if (args.hasFlag('c')) {
|
if (args.hasFlag('c')) {
|
||||||
CuboidClipboard clip = session.getClipboard();
|
CuboidClipboard clip = session.getClipboard();
|
||||||
distribution = clip.getBlockDistribution();
|
if (useData) {
|
||||||
size = clip.getHeight() * clip.getLength() * clip.getWidth();
|
distributionData = clip.getBlockDistributionWithData();
|
||||||
|
} else {
|
||||||
|
distribution = clip.getBlockDistribution();
|
||||||
|
}
|
||||||
|
size = clip.getHeight() * clip.getLength() * clip.getWidth();
|
||||||
} else {
|
} else {
|
||||||
distribution = editSession
|
if (useData) {
|
||||||
.getBlockDistribution(session.getSelection(player.getWorld()));
|
distributionData = editSession.getBlockDistributionWithData(session.getSelection(player.getWorld()));
|
||||||
|
} else {
|
||||||
|
distribution = editSession.getBlockDistribution(session.getSelection(player.getWorld()));
|
||||||
|
}
|
||||||
size = session.getSelection(player.getWorld()).getArea();
|
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.");
|
player.printError("No blocks counted.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
player.print("# total blocks: " + size);
|
player.print("# total blocks: " + size);
|
||||||
|
|
||||||
for (Countable<Integer> c : distribution) {
|
if (useData) {
|
||||||
BlockType block = BlockType.fromID(c.getID());
|
for (Countable<BaseBlock> c : distributionData) {
|
||||||
String str = String.format("%-7s (%.3f%%) %s #%d",
|
String name = BlockType.fromID(c.getID().getId()).getName();
|
||||||
String.valueOf(c.getAmount()),
|
String str = String.format("%-7s (%.3f%%) %s #%d:%d",
|
||||||
c.getAmount() / (double) size * 100,
|
String.valueOf(c.getAmount()),
|
||||||
block == null ? "Unknown" : block.getName(), c.getID());
|
c.getAmount() / (double) size * 100,
|
||||||
player.print(str);
|
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