Added an extending cuboid selector.

It can be used with //sel extend.
Also made //sel carry over some information about the selection into the new selection mode.
Also cleaned up the source of the RegionSelectors and the //sel command a bit.
This commit is contained in:
TomyLobo 2011-12-12 05:12:24 +01:00
parent 3dabcdacd1
commit f5c6678da6
4 changed files with 186 additions and 39 deletions

View File

@ -28,9 +28,11 @@ 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.CuboidRegionSelector;
import com.sk89q.worldedit.regions.ExtendingCuboidRegionSelector;
import com.sk89q.worldedit.regions.Polygonal2DRegionSelector; 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.regions.RegionOperationException;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.blocks.*; import com.sk89q.worldedit.blocks.*;
/** /**
@ -597,7 +599,7 @@ public class SelectionCommands {
@Command( @Command(
aliases = { "/sel", ";" }, aliases = { "/sel", ";" },
usage = "[cuboid|poly]", usage = "[cuboid|extend|poly]",
desc = "Choose a region selector", desc = "Choose a region selector",
min = 0, min = 0,
max = 1 max = 1
@ -606,21 +608,30 @@ public class SelectionCommands {
LocalSession session, LocalPlayer player, EditSession editSession) LocalSession session, LocalPlayer player, EditSession editSession)
throws WorldEditException { throws WorldEditException {
final LocalWorld world = player.getWorld();
if (args.argsLength() == 0) { if (args.argsLength() == 0) {
session.getRegionSelector(player.getWorld()).clear(); session.getRegionSelector(world).clear();
return; return;
} }
String typeName = args.getString(0);
final String typeName = args.getString(0);
final RegionSelector oldSelector = session.getRegionSelector(world);
final RegionSelector selector;
if (typeName.equalsIgnoreCase("cuboid")) { if (typeName.equalsIgnoreCase("cuboid")) {
session.setRegionSelector(player.getWorld(), new CuboidRegionSelector()); selector = new CuboidRegionSelector(oldSelector);
session.dispatchCUISelection(player);
player.print("Cuboid: left click for point 1, right click for point 2"); player.print("Cuboid: left click for point 1, right click for point 2");
} else if (typeName.equalsIgnoreCase("extend")) {
selector = new ExtendingCuboidRegionSelector(oldSelector);
player.print("Cuboid: left click for a starting point, right click to extend");
} else if (typeName.equalsIgnoreCase("poly")) { } else if (typeName.equalsIgnoreCase("poly")) {
session.setRegionSelector(player.getWorld(), new Polygonal2DRegionSelector()); selector = new Polygonal2DRegionSelector();
session.dispatchCUISelection(player);
player.print("2D polygon selector: Left/right click to add a point."); player.print("2D polygon selector: Left/right click to add a point.");
} else { } else {
player.printError("Only 'cuboid' and 'poly' are accepted."); player.printError("Only 'cuboid', 'extend' and 'poly' are accepted.");
} return;
}
session.setRegionSelector(world, selector);
session.dispatchCUISelection(player);
} }
} }

View File

@ -39,29 +39,54 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
protected BlockVector pos2; protected BlockVector pos2;
protected CuboidRegion region = new CuboidRegion(new Vector(), new Vector()); protected CuboidRegion region = new CuboidRegion(new Vector(), new Vector());
public CuboidRegionSelector() {
}
public CuboidRegionSelector(RegionSelector oldSelector) {
if (oldSelector instanceof CuboidRegionSelector) {
final CuboidRegionSelector cuboidRegionSelector = (CuboidRegionSelector) oldSelector;
pos1 = cuboidRegionSelector.pos1;
pos2 = cuboidRegionSelector.pos2;
} else {
final Region oldRegion;
try {
oldRegion = oldSelector.getRegion();
} catch (IncompleteRegionException e) {
return;
}
pos1 = oldRegion.getMinimumPoint().toBlockVector();
pos2 = oldRegion.getMaximumPoint().toBlockVector();
}
region.setPos1(pos1);
region.setPos2(pos2);
}
public boolean selectPrimary(Vector pos) { public boolean selectPrimary(Vector pos) {
if (pos1 != null && pos1.equals(pos)) { if (pos.equals(pos1)) {
return false; return false;
} }
pos1 = pos.toBlockVector(); pos1 = pos.toBlockVector();
region.setPos1(pos1); region.setPos1(pos1);
return true; return true;
} }
public boolean selectSecondary(Vector pos) { public boolean selectSecondary(Vector pos) {
if (pos2 != null && pos2.equals(pos)) { if (pos.equals(pos2)) {
return false; return false;
} }
pos2 = pos.toBlockVector(); pos2 = pos.toBlockVector();
region.setPos2(pos2); region.setPos2(pos2);
return true; return true;
} }
public void explainPrimarySelection(LocalPlayer player, public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) {
LocalSession session, Vector pos) {
if (pos1 != null && pos2 != null) { if (pos1 != null && pos2 != null) {
player.print("First position set to " + pos1 player.print("First position set to " + pos1 + " (" + region.getArea() + ").");
+ " (" + region.getArea() + ").");
} else { } else {
player.print("First position set to " + pos1 + "."); player.print("First position set to " + pos1 + ".");
} }
@ -69,11 +94,9 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getArea())); session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos, getArea()));
} }
public void explainSecondarySelection(LocalPlayer player, public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) {
LocalSession session, Vector pos) {
if (pos1 != null && pos2 != null) { if (pos1 != null && pos2 != null) {
player.print("Second position set to " + pos2 player.print("Second position set to " + pos2 + " (" + region.getArea() + ").");
+ " (" + region.getArea() + ").");
} else { } else {
player.print("Second position set to " + pos2 + "."); player.print("Second position set to " + pos2 + ".");
} }
@ -85,6 +108,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
if (pos1 != null) { if (pos1 != null) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos1, getArea())); session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos1, getArea()));
} }
if (pos2 != null) { if (pos2 != null) {
session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos2, getArea())); session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos2, getArea()));
} }
@ -129,7 +153,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
} }
public List<String> getInformationLines() { public List<String> getInformationLines() {
List<String> lines = new ArrayList<String>(); final List<String> lines = new ArrayList<String>();
if (pos1 != null) { if (pos1 != null) {
lines.add("Position 1: " + pos1); lines.add("Position 1: " + pos1);
@ -150,16 +174,21 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion
if (pos1 != null) { if (pos1 != null) {
player.dispatchCUIEvent(new SelectionPointEvent(0, pos1, getArea())); player.dispatchCUIEvent(new SelectionPointEvent(0, pos1, getArea()));
} }
if (pos2 != null) { if (pos2 != null) {
player.dispatchCUIEvent(new SelectionPointEvent(1, pos2, getArea())); player.dispatchCUIEvent(new SelectionPointEvent(1, pos2, getArea()));
} }
} }
public int getArea() { public int getArea() {
if (pos1 != null && pos2 != null) { if (pos1 == null) {
return region.getArea();
}
return -1; return -1;
} }
if (pos2 == null) {
return -1;
}
return region.getArea();
}
} }

View File

@ -0,0 +1,106 @@
// $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.BlockVector;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
/**
* Alternative selector for cuboids.
*
* @author sk89q
*/
public class ExtendingCuboidRegionSelector extends CuboidRegionSelector {
public ExtendingCuboidRegionSelector() {
}
public ExtendingCuboidRegionSelector(RegionSelector oldSelector) {
super(oldSelector);
if (pos1 == null || pos2 == null) {
return;
}
pos1 = region.getMinimumPoint().toBlockVector();
pos2 = region.getMaximumPoint().toBlockVector();
region.setPos1(pos1);
region.setPos2(pos2);
}
@Override
public boolean selectPrimary(Vector pos) {
if (pos.equals(pos1) && pos.equals(pos2)) {
return false;
}
pos1 = pos2 = pos.toBlockVector();
region.setPos1(pos1);
region.setPos2(pos2);
return true;
}
@Override
public boolean selectSecondary(Vector pos) {
if (pos1 == null || pos2 == null) {
return selectPrimary(pos);
}
if (region.contains(pos)) {
return false;
}
double x1 = Math.min(pos.getX(), pos1.getX());
double y1 = Math.min(pos.getY(), pos1.getY());
double z1 = Math.min(pos.getZ(), pos1.getZ());
double x2 = Math.max(pos.getX(), pos2.getX());
double y2 = Math.max(pos.getY(), pos2.getY());
double z2 = Math.max(pos.getZ(), pos2.getZ());
final BlockVector o1 = pos1;
final BlockVector o2 = pos2;
pos1 = new BlockVector(x1, y1, z1);
pos2 = new BlockVector(x2, y2, z2);
region.setPos1(pos1);
region.setPos2(pos2);
assert(region.contains(o1));
assert(region.contains(o2));
assert(region.contains(pos));
return true;
}
@Override
public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) {
player.print("Started selection at " + pos + " (" + region.getArea() + ").");
explainRegionAdjust(player, session);
}
@Override
public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) {
player.print("Extended selection to encompass " + pos + " (" + region.getArea() + ").");
explainRegionAdjust(player, session);
}
}

View File

@ -19,7 +19,7 @@
package com.sk89q.worldedit.regions; package com.sk89q.worldedit.regions;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.BlockVector2D;
@ -42,22 +42,24 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
protected Polygonal2DRegion region = new Polygonal2DRegion(); protected Polygonal2DRegion region = new Polygonal2DRegion();
public boolean selectPrimary(Vector pos) { public boolean selectPrimary(Vector pos) {
if (pos1 != null && pos1.equals(pos)) { if (pos.equals(pos1)) {
return false; return false;
} }
pos1 = pos.toBlockVector(); pos1 = pos.toBlockVector();
region = new Polygonal2DRegion(); region = new Polygonal2DRegion();
region.addPoint(pos); region.addPoint(pos);
region.expandY(pos.getBlockY()); region.expandY(pos.getBlockY());
return true; return true;
} }
public boolean selectSecondary(Vector pos) { public boolean selectSecondary(Vector pos) {
if (region.size() > 0) { if (region.size() > 0) {
List<BlockVector2D> points = region.getPoints(); final List<BlockVector2D> points = region.getPoints();
BlockVector2D lastPoint = points.get(region.size() - 1);
if (lastPoint.getBlockX() == pos.getBlockX() final BlockVector2D lastPoint = points.get(region.size() - 1);
&& lastPoint.getBlockZ() == pos.getBlockZ()) { if (lastPoint.getBlockX() == pos.getBlockX() && lastPoint.getBlockZ() == pos.getBlockZ()) {
return false; return false;
} }
@ -68,20 +70,21 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
region.addPoint(pos); region.addPoint(pos);
region.expandY(pos.getBlockY()); region.expandY(pos.getBlockY());
return true; return true;
} }
public void explainPrimarySelection(LocalPlayer player, public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) {
LocalSession session, Vector pos) {
player.print("Starting a new polygon at " + pos + "."); player.print("Starting a new polygon at " + pos + ".");
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeId())); session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeId()));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea())); session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY));
} }
public void explainSecondarySelection(LocalPlayer player, public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) {
LocalSession session, Vector pos) {
player.print("Added point #" + region.size() + " at " + pos + "."); player.print("Added point #" + region.size() + " at " + pos + ".");
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getArea())); session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY));
} }
@ -94,6 +97,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
if (pos1 == null) { if (pos1 == null) {
throw new IncompleteRegionException(); throw new IncompleteRegionException();
} }
return pos1; return pos1;
} }
@ -115,8 +119,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
public void learnChanges() { public void learnChanges() {
BlockVector2D pt = region.getPoints().get(0); BlockVector2D pt = region.getPoints().get(0);
pos1 = new BlockVector(pt.getBlockX(), pos1 = new BlockVector(pt.getBlockX(), region.getMinimumPoint().getBlockY(), pt.getBlockZ());
region.getMinimumPoint().getBlockY(), pt.getBlockZ());
} }
public void clear() { public void clear() {
@ -129,9 +132,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
} }
public List<String> getInformationLines() { public List<String> getInformationLines() {
List<String> lines = new ArrayList<String>(); return Collections.singletonList("# points: " + region.size());
lines.add("# points: " + region.size());
return lines;
} }
public String getTypeId() { public String getTypeId() {
@ -147,11 +148,11 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR
} }
public void describeCUI(LocalPlayer player) { public void describeCUI(LocalPlayer player) {
List<BlockVector2D> points = region.getPoints(); final List<BlockVector2D> points = region.getPoints();
for (int id = 0; id < points.size(); id++) { for (int id = 0; id < points.size(); id++) {
player.dispatchCUIEvent(new SelectionPoint2DEvent(id, points.get(id), getArea())); player.dispatchCUIEvent(new SelectionPoint2DEvent(id, points.get(id), getArea()));
} }
player.dispatchCUIEvent(new SelectionMinMaxEvent(region.minY, region.maxY)); player.dispatchCUIEvent(new SelectionMinMaxEvent(region.minY, region.maxY));
} }
} }