Added //count and //distr.

This commit is contained in:
sk89q 2010-11-16 22:59:53 -08:00
parent 7f2391649e
commit f810b18f07
3 changed files with 167 additions and 1 deletions

View File

@ -29,7 +29,9 @@ import java.util.LinkedHashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
/**
@ -1751,4 +1753,107 @@ public class EditSession {
setBlockIfAir(basePos.add(0, height, 0), leavesBlock);
}
/**
* Count the number of blocks of a list of types in a region.
*
* @param region
* @param searchIDs
* @return
*/
public int countBlocks(Region region, Set<Integer> searchIDs) {
int count = 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);
if (searchIDs.contains(getBlock(pt).getID())) {
count++;
}
}
}
}
} else {
for (Vector pt : region) {
if (searchIDs.contains(getBlock(pt).getID())) {
count++;
}
}
}
return count;
}
/**
* Get the block distribution inside a region.
*
* @param region
* @return
*/
public List<Countable<Integer>> getBlockDistribution(Region region) {
List<Countable<Integer>> distribution
= new ArrayList<Countable<Integer>>();
Map<Integer,Countable> map = new HashMap<Integer,Countable>();
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 id = getBlock(pt).getID();
if (map.containsKey(id)) {
map.get(id).increment();
} else {
Countable<Integer> c = new Countable<Integer>(id, 1);
map.put(id, c);
distribution.add(c);
}
}
}
}
} else {
for (Vector pt : region) {
int id = getBlock(pt).getID();
if (map.containsKey(id)) {
map.get(id).increment();
} else {
Countable<Integer> c = new Countable<Integer>(id, 1);
map.put(id, c);
}
}
}
Collections.sort(distribution);
//Collections.reverse(distribution);
return distribution;
}
}

View File

@ -110,6 +110,8 @@ public class WorldEditListener extends PluginListener {
commands.put("/clearhistory", "Clear history");
commands.put("/clearclipboard", "Clear clipboard");
commands.put("//size", "Get size of selected region");
commands.put("//count", "[BlockIDs] - Count the number of blocks in the region");
commands.put("//distr", "Get the top block distribution");
commands.put("//set", "[ID] - Set all blocks inside region");
commands.put("//outline", "[ID] - Outline the region with blocks");
commands.put("//walls", "[ID] - Build walls");
@ -890,6 +892,35 @@ public class WorldEditListener extends PluginListener {
player.print("# of blocks: " + region.getSize());
return true;
// Get count
} else if (split[0].equalsIgnoreCase("//count")) {
checkArgs(split, 1, 1, split[0]);
Set<Integer> searchIDs = getBlockIDs(split[1], true);
player.print("Counted: " +
editSession.countBlocks(session.getRegion(), searchIDs));
return true;
// Get block distribution
} else if (split[0].equalsIgnoreCase("//distr")) {
checkArgs(split, 0, 0, split[0]);
List<Countable<Integer>> distribution =
editSession.getBlockDistribution(session.getRegion());
if (distribution.size() > 0) { // *Should* always be true
int size = session.getRegion().getSize();
player.print("# total blocks: " + size);
for (Countable<Integer> c : distribution) {
player.print(String.format("%-7s (%.3f%%) %s",
String.valueOf(c.getAmount()),
c.getAmount() / (double)size * 100,
BlockType.fromID(c.getID()).getName()));
}
} else {
player.printError("No blocks counted.");
}
return true;
// Replace all blocks in the region
} else if(split[0].equalsIgnoreCase("//set")) {
checkArgs(split, 1, 1, split[0]);

View File

@ -23,7 +23,7 @@ package com.sk89q.worldedit;
*
* @author sk89q
*/
public class Countable<T> {
public class Countable<T> implements Comparable<Countable<T>> {
/**
* ID.
*/
@ -71,4 +71,34 @@ public class Countable<T> {
public void setAmount(int amount) {
this.amount = amount;
}
/**
* Decrement the amount.
*/
public void decrement() {
this.amount--;
}
/**
* Increment the amount.
*/
public void increment() {
this.amount++;
}
/**
* Comparison.
*
* @param other
* @return
*/
public int compareTo(Countable<T> other) {
if (amount > other.amount) {
return 1;
} else if (amount == other.amount) {
return 0;
} else {
return -1;
}
}
}