From f5c6678da65a06a7ff575a60c7862945103d56ea Mon Sep 17 00:00:00 2001 From: TomyLobo Date: Mon, 12 Dec 2011 05:12:24 +0100 Subject: [PATCH] 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. --- .../worldedit/commands/SelectionCommands.java | 27 +++-- .../regions/CuboidRegionSelector.java | 57 +++++++--- .../ExtendingCuboidRegionSelector.java | 106 ++++++++++++++++++ .../regions/Polygonal2DRegionSelector.java | 35 +++--- 4 files changed, 186 insertions(+), 39 deletions(-) create mode 100644 src/main/java/com/sk89q/worldedit/regions/ExtendingCuboidRegionSelector.java diff --git a/src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java b/src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java index bb5ee85e0..caaa328c5 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/SelectionCommands.java @@ -28,9 +28,11 @@ import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.worldedit.*; import com.sk89q.worldedit.data.ChunkStore; import com.sk89q.worldedit.regions.CuboidRegionSelector; +import com.sk89q.worldedit.regions.ExtendingCuboidRegionSelector; import com.sk89q.worldedit.regions.Polygonal2DRegionSelector; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionOperationException; +import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.blocks.*; /** @@ -597,7 +599,7 @@ public class SelectionCommands { @Command( aliases = { "/sel", ";" }, - usage = "[cuboid|poly]", + usage = "[cuboid|extend|poly]", desc = "Choose a region selector", min = 0, max = 1 @@ -606,21 +608,30 @@ public class SelectionCommands { LocalSession session, LocalPlayer player, EditSession editSession) throws WorldEditException { + final LocalWorld world = player.getWorld(); if (args.argsLength() == 0) { - session.getRegionSelector(player.getWorld()).clear(); + session.getRegionSelector(world).clear(); 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")) { - session.setRegionSelector(player.getWorld(), new CuboidRegionSelector()); - session.dispatchCUISelection(player); + selector = new CuboidRegionSelector(oldSelector); 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")) { - session.setRegionSelector(player.getWorld(), new Polygonal2DRegionSelector()); - session.dispatchCUISelection(player); + selector = new Polygonal2DRegionSelector(); player.print("2D polygon selector: Left/right click to add a point."); } 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); } } diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java index 171d13d3c..4cfdb487c 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegionSelector.java @@ -39,29 +39,54 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion protected BlockVector pos2; 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) { - if (pos1 != null && pos1.equals(pos)) { + if (pos.equals(pos1)) { return false; } + pos1 = pos.toBlockVector(); region.setPos1(pos1); return true; } public boolean selectSecondary(Vector pos) { - if (pos2 != null && pos2.equals(pos)) { + if (pos.equals(pos2)) { return false; } + pos2 = pos.toBlockVector(); region.setPos2(pos2); return true; } - public void explainPrimarySelection(LocalPlayer player, - LocalSession session, Vector pos) { + public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) { if (pos1 != null && pos2 != null) { - player.print("First position set to " + pos1 - + " (" + region.getArea() + ")."); + player.print("First position set to " + pos1 + " (" + region.getArea() + ")."); } else { 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())); } - public void explainSecondarySelection(LocalPlayer player, - LocalSession session, Vector pos) { + public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) { if (pos1 != null && pos2 != null) { - player.print("Second position set to " + pos2 - + " (" + region.getArea() + ")."); + player.print("Second position set to " + pos2 + " (" + region.getArea() + ")."); } else { player.print("Second position set to " + pos2 + "."); } @@ -85,6 +108,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion if (pos1 != null) { session.dispatchCUIEvent(player, new SelectionPointEvent(0, pos1, getArea())); } + if (pos2 != null) { session.dispatchCUIEvent(player, new SelectionPointEvent(1, pos2, getArea())); } @@ -129,7 +153,7 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion } public List getInformationLines() { - List lines = new ArrayList(); + final List lines = new ArrayList(); if (pos1 != null) { lines.add("Position 1: " + pos1); @@ -150,16 +174,21 @@ public class CuboidRegionSelector implements RegionSelector, CUIPointBasedRegion if (pos1 != null) { player.dispatchCUIEvent(new SelectionPointEvent(0, pos1, getArea())); } + if (pos2 != null) { player.dispatchCUIEvent(new SelectionPointEvent(1, pos2, getArea())); } } public int getArea() { - if (pos1 != null && pos2 != null) { - return region.getArea(); + if (pos1 == null) { + return -1; } - return -1; + if (pos2 == null) { + return -1; + } + + return region.getArea(); } } diff --git a/src/main/java/com/sk89q/worldedit/regions/ExtendingCuboidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/ExtendingCuboidRegionSelector.java new file mode 100644 index 000000000..74dccd653 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/regions/ExtendingCuboidRegionSelector.java @@ -0,0 +1,106 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q + * + * 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 . +*/ + +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); + } +} diff --git a/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java index 8141587f4..452ae42be 100644 --- a/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegionSelector.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit.regions; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector2D; @@ -42,22 +42,24 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR protected Polygonal2DRegion region = new Polygonal2DRegion(); public boolean selectPrimary(Vector pos) { - if (pos1 != null && pos1.equals(pos)) { + if (pos.equals(pos1)) { 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 points = region.getPoints(); - BlockVector2D lastPoint = points.get(region.size() - 1); - if (lastPoint.getBlockX() == pos.getBlockX() - && lastPoint.getBlockZ() == pos.getBlockZ()) { + final List points = region.getPoints(); + + final BlockVector2D lastPoint = points.get(region.size() - 1); + if (lastPoint.getBlockX() == pos.getBlockX() && lastPoint.getBlockZ() == pos.getBlockZ()) { return false; } @@ -68,20 +70,21 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR region.addPoint(pos); region.expandY(pos.getBlockY()); + return true; } - public void explainPrimarySelection(LocalPlayer player, - LocalSession session, Vector pos) { + public void explainPrimarySelection(LocalPlayer player, LocalSession session, Vector pos) { player.print("Starting a new polygon at " + pos + "."); + session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeId())); session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea())); session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); } - public void explainSecondarySelection(LocalPlayer player, - LocalSession session, Vector pos) { + public void explainSecondarySelection(LocalPlayer player, LocalSession session, Vector pos) { player.print("Added point #" + region.size() + " at " + pos + "."); + session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getArea())); session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.minY, region.maxY)); } @@ -94,6 +97,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR if (pos1 == null) { throw new IncompleteRegionException(); } + return pos1; } @@ -115,8 +119,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR public void learnChanges() { BlockVector2D pt = region.getPoints().get(0); - pos1 = new BlockVector(pt.getBlockX(), - region.getMinimumPoint().getBlockY(), pt.getBlockZ()); + pos1 = new BlockVector(pt.getBlockX(), region.getMinimumPoint().getBlockY(), pt.getBlockZ()); } public void clear() { @@ -129,9 +132,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR } public List getInformationLines() { - List lines = new ArrayList(); - lines.add("# points: " + region.size()); - return lines; + return Collections.singletonList("# points: " + region.size()); } public String getTypeId() { @@ -147,11 +148,11 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIPointBasedR } public void describeCUI(LocalPlayer player) { - List points = region.getPoints(); + final List points = region.getPoints(); for (int id = 0; id < points.size(); id++) { player.dispatchCUIEvent(new SelectionPoint2DEvent(id, points.get(id), getArea())); } + player.dispatchCUIEvent(new SelectionMinMaxEvent(region.minY, region.maxY)); } - }