Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-12 22:20:08 +01:00
Added polygonal regions.
Dieser Commit ist enthalten in:
Ursprung
9667e92d66
Commit
97529abaca
13
plugin.yml
13
plugin.yml
@ -178,15 +178,20 @@ commands:
|
|||||||
//count:
|
//count:
|
||||||
description: Counts the number of a certain type of block
|
description: Counts the number of a certain type of block
|
||||||
usage: /<command> <block>
|
usage: /<command> <block>
|
||||||
/size:
|
/m:
|
||||||
description: Get information about the selection
|
description: Get information about the selection
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
|
aliases: ['//size']
|
||||||
/shift:
|
/shift:
|
||||||
description: Shift the selection area
|
description: Shift the selection area
|
||||||
usage: /<command> <amount> [direction]
|
usage: /<command> <amount> [direction]
|
||||||
/expand:
|
/expand:
|
||||||
description: Expand the selection area
|
description: Expand the selection area
|
||||||
usage: /<command> <amount> [reverse-amount] <direction>
|
usage: /<command> <amount> [reverse-amount] <direction>
|
||||||
|
/sel:
|
||||||
|
description: Choose a region selector
|
||||||
|
usage: /<command> [type]
|
||||||
|
aliases: [',']
|
||||||
/inset:
|
/inset:
|
||||||
description: Inset the selection area
|
description: Inset the selection area
|
||||||
usage: /<command> [-hv] <amount>
|
usage: /<command> [-hv] <amount>
|
||||||
@ -299,6 +304,10 @@ commands:
|
|||||||
/drain:
|
/drain:
|
||||||
description: Drain a pool
|
description: Drain a pool
|
||||||
usage: /<command> <radius>
|
usage: /<command> <radius>
|
||||||
/version:
|
version:
|
||||||
description: Get WorldEdit version
|
description: Get WorldEdit version
|
||||||
usage: /<command>
|
usage: /<command>
|
||||||
|
aliases: ['ver']
|
||||||
|
reload:
|
||||||
|
description: Reload WorldEdit
|
||||||
|
usage: /<command>
|
||||||
|
@ -28,8 +28,9 @@ import com.sk89q.worldedit.tools.SinglePickaxe;
|
|||||||
import com.sk89q.worldedit.tools.BlockTool;
|
import com.sk89q.worldedit.tools.BlockTool;
|
||||||
import com.sk89q.worldedit.tools.Tool;
|
import com.sk89q.worldedit.tools.Tool;
|
||||||
import com.sk89q.worldedit.bags.BlockBag;
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegionSelector;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of this represents the WorldEdit session of a user. A session
|
* An instance of this represents the WorldEdit session of a user. A session
|
||||||
@ -51,9 +52,9 @@ public class LocalSession {
|
|||||||
|
|
||||||
private LocalConfiguration config;
|
private LocalConfiguration config;
|
||||||
|
|
||||||
|
private LocalWorld selectionWorld;
|
||||||
|
private RegionSelector regionSelector = new CuboidRegionSelector();
|
||||||
private boolean placeAtPos1 = false;
|
private boolean placeAtPos1 = false;
|
||||||
private Vector pos1, pos2;
|
|
||||||
private Region region;
|
|
||||||
private LinkedList<EditSession> history = new LinkedList<EditSession>();
|
private LinkedList<EditSession> history = new LinkedList<EditSession>();
|
||||||
private int historyPointer = 0;
|
private int historyPointer = 0;
|
||||||
private CuboidClipboard clipboard;
|
private CuboidClipboard clipboard;
|
||||||
@ -147,25 +148,41 @@ public class LocalSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to make sure that position 1 is defined.
|
* Get the region selector for defining the selection. If the selection
|
||||||
|
* was defined for a different world, the old selection will be discarded.
|
||||||
*
|
*
|
||||||
* @throws IncompleteRegionException
|
* @param world
|
||||||
|
* @return position
|
||||||
*/
|
*/
|
||||||
private void checkPos1() throws IncompleteRegionException {
|
public RegionSelector getRegionSelector(LocalWorld world) {
|
||||||
if (pos1 == null) {
|
if (selectionWorld == null) {
|
||||||
throw new IncompleteRegionException();
|
selectionWorld = world;
|
||||||
|
} else if (!selectionWorld.equals(world)) {
|
||||||
|
selectionWorld = world;
|
||||||
|
regionSelector.clear();
|
||||||
}
|
}
|
||||||
|
return regionSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to make sure that position 2 is defined.
|
* Get the region selector. This won't check worlds so make sure that
|
||||||
*
|
* this region selector isn't used blindly.
|
||||||
* @throws IncompleteRegionException
|
*
|
||||||
|
* @return position
|
||||||
*/
|
*/
|
||||||
private void checkPos2() throws IncompleteRegionException {
|
public RegionSelector getRegionSelector() {
|
||||||
if (pos2 == null) {
|
return regionSelector;
|
||||||
throw new IncompleteRegionException();
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Set the region selector.
|
||||||
|
*
|
||||||
|
* @param world
|
||||||
|
* @param selector
|
||||||
|
*/
|
||||||
|
public void setRegionSelector(LocalWorld world, RegionSelector selector) {
|
||||||
|
selectionWorld = world;
|
||||||
|
regionSelector = selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -173,80 +190,50 @@ public class LocalSession {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public boolean isRegionDefined() {
|
public boolean isRegionDefined() {
|
||||||
return pos1 != null && pos2 != null;
|
return regionSelector.isDefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets defined position 1.
|
* Returns true if the region is fully defined for the specified world.
|
||||||
*
|
*
|
||||||
* @return position 1
|
* @param world
|
||||||
* @throws IncompleteRegionException
|
* @return
|
||||||
*/
|
*/
|
||||||
public Vector getPos1() throws IncompleteRegionException {
|
public boolean isSelectionDefined(LocalWorld world) {
|
||||||
checkPos1();
|
if (selectionWorld == null || !selectionWorld.equals(world)) {
|
||||||
return pos1;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets position 1.
|
|
||||||
*
|
|
||||||
* @param pt
|
|
||||||
*/
|
|
||||||
public void setPos1(Vector pt) {
|
|
||||||
pos1 = pt;
|
|
||||||
if (pos1 != null && pos2 != null) {
|
|
||||||
region = new CuboidRegion(pos1, pos2);
|
|
||||||
}
|
}
|
||||||
|
return regionSelector.isDefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets position 2.
|
* Use <code>getSelection()</code>.
|
||||||
*
|
|
||||||
* @return position 2
|
|
||||||
* @throws IncompleteRegionException
|
|
||||||
*/
|
|
||||||
public Vector getPos2() throws IncompleteRegionException {
|
|
||||||
checkPos2();
|
|
||||||
return pos2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets position 2.
|
|
||||||
*
|
|
||||||
* @param pt
|
|
||||||
*/
|
|
||||||
public void setPos2(Vector pt) {
|
|
||||||
pos2 = pt;
|
|
||||||
if (pos1 != null && pos2 != null) {
|
|
||||||
region = new CuboidRegion(pos1, pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update session position 1/2 based on the currently set region,
|
|
||||||
* provided that the region is of a cuboid.
|
|
||||||
*/
|
|
||||||
public void learnRegionChanges() {
|
|
||||||
if (region instanceof CuboidRegion) {
|
|
||||||
CuboidRegion cuboidRegion = (CuboidRegion)region;
|
|
||||||
pos1 = cuboidRegion.getPos1();
|
|
||||||
pos2 = cuboidRegion.getPos2();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the region. If you change the region, you should
|
|
||||||
* call learnRegionChanges().
|
|
||||||
*
|
*
|
||||||
* @return region
|
* @return region
|
||||||
* @throws IncompleteRegionException
|
* @throws IncompleteRegionException
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Region getRegion() throws IncompleteRegionException {
|
public Region getRegion() throws IncompleteRegionException {
|
||||||
if (region == null) {
|
return regionSelector.getRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the selection region. If you change the region, you should
|
||||||
|
* call learnRegionChanges(). If the selection is defined in
|
||||||
|
* a different world, the <code>IncompleteRegionException</code>
|
||||||
|
* exception will be thrown.
|
||||||
|
*
|
||||||
|
* @param world
|
||||||
|
* @return region
|
||||||
|
* @throws IncompleteRegionException
|
||||||
|
*/
|
||||||
|
public Region getSelection(LocalWorld world) throws IncompleteRegionException {
|
||||||
|
if (selectionWorld == null || !selectionWorld.equals(world)) {
|
||||||
throw new IncompleteRegionException();
|
throw new IncompleteRegionException();
|
||||||
}
|
}
|
||||||
return region;
|
return regionSelector.getRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -353,8 +340,7 @@ public class LocalSession {
|
|||||||
return player.getBlockIn();
|
return player.getBlockIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPos1();
|
return regionSelector.getPrimaryPosition();
|
||||||
return pos1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,6 +145,15 @@ public class Vector2D {
|
|||||||
return new Vector2D(x, z);
|
return new Vector2D(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a BlockVector version.
|
||||||
|
*
|
||||||
|
* @return BlockVector
|
||||||
|
*/
|
||||||
|
public BlockVector2D toBlockVector2D() {
|
||||||
|
return new BlockVector2D(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if another object is equivalent.
|
* Checks if another object is equivalent.
|
||||||
*
|
*
|
||||||
|
@ -35,6 +35,7 @@ import com.sk89q.worldedit.LocalSession.CompassMode;
|
|||||||
import com.sk89q.worldedit.bags.BlockBag;
|
import com.sk89q.worldedit.bags.BlockBag;
|
||||||
import com.sk89q.worldedit.blocks.*;
|
import com.sk89q.worldedit.blocks.*;
|
||||||
import com.sk89q.worldedit.commands.*;
|
import com.sk89q.worldedit.commands.*;
|
||||||
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
import com.sk89q.worldedit.scripting.*;
|
import com.sk89q.worldedit.scripting.*;
|
||||||
import com.sk89q.worldedit.tools.BlockTool;
|
import com.sk89q.worldedit.tools.BlockTool;
|
||||||
import com.sk89q.worldedit.tools.Tool;
|
import com.sk89q.worldedit.tools.Tool;
|
||||||
@ -782,13 +783,9 @@ public class WorldEdit {
|
|||||||
|
|
||||||
if (itemInHand == config.wandItem && session.isToolControlEnabled()
|
if (itemInHand == config.wandItem && session.isToolControlEnabled()
|
||||||
&& player.hasPermission("worldedit.selection.pos")) {
|
&& player.hasPermission("worldedit.selection.pos")) {
|
||||||
session.setPos2(clicked);
|
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
||||||
|
if (selector.selectSecondary(clicked)) {
|
||||||
try {
|
selector.explainSecondarySelection(player, clicked);
|
||||||
player.print("Second position set to " + clicked
|
|
||||||
+ " (" + session.getRegion().getSize() + ").");
|
|
||||||
} catch (IncompleteRegionException e) {
|
|
||||||
player.print("Second position set to " + clicked + ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -823,19 +820,9 @@ public class WorldEdit {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
RegionSelector selector = session.getRegionSelector(player.getWorld());
|
||||||
if (session.getPos1().equals(clicked)) {
|
if (selector.selectPrimary(clicked)) {
|
||||||
return false;
|
selector.explainPrimarySelection(player, clicked);
|
||||||
}
|
|
||||||
} catch (IncompleteRegionException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
session.setPos1(clicked);
|
|
||||||
try {
|
|
||||||
player.print("First position set to " + clicked
|
|
||||||
+ " (" + session.getRegion().getSize() + ").");
|
|
||||||
} catch (IncompleteRegionException e) {
|
|
||||||
player.print("First position set to " + clicked + ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -208,7 +208,8 @@ public class WorldEditPlugin extends JavaPlugin {
|
|||||||
*/
|
*/
|
||||||
public Region getPlayerSelection(Player player)
|
public Region getPlayerSelection(Player player)
|
||||||
throws IncompleteRegionException {
|
throws IncompleteRegionException {
|
||||||
return controller.getSession(wrapPlayer(player)).getRegion();
|
return controller.getSession(wrapPlayer(player))
|
||||||
|
.getSelection(new BukkitWorld(player.getWorld()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,7 +70,7 @@ public class ChunkCommands {
|
|||||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Set<Vector2D> chunks = session.getRegion().getChunks();
|
Set<Vector2D> chunks = session.getSelection(player.getWorld()).getChunks();
|
||||||
|
|
||||||
for (Vector2D chunk : chunks) {
|
for (Vector2D chunk : chunks) {
|
||||||
player.print(NestedFileChunkStore.getFilename(chunk));
|
player.print(NestedFileChunkStore.getFilename(chunk));
|
||||||
@ -91,7 +91,7 @@ public class ChunkCommands {
|
|||||||
|
|
||||||
LocalConfiguration config = we.getConfiguration();
|
LocalConfiguration config = we.getConfiguration();
|
||||||
|
|
||||||
Set<Vector2D> chunks = session.getRegion().getChunks();
|
Set<Vector2D> chunks = session.getSelection(player.getWorld()).getChunks();
|
||||||
FileOutputStream out = null;
|
FileOutputStream out = null;
|
||||||
|
|
||||||
if (config.shellSaveType == null) {
|
if (config.shellSaveType == null) {
|
||||||
|
@ -47,7 +47,7 @@ public class ClipboardCommands {
|
|||||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
Vector min = region.getMinimumPoint();
|
Vector min = region.getMinimumPoint();
|
||||||
Vector max = region.getMaximumPoint();
|
Vector max = region.getMaximumPoint();
|
||||||
Vector pos = player.getBlockIn();
|
Vector pos = player.getBlockIn();
|
||||||
@ -79,7 +79,7 @@ public class ClipboardCommands {
|
|||||||
block = we.getBlock(player, args.getString(0));
|
block = we.getBlock(player, args.getString(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
Vector min = region.getMinimumPoint();
|
Vector min = region.getMinimumPoint();
|
||||||
Vector max = region.getMaximumPoint();
|
Vector max = region.getMaximumPoint();
|
||||||
Vector pos = player.getBlockIn();
|
Vector pos = player.getBlockIn();
|
||||||
@ -90,7 +90,7 @@ public class ClipboardCommands {
|
|||||||
clipboard.copy(editSession);
|
clipboard.copy(editSession);
|
||||||
session.setClipboard(clipboard);
|
session.setClipboard(clipboard);
|
||||||
|
|
||||||
editSession.setBlocks(session.getRegion(), block);
|
editSession.setBlocks(session.getSelection(player.getWorld()), block);
|
||||||
player.print("Block(s) cut.");
|
player.print("Block(s) cut.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +53,10 @@ public class RegionCommands {
|
|||||||
int affected;
|
int affected;
|
||||||
|
|
||||||
if (pattern instanceof SingleBlockPattern) {
|
if (pattern instanceof SingleBlockPattern) {
|
||||||
affected = editSession.setBlocks(session.getRegion(),
|
affected = editSession.setBlocks(session.getSelection(player.getWorld()),
|
||||||
((SingleBlockPattern)pattern).getBlock());
|
((SingleBlockPattern)pattern).getBlock());
|
||||||
} else {
|
} else {
|
||||||
affected = editSession.setBlocks(session.getRegion(), pattern);
|
affected = editSession.setBlocks(session.getSelection(player.getWorld()), pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
player.print(affected + " block(s) have been changed.");
|
player.print(affected + " block(s) have been changed.");
|
||||||
@ -86,10 +86,10 @@ public class RegionCommands {
|
|||||||
|
|
||||||
int affected = 0;
|
int affected = 0;
|
||||||
if (to instanceof SingleBlockPattern) {
|
if (to instanceof SingleBlockPattern) {
|
||||||
affected = editSession.replaceBlocks(session.getRegion(), from,
|
affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from,
|
||||||
((SingleBlockPattern)to).getBlock());
|
((SingleBlockPattern)to).getBlock());
|
||||||
} else {
|
} else {
|
||||||
affected = editSession.replaceBlocks(session.getRegion(), from, to);
|
affected = editSession.replaceBlocks(session.getSelection(player.getWorld()), from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
player.print(affected + " block(s) have been replaced.");
|
player.print(affected + " block(s) have been replaced.");
|
||||||
@ -109,7 +109,7 @@ public class RegionCommands {
|
|||||||
|
|
||||||
Pattern pat = we.getBlockPattern(player, args.getString(0));
|
Pattern pat = we.getBlockPattern(player, args.getString(0));
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
int affected = 0;
|
int affected = 0;
|
||||||
if (pat instanceof SingleBlockPattern) {
|
if (pat instanceof SingleBlockPattern) {
|
||||||
affected = editSession.overlayCuboidBlocks(region,
|
affected = editSession.overlayCuboidBlocks(region,
|
||||||
@ -133,7 +133,7 @@ public class RegionCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
BaseBlock block = we.getBlock(player, args.getString(0));
|
BaseBlock block = we.getBlock(player, args.getString(0));
|
||||||
int affected = editSession.makeCuboidWalls(session.getRegion(), block);
|
int affected = editSession.makeCuboidWalls(session.getSelection(player.getWorld()), block);
|
||||||
|
|
||||||
player.print(affected + " block(s) have been changed.");
|
player.print(affected + " block(s) have been changed.");
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ public class RegionCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
BaseBlock block = we.getBlock(player, args.getString(0));
|
BaseBlock block = we.getBlock(player, args.getString(0));
|
||||||
int affected = editSession.makeCuboidFaces(session.getRegion(), block);
|
int affected = editSession.makeCuboidFaces(session.getSelection(player.getWorld()), block);
|
||||||
player.print(affected + " block(s) have been changed.");
|
player.print(affected + " block(s) have been changed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ public class RegionCommands {
|
|||||||
iterations = args.getInteger(0);
|
iterations = args.getInteger(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightMap heightMap = new HeightMap(editSession, session.getRegion());
|
HeightMap heightMap = new HeightMap(editSession, session.getSelection(player.getWorld()));
|
||||||
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
|
HeightMapFilter filter = new HeightMapFilter(new GaussianKernel(5, 1.0));
|
||||||
int affected = heightMap.applyFilter(filter, iterations);
|
int affected = heightMap.applyFilter(filter, iterations);
|
||||||
player.print("Terrain's height map smoothed. " + affected + " block(s) changed.");
|
player.print("Terrain's height map smoothed. " + affected + " block(s) changed.");
|
||||||
@ -203,7 +203,7 @@ public class RegionCommands {
|
|||||||
replace = new BaseBlock(0);
|
replace = new BaseBlock(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int affected = editSession.moveCuboidRegion(session.getRegion(),
|
int affected = editSession.moveCuboidRegion(session.getSelection(player.getWorld()),
|
||||||
dir, count, true, replace);
|
dir, count, true, replace);
|
||||||
player.print(affected + " blocks moved.");
|
player.print(affected + " blocks moved.");
|
||||||
}
|
}
|
||||||
@ -226,7 +226,7 @@ public class RegionCommands {
|
|||||||
Vector dir = we.getDirection(player,
|
Vector dir = we.getDirection(player,
|
||||||
args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me");
|
args.argsLength() > 1 ? args.getString(1).toLowerCase() : "me");
|
||||||
|
|
||||||
int affected = editSession.stackCuboidRegion(session.getRegion(),
|
int affected = editSession.stackCuboidRegion(session.getSelection(player.getWorld()),
|
||||||
dir, count, !args.hasFlag('a'));
|
dir, count, !args.hasFlag('a'));
|
||||||
player.print(affected + " blocks changed. Undo with //undo");
|
player.print(affected + " blocks changed. Undo with //undo");
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,10 @@ import com.sk89q.minecraft.util.commands.CommandContext;
|
|||||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
import com.sk89q.worldedit.*;
|
import com.sk89q.worldedit.*;
|
||||||
import com.sk89q.worldedit.data.ChunkStore;
|
import com.sk89q.worldedit.data.ChunkStore;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegionSelector;
|
||||||
|
import com.sk89q.worldedit.regions.Polygonal2DRegionSelector;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.regions.RegionOperationException;
|
||||||
import com.sk89q.worldedit.blocks.*;
|
import com.sk89q.worldedit.blocks.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,14 +51,14 @@ public class SelectionCommands {
|
|||||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
session.setPos1(player.getBlockIn());
|
if (!session.getRegionSelector(player.getWorld())
|
||||||
|
.selectPrimary(player.getBlockIn())) {
|
||||||
if (session.isRegionDefined()) {
|
player.printError("Position already set.");
|
||||||
player.print("First position set to " + player.getBlockIn()
|
return;
|
||||||
+ " (" + session.getRegion().getSize() + ").");
|
|
||||||
} else {
|
|
||||||
player.print("First position set to " + player.getBlockIn() + ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getRegionSelector(player.getWorld())
|
||||||
|
.explainPrimarySelection(player, player.getBlockIn());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -69,15 +72,16 @@ public class SelectionCommands {
|
|||||||
public static void pos2(CommandContext args, WorldEdit we,
|
public static void pos2(CommandContext args, WorldEdit we,
|
||||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
session.setPos2(player.getBlockIn());
|
if (!session.getRegionSelector(player.getWorld())
|
||||||
|
.selectSecondary(player.getBlockIn())) {
|
||||||
if (session.isRegionDefined()) {
|
player.printError("Position already set.");
|
||||||
player.print("Second position set to " + player.getBlockIn()
|
return;
|
||||||
+ " (" + session.getRegion().getSize() + ").");
|
|
||||||
} else {
|
|
||||||
player.print("Second position set to " + player.getBlockIn() + ".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
session.getRegionSelector(player.getWorld())
|
||||||
|
.explainSecondarySelection(player, player.getBlockIn());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -95,13 +99,14 @@ public class SelectionCommands {
|
|||||||
Vector pos = player.getBlockTrace(300);
|
Vector pos = player.getBlockTrace(300);
|
||||||
|
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
session.setPos1(pos);
|
if (!session.getRegionSelector(player.getWorld())
|
||||||
if (session.isRegionDefined()) {
|
.selectPrimary(pos)) {
|
||||||
player.print("First position set to " + pos
|
player.printError("Position already set.");
|
||||||
+ " (" + session.getRegion().getSize() + ").");
|
return;
|
||||||
} else {
|
|
||||||
player.print("First position set to " + pos.toString() + " .");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getRegionSelector(player.getWorld())
|
||||||
|
.explainPrimarySelection(player, pos);
|
||||||
} else {
|
} else {
|
||||||
player.printError("No block in sight!");
|
player.printError("No block in sight!");
|
||||||
}
|
}
|
||||||
@ -122,14 +127,14 @@ public class SelectionCommands {
|
|||||||
Vector pos = player.getBlockTrace(300);
|
Vector pos = player.getBlockTrace(300);
|
||||||
|
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
session.setPos2(pos);
|
if (!session.getRegionSelector(player.getWorld())
|
||||||
|
.selectSecondary(pos)) {
|
||||||
if (session.isRegionDefined()) {
|
player.printError("Position already set.");
|
||||||
player.print("Second position set to " + pos
|
return;
|
||||||
+ " (" + session.getRegion().getSize() + ").");
|
|
||||||
} else {
|
|
||||||
player.print("Second position set to " + pos.toString() + " .");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.getRegionSelector(player.getWorld())
|
||||||
|
.explainSecondarySelection(player, pos);
|
||||||
} else {
|
} else {
|
||||||
player.printError("No block in sight!");
|
player.printError("No block in sight!");
|
||||||
}
|
}
|
||||||
@ -151,8 +156,10 @@ public class SelectionCommands {
|
|||||||
Vector min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
|
Vector min = new Vector(min2D.getBlockX() * 16, 0, min2D.getBlockZ() * 16);
|
||||||
Vector max = min.add(15, 127, 15);
|
Vector max = min.add(15, 127, 15);
|
||||||
|
|
||||||
session.setPos1(min);
|
CuboidRegionSelector selector = new CuboidRegionSelector();
|
||||||
session.setPos2(max);
|
selector.selectPrimary(min);
|
||||||
|
selector.selectSecondary(max);
|
||||||
|
session.setRegionSelector(player.getWorld(), selector);
|
||||||
|
|
||||||
player.print("Chunk selected: "
|
player.print("Chunk selected: "
|
||||||
+ min2D.getBlockX() + ", " + min2D.getBlockZ());
|
+ min2D.getBlockX() + ", " + min2D.getBlockZ());
|
||||||
@ -213,14 +220,18 @@ public class SelectionCommands {
|
|||||||
// sky and bedrock.
|
// sky and bedrock.
|
||||||
if (args.getString(0).equalsIgnoreCase("vert")
|
if (args.getString(0).equalsIgnoreCase("vert")
|
||||||
|| args.getString(0).equalsIgnoreCase("vertical")) {
|
|| args.getString(0).equalsIgnoreCase("vertical")) {
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
int oldSize = region.getSize();
|
try {
|
||||||
region.expand(new Vector(0, 128, 0));
|
int oldSize = region.getArea();
|
||||||
region.expand(new Vector(0, -128, 0));
|
region.expand(new Vector(0, 128, 0));
|
||||||
session.learnRegionChanges();
|
region.expand(new Vector(0, -128, 0));
|
||||||
int newSize = region.getSize();
|
session.getRegionSelector().learnChanges();
|
||||||
player.print("Region expanded " + (newSize - oldSize)
|
int newSize = region.getArea();
|
||||||
+ " blocks [top-to-bottom].");
|
player.print("Region expanded " + (newSize - oldSize)
|
||||||
|
+ " blocks [top-to-bottom].");
|
||||||
|
} catch (RegionOperationException e) {
|
||||||
|
player.printError(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -246,16 +257,16 @@ public class SelectionCommands {
|
|||||||
dir = we.getDirection(player, "me");
|
dir = we.getDirection(player, "me");
|
||||||
}
|
}
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
int oldSize = region.getSize();
|
int oldSize = region.getArea();
|
||||||
region.expand(dir.multiply(change));
|
region.expand(dir.multiply(change));
|
||||||
|
|
||||||
if (reverseChange != 0) {
|
if (reverseChange != 0) {
|
||||||
region.expand(dir.multiply(reverseChange));
|
region.expand(dir.multiply(reverseChange));
|
||||||
}
|
}
|
||||||
|
|
||||||
session.learnRegionChanges();
|
session.getRegionSelector().learnChanges();
|
||||||
int newSize = region.getSize();
|
int newSize = region.getArea();
|
||||||
|
|
||||||
player.print("Region expanded " + (newSize - oldSize) + " blocks.");
|
player.print("Region expanded " + (newSize - oldSize) + " blocks.");
|
||||||
}
|
}
|
||||||
@ -294,16 +305,20 @@ public class SelectionCommands {
|
|||||||
dir = we.getDirection(player, "me");
|
dir = we.getDirection(player, "me");
|
||||||
}
|
}
|
||||||
|
|
||||||
Region region = session.getRegion();
|
try {
|
||||||
int oldSize = region.getSize();
|
Region region = session.getSelection(player.getWorld());
|
||||||
region.contract(dir.multiply(change));
|
int oldSize = region.getArea();
|
||||||
if (reverseChange != 0) {
|
region.contract(dir.multiply(change));
|
||||||
region.contract(dir.multiply(reverseChange));
|
if (reverseChange != 0) {
|
||||||
|
region.contract(dir.multiply(reverseChange));
|
||||||
|
}
|
||||||
|
session.getRegionSelector().learnChanges();
|
||||||
|
int newSize = region.getArea();
|
||||||
|
|
||||||
|
player.print("Region contracted " + (oldSize - newSize) + " blocks.");
|
||||||
|
} catch (RegionOperationException e) {
|
||||||
|
player.printError(e.getMessage());
|
||||||
}
|
}
|
||||||
session.learnRegionChanges();
|
|
||||||
int newSize = region.getSize();
|
|
||||||
|
|
||||||
player.print("Region contracted " + (oldSize - newSize) + " blocks.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -327,12 +342,16 @@ public class SelectionCommands {
|
|||||||
dir = we.getDirection(player, "me");
|
dir = we.getDirection(player, "me");
|
||||||
}
|
}
|
||||||
|
|
||||||
Region region = session.getRegion();
|
try {
|
||||||
region.expand(dir.multiply(change));
|
Region region = session.getSelection(player.getWorld());
|
||||||
region.contract(dir.multiply(change));
|
region.expand(dir.multiply(change));
|
||||||
session.learnRegionChanges();
|
region.contract(dir.multiply(change));
|
||||||
|
session.getRegionSelector().learnChanges();
|
||||||
player.print("Region shifted.");
|
|
||||||
|
player.print("Region shifted.");
|
||||||
|
} catch (RegionOperationException e) {
|
||||||
|
player.printError(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -349,23 +368,27 @@ public class SelectionCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
int change = args.getInteger(0);
|
int change = args.getInteger(0);
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
|
|
||||||
if (!args.hasFlag('h')) {
|
try {
|
||||||
region.expand((new Vector(0, 1, 0)).multiply(change));
|
if (!args.hasFlag('h')) {
|
||||||
region.expand((new Vector(0, -1, 0)).multiply(change));
|
region.expand((new Vector(0, 1, 0)).multiply(change));
|
||||||
|
region.expand((new Vector(0, -1, 0)).multiply(change));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args.hasFlag('v')) {
|
||||||
|
region.expand((new Vector(1, 0, 0)).multiply(change));
|
||||||
|
region.expand((new Vector(-1, 0, 0)).multiply(change));
|
||||||
|
region.expand((new Vector(0, 0, 1)).multiply(change));
|
||||||
|
region.expand((new Vector(0, 0, -1)).multiply(change));
|
||||||
|
}
|
||||||
|
|
||||||
|
session.getRegionSelector().learnChanges();
|
||||||
|
|
||||||
|
player.print("Region outset.");
|
||||||
|
} catch (RegionOperationException e) {
|
||||||
|
player.printError(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.hasFlag('v')) {
|
|
||||||
region.expand((new Vector(1, 0, 0)).multiply(change));
|
|
||||||
region.expand((new Vector(-1, 0, 0)).multiply(change));
|
|
||||||
region.expand((new Vector(0, 0, 1)).multiply(change));
|
|
||||||
region.expand((new Vector(0, 0, -1)).multiply(change));
|
|
||||||
}
|
|
||||||
|
|
||||||
session.learnRegionChanges();
|
|
||||||
|
|
||||||
player.print("Region outset.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -382,7 +405,7 @@ public class SelectionCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
int change = args.getInteger(0);
|
int change = args.getInteger(0);
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
|
|
||||||
if (!args.hasFlag('h')) {
|
if (!args.hasFlag('h')) {
|
||||||
region.contract((new Vector(0, 1, 0)).multiply(change));
|
region.contract((new Vector(0, 1, 0)).multiply(change));
|
||||||
@ -395,14 +418,14 @@ public class SelectionCommands {
|
|||||||
region.contract((new Vector(0, 0, 1)).multiply(change));
|
region.contract((new Vector(0, 0, 1)).multiply(change));
|
||||||
region.contract((new Vector(0, 0, -1)).multiply(change));
|
region.contract((new Vector(0, 0, -1)).multiply(change));
|
||||||
}
|
}
|
||||||
|
|
||||||
session.learnRegionChanges();
|
session.getRegionSelector().learnChanges();
|
||||||
|
|
||||||
player.print("Region inset.");
|
player.print("Region inset.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
aliases = {"/size"},
|
aliases = {"/m", "//size"},
|
||||||
usage = "",
|
usage = "",
|
||||||
desc = "Get information about the selection",
|
desc = "Get information about the selection",
|
||||||
min = 0,
|
min = 0,
|
||||||
@ -412,17 +435,21 @@ public class SelectionCommands {
|
|||||||
public static void size(CommandContext args, WorldEdit we,
|
public static void size(CommandContext args, WorldEdit we,
|
||||||
LocalSession session, LocalPlayer player, EditSession editSession)
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
Vector size = region.getMaximumPoint()
|
Vector size = region.getMaximumPoint()
|
||||||
.subtract(region.getMinimumPoint())
|
.subtract(region.getMinimumPoint())
|
||||||
.add(1, 1, 1);
|
.add(1, 1, 1);
|
||||||
|
|
||||||
|
player.print("Type: " + session.getRegionSelector().getTypeName());
|
||||||
|
|
||||||
|
for (String line : session.getRegionSelector().getInformationLines()) {
|
||||||
|
player.print(line);
|
||||||
|
}
|
||||||
|
|
||||||
player.print("First position: " + session.getPos1());
|
|
||||||
player.print("Second position: " + session.getPos2());
|
|
||||||
player.print("Size: " + size);
|
player.print("Size: " + size);
|
||||||
player.print("Distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
|
player.print("Cuboid distance: " + region.getMaximumPoint().distance(region.getMinimumPoint()));
|
||||||
player.print("# of blocks: " + region.getSize());
|
player.print("# of blocks: " + region.getArea());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -440,7 +467,7 @@ public class SelectionCommands {
|
|||||||
Set<Integer> searchIDs = we.getBlockIDs(player,
|
Set<Integer> searchIDs = we.getBlockIDs(player,
|
||||||
args.getString(0), true);
|
args.getString(0), true);
|
||||||
player.print("Counted: " +
|
player.print("Counted: " +
|
||||||
editSession.countBlocks(session.getRegion(), searchIDs));
|
editSession.countBlocks(session.getSelection(player.getWorld()), searchIDs));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -457,12 +484,12 @@ public class SelectionCommands {
|
|||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
|
|
||||||
List<Countable<Integer>> distribution =
|
List<Countable<Integer>> distribution =
|
||||||
editSession.getBlockDistribution(session.getRegion());
|
editSession.getBlockDistribution(session.getSelection(player.getWorld()));
|
||||||
|
|
||||||
Logger logger = Logger.getLogger("Minecraft.WorldEdit");
|
Logger logger = Logger.getLogger("Minecraft.WorldEdit");
|
||||||
|
|
||||||
if (distribution.size() > 0) { // *Should* always be true
|
if (distribution.size() > 0) { // *Should* always be true
|
||||||
int size = session.getRegion().getSize();
|
int size = session.getSelection(player.getWorld()).getArea();
|
||||||
|
|
||||||
player.print("# total blocks: " + size);
|
player.print("# total blocks: " + size);
|
||||||
|
|
||||||
@ -486,4 +513,27 @@ public class SelectionCommands {
|
|||||||
player.printError("No blocks counted.");
|
player.printError("No blocks counted.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Command(
|
||||||
|
aliases = {"/sel", ","},
|
||||||
|
usage = "[type]",
|
||||||
|
desc = "Choose a region selector",
|
||||||
|
min = 1,
|
||||||
|
max = 1
|
||||||
|
)
|
||||||
|
public static void select(CommandContext args, WorldEdit we,
|
||||||
|
LocalSession session, LocalPlayer player, EditSession editSession)
|
||||||
|
throws WorldEditException {
|
||||||
|
|
||||||
|
String typeName = args.getString(0);
|
||||||
|
if (typeName.equalsIgnoreCase("cuboid")) {
|
||||||
|
session.setRegionSelector(player.getWorld(), new CuboidRegionSelector());
|
||||||
|
player.print("Cuboid: left click for point 1, right click for point 2");
|
||||||
|
} else if (typeName.equalsIgnoreCase("poly")) {
|
||||||
|
session.setRegionSelector(player.getWorld(), new Polygonal2DRegionSelector());
|
||||||
|
player.print("2D polygon selector: Left/right click to add a point.");
|
||||||
|
} else {
|
||||||
|
player.printError("Only 'cuboid' and 'poly' are accepted.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class SnapshotUtilCommands {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Region region = session.getRegion();
|
Region region = session.getSelection(player.getWorld());
|
||||||
Snapshot snapshot;
|
Snapshot snapshot;
|
||||||
|
|
||||||
if (args.argsLength() > 0) {
|
if (args.argsLength() > 0) {
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.regions;
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import com.sk89q.worldedit.data.ChunkStore;
|
import com.sk89q.worldedit.data.ChunkStore;
|
||||||
@ -28,7 +29,7 @@ import java.util.HashSet;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Albert
|
* @author sk89q
|
||||||
*/
|
*/
|
||||||
public class CuboidRegion implements Region {
|
public class CuboidRegion implements Region {
|
||||||
/**
|
/**
|
||||||
@ -80,7 +81,7 @@ public class CuboidRegion implements Region {
|
|||||||
*
|
*
|
||||||
* @return number of blocks
|
* @return number of blocks
|
||||||
*/
|
*/
|
||||||
public int getSize() {
|
public int getArea() {
|
||||||
Vector min = getMinimumPoint();
|
Vector min = getMinimumPoint();
|
||||||
Vector max = getMaximumPoint();
|
Vector max = getMaximumPoint();
|
||||||
|
|
||||||
@ -288,12 +289,30 @@ public class CuboidRegion implements Region {
|
|||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true based on whether the region contains the point,
|
||||||
|
*
|
||||||
|
* @param pt
|
||||||
|
*/
|
||||||
|
public boolean contains(Vector pt) {
|
||||||
|
double x = pt.getX();
|
||||||
|
double y = pt.getY();
|
||||||
|
double z = pt.getZ();
|
||||||
|
|
||||||
|
Vector min = getMinimumPoint();
|
||||||
|
Vector max = getMaximumPoint();
|
||||||
|
|
||||||
|
return x >= min.getBlockX() && x <= max.getBlockX()
|
||||||
|
&& y >= min.getBlockY() && y <= max.getBlockY()
|
||||||
|
&& z >= min.getBlockZ() && z <= max.getBlockZ();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the iterator.
|
* Get the iterator.
|
||||||
*
|
*
|
||||||
* @return iterator of Points
|
* @return iterator of points inside the region
|
||||||
*/
|
*/
|
||||||
public Iterator<Vector> iterator() {
|
public Iterator<BlockVector> iterator() {
|
||||||
throw new UnsupportedOperationException("Not implemented");
|
throw new UnsupportedOperationException("Not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
122
src/com/sk89q/worldedit/regions/CuboidRegionSelector.java
Normale Datei
122
src/com/sk89q/worldedit/regions/CuboidRegionSelector.java
Normale Datei
@ -0,0 +1,122 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
|
import com.sk89q.worldedit.LocalPlayer;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector for cuboids.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
|
public class CuboidRegionSelector implements RegionSelector {
|
||||||
|
protected BlockVector pos1;
|
||||||
|
protected BlockVector pos2;
|
||||||
|
protected CuboidRegion region = new CuboidRegion(new Vector(), new Vector());
|
||||||
|
|
||||||
|
public boolean selectPrimary(Vector pos) {
|
||||||
|
if (pos1 != null && pos1.equals(pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pos1 = pos.toBlockVector();
|
||||||
|
region.setPos1(pos1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean selectSecondary(Vector pos) {
|
||||||
|
if (pos2 != null && pos2.equals(pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pos2 = pos.toBlockVector();
|
||||||
|
region.setPos2(pos2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void explainPrimarySelection(LocalPlayer player, Vector pos) {
|
||||||
|
if (pos1 != null && pos2 != null) {
|
||||||
|
player.print("First position set to " + pos1
|
||||||
|
+ " (" + region.getArea() + ").");
|
||||||
|
} else {
|
||||||
|
player.print("First position set to " + pos1 + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void explainSecondarySelection(LocalPlayer player, Vector pos) {
|
||||||
|
if (pos1 != null && pos2 != null) {
|
||||||
|
player.print("Second position set to " + pos1
|
||||||
|
+ " (" + region.getArea() + ").");
|
||||||
|
} else {
|
||||||
|
player.print("Second position set to " + pos1 + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
|
||||||
|
if (pos1 == null) {
|
||||||
|
throw new IncompleteRegionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefined() {
|
||||||
|
return pos1 != null && pos2 != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region getRegion() throws IncompleteRegionException {
|
||||||
|
if (pos1 == null || pos2 == null) {
|
||||||
|
throw new IncompleteRegionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void learnChanges() {
|
||||||
|
pos1 = region.getPos1().toBlockVector();
|
||||||
|
pos2 = region.getPos2().toBlockVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
pos1 = null;
|
||||||
|
pos2 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeName() {
|
||||||
|
return "cuboid";
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getInformationLines() {
|
||||||
|
List<String> lines = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (pos1 != null) {
|
||||||
|
lines.add("Position 1: " + pos1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos2 != null) {
|
||||||
|
lines.add("Position 2: " + pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
}
|
527
src/com/sk89q/worldedit/regions/Polygonal2DRegion.java
Normale Datei
527
src/com/sk89q/worldedit/regions/Polygonal2DRegion.java
Normale Datei
@ -0,0 +1,527 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.BlockVector2D;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldedit.Vector2D;
|
||||||
|
import com.sk89q.worldedit.data.ChunkStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a 2D polygonal region.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
|
public class Polygonal2DRegion implements Region {
|
||||||
|
protected List<BlockVector2D> points;
|
||||||
|
protected BlockVector min;
|
||||||
|
protected BlockVector max;
|
||||||
|
protected int minY;
|
||||||
|
protected int maxY;
|
||||||
|
protected boolean hasY = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the region.
|
||||||
|
*/
|
||||||
|
public Polygonal2DRegion() {
|
||||||
|
points = new ArrayList<BlockVector2D>();
|
||||||
|
minY = 0;
|
||||||
|
maxY = 0;
|
||||||
|
hasY = false;
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the region.
|
||||||
|
*
|
||||||
|
* @param points
|
||||||
|
* @param minY
|
||||||
|
* @param maxY
|
||||||
|
*/
|
||||||
|
public Polygonal2DRegion(List<BlockVector2D> points, int minY, int maxY) {
|
||||||
|
this.points = points;
|
||||||
|
this.minY = minY;
|
||||||
|
this.maxY = maxY;
|
||||||
|
hasY = true;
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of points.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<BlockVector2D> getPoints() {
|
||||||
|
return Collections.unmodifiableList(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculate the bounding box of this polygonal region. This should be
|
||||||
|
* called after points have been changed.
|
||||||
|
*/
|
||||||
|
protected void recalculate() {
|
||||||
|
if (points.size() == 0) {
|
||||||
|
min = new BlockVector(0, 0, 0);
|
||||||
|
max = new BlockVector(0, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int minX = points.get(0).getBlockX();
|
||||||
|
int minZ = points.get(0).getBlockZ();
|
||||||
|
int maxX = points.get(0).getBlockX();
|
||||||
|
int maxZ = points.get(0).getBlockZ();
|
||||||
|
|
||||||
|
for (BlockVector2D v : points) {
|
||||||
|
int x = v.getBlockX();
|
||||||
|
int z = v.getBlockZ();
|
||||||
|
if (x < minX) minX = x;
|
||||||
|
if (z < minZ) minZ = z;
|
||||||
|
if (x > maxX) maxX = x;
|
||||||
|
if (z > maxZ) maxZ = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
int oldMinY = minY;
|
||||||
|
int oldMaxY = maxY;
|
||||||
|
minY = Math.min(oldMinY, oldMaxY);
|
||||||
|
maxY = Math.max(oldMinY, oldMaxY);
|
||||||
|
|
||||||
|
min = new BlockVector(minX, minY, minZ);
|
||||||
|
max = new BlockVector(maxX, maxY, maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a point to the list.
|
||||||
|
*
|
||||||
|
* @param pt
|
||||||
|
*/
|
||||||
|
public void addPoint(Vector2D pt) {
|
||||||
|
points.add(pt.toBlockVector2D());
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a point to the list.
|
||||||
|
*
|
||||||
|
* @param pt
|
||||||
|
*/
|
||||||
|
public void addPoint(BlockVector2D pt) {
|
||||||
|
points.add(pt);
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a point to the list.
|
||||||
|
*
|
||||||
|
* @param pt
|
||||||
|
*/
|
||||||
|
public void addPoint(Vector pt) {
|
||||||
|
points.add(new BlockVector2D(pt.getBlockX(), pt.getBlockZ()));
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the lower point of a region.
|
||||||
|
*
|
||||||
|
* @return min. point
|
||||||
|
*/
|
||||||
|
public Vector getMinimumPoint() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the upper point of a region.
|
||||||
|
*
|
||||||
|
* @return max. point
|
||||||
|
*/
|
||||||
|
public Vector getMaximumPoint() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of blocks in the region.
|
||||||
|
*
|
||||||
|
* @return number of blocks
|
||||||
|
*/
|
||||||
|
public int getArea() {
|
||||||
|
double area = 0;
|
||||||
|
int i, j = points.size() - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < points.size(); i++) {
|
||||||
|
area += (points.get(j).getBlockX() + points.get(i).getBlockX())
|
||||||
|
* (points.get(j).getBlockZ() - points.get(i).getBlockZ());
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)Math.floor(Math.abs(area * 0.5)
|
||||||
|
* (maxY - minY + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get X-size.
|
||||||
|
*
|
||||||
|
* @return width
|
||||||
|
*/
|
||||||
|
public int getWidth() {
|
||||||
|
return max.getBlockX() - min.getBlockX();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Y-size.
|
||||||
|
*
|
||||||
|
* @return height
|
||||||
|
*/
|
||||||
|
public int getHeight() {
|
||||||
|
return max.getBlockY() - min.getBlockY();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Z-size.
|
||||||
|
*
|
||||||
|
* @return length
|
||||||
|
*/
|
||||||
|
public int getLength() {
|
||||||
|
return max.getBlockZ() - min.getBlockZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand the region.
|
||||||
|
*
|
||||||
|
* @param change
|
||||||
|
*/
|
||||||
|
public void expand(Vector change) throws RegionOperationException {
|
||||||
|
if (change.getBlockX() != 0 || change.getBlockZ() != 0) {
|
||||||
|
throw new RegionOperationException("Polygons can only be expanded vertically.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int changeY = change.getBlockY();
|
||||||
|
if (changeY > 0) {
|
||||||
|
maxY += changeY;
|
||||||
|
} else {
|
||||||
|
minY += changeY;
|
||||||
|
}
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contract the region.
|
||||||
|
*
|
||||||
|
* @param change
|
||||||
|
*/
|
||||||
|
public void contract(Vector change) throws RegionOperationException {
|
||||||
|
if (change.getBlockX() != 0 || change.getBlockZ() != 0) {
|
||||||
|
throw new RegionOperationException("Polygons can only be contracted vertically.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int changeY = change.getBlockY();
|
||||||
|
if (changeY > 0) {
|
||||||
|
minY += changeY;
|
||||||
|
} else {
|
||||||
|
maxY += changeY;
|
||||||
|
}
|
||||||
|
recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a point is inside this region.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean contains(Vector pt) {
|
||||||
|
return contains(points, minY, maxY, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if a point is inside a region.
|
||||||
|
*
|
||||||
|
* @param points
|
||||||
|
* @param minY
|
||||||
|
* @param maxY
|
||||||
|
* @param pt
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean contains(List<BlockVector2D> points, int minY,
|
||||||
|
int maxY, Vector pt) {
|
||||||
|
if (points.size() < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int targetX = pt.getBlockX();
|
||||||
|
int targetY = pt.getBlockY();
|
||||||
|
int targetZ = pt.getBlockZ();
|
||||||
|
|
||||||
|
if (targetY < minY || targetY > maxY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean inside = false;
|
||||||
|
int npoints = points.size();
|
||||||
|
int xNew, zNew;
|
||||||
|
int xOld, zOld;
|
||||||
|
int x1, z1;
|
||||||
|
int x2, z2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
xOld = points.get(npoints - 1).getBlockX();
|
||||||
|
zOld = points.get(npoints - 1).getBlockZ();
|
||||||
|
|
||||||
|
for (i = 0; i < npoints; i++) {
|
||||||
|
xNew = points.get(i).getBlockX();
|
||||||
|
zNew = points.get(i).getBlockZ();
|
||||||
|
|
||||||
|
if (xNew > xOld) {
|
||||||
|
x1 = xOld - 1;
|
||||||
|
x2 = xNew;
|
||||||
|
z1 = zOld;
|
||||||
|
z2 = zNew + 1;
|
||||||
|
} else {
|
||||||
|
x1 = xNew - 1;
|
||||||
|
x2 = xOld;
|
||||||
|
z1 = zNew;
|
||||||
|
z2 = zOld + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xNew < targetX == targetX <= xOld) {
|
||||||
|
long v1 = ((long) targetZ - (long) z1) * (long) (x2 - x1);
|
||||||
|
long v2 = ((long) z2 - (long) z1) * (long) (targetX - x1);
|
||||||
|
|
||||||
|
if (v1 < v2) {
|
||||||
|
inside = !inside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xOld = xNew;
|
||||||
|
zOld = zNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of chunks.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Set<Vector2D> getChunks() {
|
||||||
|
Set<Vector2D> chunks = new HashSet<Vector2D>();
|
||||||
|
|
||||||
|
Vector min = getMinimumPoint();
|
||||||
|
Vector max = getMaximumPoint();
|
||||||
|
|
||||||
|
for (int x = min.getBlockX(); x <= max.getBlockX(); x++) {
|
||||||
|
for (int y = min.getBlockY(); y <= max.getBlockY(); y++) {
|
||||||
|
for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) {
|
||||||
|
Vector pt = new Vector(x, y, z);
|
||||||
|
if (contains(pt)) { // Not the best
|
||||||
|
chunks.add(ChunkStore.toChunk(pt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of points.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return points.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand the height of the polygon to fit the specified Y.
|
||||||
|
*
|
||||||
|
* @param y
|
||||||
|
* @return true if the area was expanded
|
||||||
|
*/
|
||||||
|
public boolean expandY(int y) {
|
||||||
|
if (!hasY) {
|
||||||
|
minY = y;
|
||||||
|
maxY = y;
|
||||||
|
hasY = true;
|
||||||
|
return true;
|
||||||
|
} else if (y < minY) {
|
||||||
|
minY = y;
|
||||||
|
return true;
|
||||||
|
} else if (y > maxY) {
|
||||||
|
maxY = y;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the iterator.
|
||||||
|
*
|
||||||
|
* @return iterator of points inside the region
|
||||||
|
*/
|
||||||
|
public Iterator<BlockVector> iterator() {
|
||||||
|
return new Polygonal2DRegionIterator(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Incomplete iterator. Where's my yield?!
|
||||||
|
|
||||||
|
ArrayList<BlockVector> items = new ArrayList<BlockVector>();
|
||||||
|
|
||||||
|
int nodes, pixelZ, i, j, swap;
|
||||||
|
int n = points.size();
|
||||||
|
int[] nodeX = new int[n];
|
||||||
|
|
||||||
|
int minZ = getMinimumPoint().getBlockZ();
|
||||||
|
int maxZ = getMaximumPoint().getBlockZ();
|
||||||
|
|
||||||
|
for (pixelZ = minZ; pixelZ < maxZ; pixelZ++) {
|
||||||
|
// Build a list of nodes
|
||||||
|
nodes = 0;
|
||||||
|
j = n - 1;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (points.get(i).getBlockZ() < (double) pixelZ
|
||||||
|
&& points.get(j).getBlockZ() >= (double) pixelZ
|
||||||
|
|| points.get(j).getBlockZ() < (double) pixelZ
|
||||||
|
&& points.get(i).getBlockZ() >= (double) pixelZ) {
|
||||||
|
nodeX[nodes++] = (int) (points.get(i).getBlockX()
|
||||||
|
+ (pixelZ - points.get(i).getBlockZ())
|
||||||
|
/ (points.get(j).getBlockZ() - points.get(i)
|
||||||
|
.getBlockZ())
|
||||||
|
* (points.get(j).getBlockX() - points.get(i)
|
||||||
|
.getBlockX()));
|
||||||
|
}
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the nodes, via a simple bubble sort
|
||||||
|
i = 0;
|
||||||
|
while (i < nodes - 1) {
|
||||||
|
if (nodeX[i] > nodeX[i + 1]) {
|
||||||
|
swap = nodeX[i];
|
||||||
|
nodeX[i] = nodeX[i + 1];
|
||||||
|
nodeX[i + 1] = swap;
|
||||||
|
if (i > 0)
|
||||||
|
i--;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the pixels between node pairs
|
||||||
|
for (i = 0; i < nodes; i += 2) {
|
||||||
|
for (j = nodeX[i]; j < nodeX[i + 1]; j++) {
|
||||||
|
for (int y = minY; y >= maxY; y++) {
|
||||||
|
items.add(new BlockVector(j, y, pixelZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items.iterator();*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A terrible polygonal region iterator.
|
||||||
|
*/
|
||||||
|
public class Polygonal2DRegionIterator implements Iterator<BlockVector> {
|
||||||
|
protected List<BlockVector2D> points = new ArrayList<BlockVector2D>();
|
||||||
|
protected int minX;
|
||||||
|
protected int minY;
|
||||||
|
protected int minZ;
|
||||||
|
protected int maxX;
|
||||||
|
protected int maxY;
|
||||||
|
protected int maxZ;
|
||||||
|
protected int n;
|
||||||
|
protected int i;
|
||||||
|
protected int curX;
|
||||||
|
protected int curZ;
|
||||||
|
protected int curY;
|
||||||
|
protected BlockVector next;
|
||||||
|
|
||||||
|
public Polygonal2DRegionIterator(Polygonal2DRegion region) {
|
||||||
|
points = new ArrayList<BlockVector2D>(region.points);
|
||||||
|
Vector min = region.getMinimumPoint();
|
||||||
|
Vector max = region.getMaximumPoint();
|
||||||
|
minX = min.getBlockX();
|
||||||
|
minY = min.getBlockY();
|
||||||
|
minZ = min.getBlockZ();
|
||||||
|
maxX = max.getBlockX();
|
||||||
|
maxY = max.getBlockY();
|
||||||
|
maxZ = max.getBlockZ();
|
||||||
|
n = (maxX - minX + 1) * (maxZ - minZ + 1);
|
||||||
|
i = 0;
|
||||||
|
curX = 0;
|
||||||
|
curZ = 0;
|
||||||
|
curY = minY;
|
||||||
|
next = null;
|
||||||
|
findNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findNext() {
|
||||||
|
if (i >= n) {
|
||||||
|
next = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next != null && curY <= maxY) {
|
||||||
|
curY++;
|
||||||
|
next = new BlockVector(curX, curY, curZ);
|
||||||
|
if (curY > maxY) {
|
||||||
|
i++;
|
||||||
|
curY = minY;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < n) {
|
||||||
|
curZ = i / (maxX - minX + 1) + minZ;
|
||||||
|
curX = (i % (maxX - minX + 1)) + minX;
|
||||||
|
BlockVector pt = new BlockVector(curX, minY, curZ);
|
||||||
|
if (contains(points, minY, maxY, pt)) {
|
||||||
|
next = pt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return next != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockVector next() {
|
||||||
|
BlockVector next = this.next;
|
||||||
|
findNext();
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
throw new UnsupportedOperationException("Not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
114
src/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java
Normale Datei
114
src/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java
Normale Datei
@ -0,0 +1,114 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.BlockVector2D;
|
||||||
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
|
import com.sk89q.worldedit.LocalPlayer;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector for polygonal regions.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
|
public class Polygonal2DRegionSelector implements RegionSelector {
|
||||||
|
protected BlockVector pos1;
|
||||||
|
protected Polygonal2DRegion region = new Polygonal2DRegion();
|
||||||
|
|
||||||
|
public boolean selectPrimary(Vector pos) {
|
||||||
|
if (pos1 != null && pos1.equals(pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pos1 = pos.toBlockVector();
|
||||||
|
region = new Polygonal2DRegion();
|
||||||
|
region.addPoint(pos);
|
||||||
|
region.expandY(pos.getBlockY());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean selectSecondary(Vector pos) {
|
||||||
|
if (region.size() > 0) {
|
||||||
|
List<BlockVector2D> points = region.getPoints();
|
||||||
|
BlockVector2D lastPoint = points.get(region.size() - 1);
|
||||||
|
if (lastPoint.getBlockX() == pos.getBlockX()
|
||||||
|
&& lastPoint.getBlockZ() == pos.getBlockZ()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points.size() >= 20) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
region.addPoint(pos);
|
||||||
|
region.expandY(pos.getBlockY());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void explainPrimarySelection(LocalPlayer player, Vector pos) {
|
||||||
|
player.print("Starting a new polygon at " + pos + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void explainSecondarySelection(LocalPlayer player, Vector pos) {
|
||||||
|
player.print("Added point #" + region.size() + " at " + pos + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
|
||||||
|
if (pos1 == null) {
|
||||||
|
throw new IncompleteRegionException();
|
||||||
|
}
|
||||||
|
return pos1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Region getRegion() throws IncompleteRegionException {
|
||||||
|
if (!isDefined()) {
|
||||||
|
throw new IncompleteRegionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefined() {
|
||||||
|
return region.size() > 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void learnChanges() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
pos1 = null;
|
||||||
|
region = new Polygonal2DRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeName() {
|
||||||
|
return "2Dx1D polygon";
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getInformationLines() {
|
||||||
|
List<String> lines = new ArrayList<String>();
|
||||||
|
lines.add("# points: " + region.size());
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -19,15 +19,16 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.regions;
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Albert
|
* @author sk89q
|
||||||
*/
|
*/
|
||||||
public interface Region extends Iterable<Vector> {
|
public interface Region extends Iterable<BlockVector> {
|
||||||
/**
|
/**
|
||||||
* Get the lower point of a region.
|
* Get the lower point of a region.
|
||||||
*
|
*
|
||||||
@ -45,7 +46,7 @@ public interface Region extends Iterable<Vector> {
|
|||||||
*
|
*
|
||||||
* @return number of blocks
|
* @return number of blocks
|
||||||
*/
|
*/
|
||||||
public int getSize();
|
public int getArea();
|
||||||
/**
|
/**
|
||||||
* Get X-size.
|
* Get X-size.
|
||||||
*
|
*
|
||||||
@ -68,14 +69,23 @@ public interface Region extends Iterable<Vector> {
|
|||||||
* Expand the region.
|
* Expand the region.
|
||||||
*
|
*
|
||||||
* @param change
|
* @param change
|
||||||
|
* @throws RegionOperationException
|
||||||
*/
|
*/
|
||||||
public void expand(Vector change);
|
public void expand(Vector change) throws RegionOperationException;
|
||||||
/**
|
/**
|
||||||
* Contract the region.
|
* Contract the region.
|
||||||
*
|
*
|
||||||
* @param change
|
* @param change
|
||||||
|
* @throws RegionOperationException
|
||||||
*/
|
*/
|
||||||
public void contract(Vector change);
|
public void contract(Vector change) throws RegionOperationException;
|
||||||
|
/**
|
||||||
|
* Returns true based on whether the region contains the point,
|
||||||
|
*
|
||||||
|
* @param pt
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean contains(Vector pt);
|
||||||
/**
|
/**
|
||||||
* Get a list of chunks.
|
* Get a list of chunks.
|
||||||
*
|
*
|
||||||
|
30
src/com/sk89q/worldedit/regions/RegionOperationException.java
Normale Datei
30
src/com/sk89q/worldedit/regions/RegionOperationException.java
Normale Datei
@ -0,0 +1,30 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
|
||||||
|
public class RegionOperationException extends WorldEditException {
|
||||||
|
private static final long serialVersionUID = -6180325009115242142L;
|
||||||
|
|
||||||
|
public RegionOperationException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
112
src/com/sk89q/worldedit/regions/RegionSelector.java
Normale Datei
112
src/com/sk89q/worldedit/regions/RegionSelector.java
Normale Datei
@ -0,0 +1,112 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldEdit
|
||||||
|
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.regions;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
|
import com.sk89q.worldedit.LocalPlayer;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Region selection factory.
|
||||||
|
*
|
||||||
|
* @author sk89q
|
||||||
|
*/
|
||||||
|
public interface RegionSelector {
|
||||||
|
/**
|
||||||
|
* Called when the first point is selected.
|
||||||
|
*
|
||||||
|
* @param pos
|
||||||
|
* @return true if something changed
|
||||||
|
*/
|
||||||
|
public boolean selectPrimary(Vector pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the second point is selected.
|
||||||
|
*
|
||||||
|
* @param pos
|
||||||
|
* @return true if something changed
|
||||||
|
*/
|
||||||
|
public boolean selectSecondary(Vector pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the player information about his/her primary selection.
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* @param pos
|
||||||
|
*/
|
||||||
|
public void explainPrimarySelection(LocalPlayer player, Vector pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the player information about his/her secondary selection.
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* @param pos
|
||||||
|
*/
|
||||||
|
public void explainSecondarySelection(LocalPlayer player, Vector pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the primary position.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws IncompleteRegionException
|
||||||
|
*/
|
||||||
|
public BlockVector getPrimaryPosition() throws IncompleteRegionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the selection.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws IncompleteRegionException
|
||||||
|
*/
|
||||||
|
public Region getRegion() throws IncompleteRegionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the region has been fully defined.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean isDefined();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the selector with changes to the region.
|
||||||
|
*/
|
||||||
|
public void learnChanges();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the selection.
|
||||||
|
*/
|
||||||
|
public void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a lowercase name of this region selector type.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getTypeName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get lines of information about the selection.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> getInformationLines();
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren