Various minor

Fixes #742
Fixes #734
This commit is contained in:
Jesse Boyd 2017-09-22 12:44:49 +10:00
parent cf4683b876
commit 9a45b364f6
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
18 changed files with 1482 additions and 108 deletions

View File

@ -31,9 +31,10 @@ public class FactionsOneFeature extends BukkitMaskManager implements Listener {
final Player player = fp.parent;
final Chunk chunk = player.getLocation().getChunk();
final boolean perm = Perm.hasPermission(FawePlayer.wrap(player), "fawe.factions.wilderness");
final RegionWrapper locs = new RegionWrapper(chunk.getX(), chunk.getX(), chunk.getZ(), chunk.getZ());
final World world = player.getWorld();
RegionWrapper locs = new RegionWrapper(chunk.getX(), chunk.getX(), chunk.getZ(), chunk.getZ());
int count = 32;
if (this.isAdded(locs, world, player, perm, type)) {
@ -48,28 +49,28 @@ public class FactionsOneFeature extends BukkitMaskManager implements Listener {
chunkSelection = new RegionWrapper(locs.maxX + 1, locs.maxX + 1, locs.minZ, locs.maxZ);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.maxX += 1;
locs = new RegionWrapper(locs.minX, locs.maxX + 1, locs.minZ, locs.maxZ);
hasPerm = true;
}
chunkSelection = new RegionWrapper(locs.minX - 1, locs.minX - 1, locs.minZ, locs.maxZ);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.minX -= 1;
locs = new RegionWrapper(locs.minX - 1, locs.maxX, locs.minZ, locs.maxZ);
hasPerm = true;
}
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.maxZ + 1, locs.maxZ + 1);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.maxZ += 1;
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ, locs.maxZ + 1);
hasPerm = true;
}
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.minZ - 1);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.minZ -= 1;
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.maxZ);
hasPerm = true;
}
}

View File

@ -27,9 +27,10 @@ public class FactionsUUIDFeature extends BukkitMaskManager implements Listener {
final Player player = fp.parent;
final Chunk chunk = player.getLocation().getChunk();
final boolean perm = Perm.hasPermission(FawePlayer.wrap(player), "fawe.factions.wilderness");
final RegionWrapper locs = new RegionWrapper(chunk.getX(), chunk.getX(), chunk.getZ(), chunk.getZ());
final World world = player.getWorld();
RegionWrapper locs = new RegionWrapper(chunk.getX(), chunk.getX(), chunk.getZ(), chunk.getZ());
int count = 32;
if (this.isAdded(locs, world, player, perm, type)) {
@ -44,28 +45,28 @@ public class FactionsUUIDFeature extends BukkitMaskManager implements Listener {
chunkSelection = new RegionWrapper(locs.maxX + 1, locs.maxX + 1, locs.minZ, locs.maxZ);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.maxX += 1;
locs = new RegionWrapper(locs.minX, locs.maxX + 1, locs.minZ, locs.maxZ);
hasPerm = true;
}
chunkSelection = new RegionWrapper(locs.minX - 1, locs.minX - 1, locs.minZ, locs.maxZ);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.minX -= 1;
locs = new RegionWrapper(locs.minX - 1, locs.maxX, locs.minZ, locs.maxZ);
hasPerm = true;
}
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.maxZ + 1, locs.maxZ + 1);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.maxZ += 1;
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ, locs.maxZ + 1);
hasPerm = true;
}
chunkSelection = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.minZ - 1);
if (this.isAdded(chunkSelection, world, player, perm, type)) {
locs.minZ -= 1;
locs = new RegionWrapper(locs.minX, locs.maxX, locs.minZ - 1, locs.maxZ);
hasPerm = true;
}
}

View File

@ -121,8 +121,13 @@ import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.CylinderRegionSelector;
import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector;
import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
import com.sk89q.worldedit.regions.selector.SphereRegionSelector;
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.session.ClipboardHolder;
@ -560,7 +565,12 @@ public class Fawe {
BrushTool.inject(); // Add transform + support for double action brushes + visualizations
// Selectors
CuboidRegionSelector.inject(); // Translations
EllipsoidRegion.inject(); // Optimizations
ExtendingCuboidRegionSelector.inject();
EllipsoidRegionSelector.inject();
SphereRegionSelector.inject();
ConvexPolyhedralRegionSelector.inject();
CylinderRegionSelector.inject();
Polygonal2DRegionSelector.inject();
// Visitors
BreadthFirstSearch.inject(); // Translations + Optimizations
DownwardVisitor.inject(); // Optimizations

View File

@ -626,7 +626,7 @@ public class AnvilCommands {
FawePlayer fp = FawePlayer.wrap(player);
MCAClipboard clipboard = fp.getMeta(FawePlayer.METADATA_KEYS.ANVIL_CLIPBOARD);
if (clipboard == null) {
fp.sendMessage(BBC.getPrefix() + "You must first copy to your clipboard");
fp.sendMessage(BBC.getPrefix() + "You must first use `//anvil copy`");
return;
}
CuboidRegion cuboid = clipboard.getRegion();
@ -649,6 +649,6 @@ public class AnvilCommands {
pasteQueue.pasteRegion(copyQueue, copyRegion, offset, iAnvilHistory);
} catch (IOException e) { throw new RuntimeException(e); }
});
BBC.COMMAND_PASTE.send(player, player.getPosition());
BBC.COMMAND_PASTE.send(player, player.getPosition().toBlockVector());
}
}

View File

@ -840,6 +840,9 @@ public class CFICommands extends MethodCommands {
if (settings.mask != null) maskArgs.append(" " + settings.maskArg);
if (!settings.whiteOnly) maskArgs.append(" -w");
String height = Commands.getAlias(CFICommands.class, "height");
String waterHeight = Commands.getAlias(CFICommands.class, "waterheight");
String snow = Commands.getAlias(CFICommands.class, "snow");
Message msg = msg("&8>>&7 Current Settings &8<<&7").newline()
.text("&7Mask ").text("&7[&a" + mask + "&7]").cmdTip(alias() + " mask")
@ -849,11 +852,11 @@ public class CFICommands extends MethodCommands {
.newline()
.text("&8>>&7 Components &8<<&7")
.newline()
.text("&7[&aHeight&7]").suggestTip(alias() + " height 120").text(" - Terrain height for whole map")
.text("&7[&aHeight&7]").suggestTip(alias() + " " + alias("height") + " 120").text(" - Terrain height for whole map")
.newline()
.text("&7[&aWaterHeight&7]").suggestTip(alias() + " waterHeight 60").text(" - Sea level for whole map")
.text("&7[&aWaterHeight&7]").suggestTip(alias() + " " + alias("waterheight") + " 60").text(" - Sea level for whole map")
.newline()
.text("&7[&aSnow&7]").suggestTip(alias() + " snow" + maskArgs).text(" - Set snow in the masked areas")
.text("&7[&aSnow&7]").suggestTip(alias() + " " + alias("snow") + maskArgs).text(" - Set snow in the masked areas")
.newline();
if (pattern != null) {
@ -1006,6 +1009,10 @@ public class CFICommands extends MethodCommands {
return Commands.getAlias(CFICommand.class, "/cfi");
}
protected String alias(String command) {
return Commands.getAlias(CFICommands.class, command);
}
protected Message msg(String text) {
return new Message().newline()
.text(BBC.getPrefix())

View File

@ -203,8 +203,10 @@ public enum BBC {
SELECTOR_FUZZY_POS1("Region set and expanded from %s0 %s1.", "WorldEdit.Selector"),
SELECTOR_FUZZY_POS2("Added expansion of %s0 %s1.", "WorldEdit.Selector"),
SELECTOR_CUBOID_POS1("pos1 set to %s0 %s1.", "WorldEdit.Selector"),
SELECTOR_CUBOID_POS2("pos2 set to %s0 %s1.", "WorldEdit.Selector"),
SELECTOR_POS("pos%s0 set to %s1 (%s2).", "WorldEdit.Selector"),
SELECTOR_CENTER("Center set to %s0 (%s1).", "WorldEdit.Selector"),
SELECTOR_RADIUS("Radius set to %s0 (%s1).", "WorldEdit.Selector"),
SELECTOR_EXPANDED("Expanded region to %s0 (%s1)", "WorldEdit.Selector"),
SELECTOR_INVALID_COORDINATES("Invalid coordinates %s0", "WorldEdit.Selector"),
SELECTOR_ALREADY_SET("Position already set.", "WorldEdit.Selector"),
SELECTOR_SET_DEFAULT("Your default region selector is now %s0.", "WorldEdit.Selector"),

View File

@ -3,12 +3,12 @@ package com.boydti.fawe.object;
import com.sk89q.worldedit.Vector;
public class RegionWrapper {
public int minX;
public int maxX;
public int minY;
public int maxY;
public int minZ;
public int maxZ;
public final int minX;
public final int maxX;
public final int minY;
public final int maxY;
public final int minZ;
public final int maxZ;
public static RegionWrapper GLOBAL() {
return new RegionWrapper(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
@ -40,25 +40,8 @@ public class RegionWrapper {
return new RegionWrapper[]{this};
}
private int ly = Integer.MIN_VALUE;
private int lz = Integer.MIN_VALUE;
private boolean lr, lry, lrz;
public boolean isIn(int x, int y, int z) {
if (z != lz) {
lz = z;
lrz = z >= this.minZ && z <= this.maxZ;
if (y != ly) {
ly = y;
lry = y >= this.minY && y <= this.maxY;
}
lr = lrz && lry;
} else if (y != ly) {
ly = y;
lry = y >= this.minY && y <= this.maxY;
lr = lrz && lry;
}
return lr && (x >= this.minX && x <= this.maxX);
return (x >= this.minX) && (x <= this.maxX) && (z >= this.minZ) && (z <= this.maxZ) && (y >= this.minY) && (y <= this.maxY);
}
public boolean isInChunk(int cx, int cz) {

View File

@ -16,16 +16,15 @@ public class FaweMask {
throw new IllegalArgumentException("BlockVectors cannot be null!");
}
this.description = id;
this.position1 = new BlockVector(Math.min(pos1.getBlockX(), pos2.getBlockX()), 0, Math.min(pos1.getBlockZ(), pos2.getBlockZ()));
this.position2 = new BlockVector(Math.max(pos1.getBlockX(), pos2.getBlockX()), 256, Math.max(pos1.getBlockZ(), pos2.getBlockZ()));
this.position1 = new BlockVector(Math.min(pos1.getBlockX(), pos2.getBlockX()), pos1.getBlockY(), Math.min(pos1.getBlockZ(), pos2.getBlockZ()));
this.position2 = new BlockVector(Math.max(pos1.getBlockX(), pos2.getBlockX()), pos2.getBlockY(), Math.max(pos1.getBlockZ(), pos2.getBlockZ()));
}
public FaweMask(final BlockVector pos1, final BlockVector pos2) {
this(pos1, pos2, null);
if ((pos1 == null) || (pos2 == null)) {
throw new IllegalArgumentException("BlockVectors cannot be null!");
}
this.position1 = new BlockVector(Math.min(pos1.getBlockX(), pos2.getBlockX()), 0, Math.min(pos1.getBlockZ(), pos2.getBlockZ()));
this.position2 = new BlockVector(Math.max(pos1.getBlockX(), pos2.getBlockX()), 256, Math.max(pos1.getBlockZ(), pos2.getBlockZ()));
}
public HashSet<RegionWrapper> getRegions() {

View File

@ -268,13 +268,13 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
if (world instanceof MCAWorld) {
queue = ((MCAWorld) world).getQueue();
} else {
queue = SetQueue.IMP.getNewQueue(this, fastmode || limit.FAST_PLACEMENT, autoQueue);
queue = SetQueue.IMP.getNewQueue(this, fastmode || this.limit.FAST_PLACEMENT, autoQueue);
}
}
if (combineStages == null) {
combineStages = Settings.IMP.HISTORY.COMBINE_STAGES && !(queue instanceof MCAQueue);
}
if (!limit.FAST_PLACEMENT || !queue.supportsChangeTask()) {
if (!this.limit.FAST_PLACEMENT || !queue.supportsChangeTask()) {
combineStages = false;
}
if (this.blockBag != null) {
@ -313,24 +313,24 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
changeSet = new MemoryOptimizedHistory(world);
}
}
if (limit.SPEED_REDUCTION > 0) {
this.bypassHistory = new SlowExtent(this.bypassHistory, limit.SPEED_REDUCTION);
if (this.limit.SPEED_REDUCTION > 0) {
this.bypassHistory = new SlowExtent(this.bypassHistory, this.limit.SPEED_REDUCTION);
}
if (!(changeSet instanceof NullChangeSet)) {
if (player != null && Fawe.imp().getBlocksHubApi() != null) {
changeSet = LoggingChangeSet.wrap(player, changeSet);
}
if (this.blockBag != null) {
changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
}
if (combineStages) {
if (this.blockBag != null) {
changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1);
}
changeTask = changeSet;
changeSet.addChangeTask(queue);
} else {
this.extent = (history = new HistoryExtent(this, bypassHistory, changeSet, queue));
if (this.blockBag != null) {
this.extent = new BlockBagExtent(this.extent, blockBag, limit.INVENTORY_MODE == 1);
}
// if (this.blockBag != null) {
// this.extent = new BlockBagExtent(this.extent, blockBag, limit.INVENTORY_MODE == 1);
// }
}
}
}
@ -341,13 +341,14 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
} else {
this.extent = new ProcessedWEExtent(this.extent, this.limit);
if (allowedRegions.length == 1) {
this.extent = new SingleRegionExtent(this.extent, limit, allowedRegions[0]);
RegionWrapper region = allowedRegions[0];
this.extent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]);
} else {
this.extent = new MultiRegionExtent(this.extent, limit, allowedRegions);
this.extent = new MultiRegionExtent(this.extent, this.limit, allowedRegions);
}
}
} else {
this.extent = new HeightBoundExtent(this.extent, limit, 0, maxY);
this.extent = new HeightBoundExtent(this.extent, this.limit, 0, maxY);
}
this.extent = wrapExtent(this.extent, bus, event, Stage.BEFORE_HISTORY);
}
@ -889,36 +890,47 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
* @return a map of missing blocks
*/
public Map<Integer, Integer> popMissingBlocks() {
ChangeSet changeSet = getChangeSet();
if (changeSet instanceof BlockBagChangeSet) {
BlockBagChangeSet bbcs = (BlockBagChangeSet) changeSet;
BlockBag bag = bbcs.getBlockBag();
if (bag != null) {
bag.flushChanges();
Map<Integer, Integer> missingBlocks = ((BlockBagChangeSet) changeSet).popMissing();
if (!missingBlocks.isEmpty()) {
StringBuilder str = new StringBuilder();
int size = missingBlocks.size();
int i = 0;
BlockBag bag = getBlockBag();
if (bag != null) {
bag.flushChanges();
for (Map.Entry<Integer, Integer> entry : missingBlocks.entrySet()) {
int combined = entry.getKey();
int id = FaweCache.getId(combined);
int data = FaweCache.getData(combined);
int amount = entry.getValue();
BlockType type = BlockType.fromID(id);
str.append((type != null ? type.getName() : "" + id))
.append((data != 0 ? ":" + data : ""))
.append((amount != 1 ? "x" + amount : ""));
++i;
if (i != size) {
str.append(", ");
}
}
Map<Integer, Integer> missingBlocks;
ChangeSet changeSet = getChangeSet();
BBC.WORLDEDIT_SOME_FAILS_BLOCKBAG.send(player, str.toString());
if (changeSet instanceof BlockBagChangeSet) {
missingBlocks = ((BlockBagChangeSet) changeSet).popMissing();
} else {
ExtentTraverser<BlockBagExtent> find = new ExtentTraverser(extent).find(BlockBagExtent.class);
if (find != null && find.get() != null) {
missingBlocks = find.get().popMissing();
} else {
missingBlocks = null;
}
}
if (missingBlocks != null && !missingBlocks.isEmpty()) {
StringBuilder str = new StringBuilder();
int size = missingBlocks.size();
int i = 0;
for (Map.Entry<Integer, Integer> entry : missingBlocks.entrySet()) {
int combined = entry.getKey();
int id = FaweCache.getId(combined);
int data = FaweCache.getData(combined);
int amount = entry.getValue();
BlockType type = BlockType.fromID(id);
str.append((type != null ? type.getName() : "" + id))
.append((data != 0 ? ":" + data : ""))
.append((amount != 1 ? "x" + amount : ""));
++i;
if (i != size) {
str.append(", ");
}
}
BBC.WORLDEDIT_SOME_FAILS_BLOCKBAG.send(player, str.toString());
}
}
return new HashMap<>();
}
@ -1616,7 +1628,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
Vector pos2 = region.getMaximumPoint();
boolean contains = false;
for (RegionWrapper current : regionExtent.getRegions()) {
if (current.isIn((int) pos1.getX(), pos1.getBlockZ()) && current.isIn((int) pos2.getX(), pos2.getBlockZ())) {
if (current.isIn((int) pos1.getX(), pos1.getBlockY(), pos1.getBlockZ()) && current.isIn(pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ())) {
contains = true;
break;
}

View File

@ -1,5 +1,7 @@
package com.sk89q.worldedit.extent.inventory;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.exception.FaweException;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
@ -87,31 +89,23 @@ public class BlockBagExtent extends AbstractDelegateExtent {
@Override
public boolean setBlock(int x, int y, int z, BaseBlock block) throws WorldEditException {
CompoundTag nbt = block.getNbtData();
final int type = block.getType();
if (type != 0) {
int combinedTo = block.getCombined();
if (combinedTo != 0) {
try {
blockBag.fetchPlacedBlock(block.getId(), block.getData());
if (nbt != null) {
// Remove items (to avoid duplication)
if (nbt.containsKey("items")) {
block.setNbtData(null);
}
}
blockBag.fetchPlacedBlock(FaweCache.getId(combinedTo), FaweCache.getData(combinedTo));
} catch (UnplaceableBlockException e) {
return false;
throw new FaweException.FaweBlockBagException();
} catch (BlockBagException e) {
missingBlocks[type]++;
return false;
} catch (Throwable e) {
throw e;
missingBlocks[combinedTo]++;
throw new FaweException.FaweBlockBagException();
}
}
if (mine) {
BaseBlock lazyBlock = getExtent().getLazyBlock(x, y, z);
int existing = lazyBlock.getType();
if (existing != 0) {
int combinedFrom = lazyBlock.getCombined();
if (combinedFrom != 0) {
try {
blockBag.storeDroppedBlock(existing, lazyBlock.getData());
blockBag.storeDroppedBlock(FaweCache.getId(combinedFrom), FaweCache.getData(combinedFrom));
} catch (BlockBagException ignored) {
}
}

View File

@ -92,6 +92,7 @@ public class EllipsoidRegion extends AbstractRegion {
@Override
public int getArea() {
if (radius == null) return 0;
return (int) Math.floor((4.0 / 3.0) * Math.PI * radius.getX() * radius.getY() * radius.getZ());
}
@ -173,6 +174,7 @@ public class EllipsoidRegion extends AbstractRegion {
* @return radii
*/
public Vector getRadius() {
if (radius == null) return null;
return radius.subtract(0.5, 0.5, 0.5);
}

View File

@ -0,0 +1,278 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.selector;
import com.boydti.fawe.config.BBC;
import com.google.common.base.Optional;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIRegion;
import com.sk89q.worldedit.internal.cui.SelectionPointEvent;
import com.sk89q.worldedit.internal.cui.SelectionPolygonEvent;
import com.sk89q.worldedit.regions.ConvexPolyhedralRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.polyhedron.Triangle;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Creates a {@code ConvexPolyhedralRegion} from a user's selections.
*/
public class ConvexPolyhedralRegionSelector extends com.sk89q.worldedit.regions.ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion {
private final transient ConvexPolyhedralRegion region;
private transient BlockVector pos1;
/**
* Create a new selector with a {@code null} world.
*/
public ConvexPolyhedralRegionSelector() {
this((World) null);
}
/**
* Create a new selector.
*
* @param world the world, which may be {@code null}
*/
public ConvexPolyhedralRegionSelector(@Nullable World world) {
region = new ConvexPolyhedralRegion(world);
}
/**
* Create a new selector.
*
* @param oldSelector the old selector
*/
public ConvexPolyhedralRegionSelector(RegionSelector oldSelector) {
checkNotNull(oldSelector);
if (oldSelector instanceof ConvexPolyhedralRegionSelector) {
final ConvexPolyhedralRegionSelector convexPolyhedralRegionSelector = (ConvexPolyhedralRegionSelector) oldSelector;
pos1 = convexPolyhedralRegionSelector.pos1;
region = new ConvexPolyhedralRegion(convexPolyhedralRegionSelector.region);
} else {
final Region oldRegion;
try {
oldRegion = oldSelector.getRegion();
} catch (IncompleteRegionException e) {
region = new ConvexPolyhedralRegion(oldSelector.getIncompleteRegion().getWorld());
return;
}
final int minY = oldRegion.getMinimumPoint().getBlockY();
final int maxY = oldRegion.getMaximumPoint().getBlockY();
region = new ConvexPolyhedralRegion(oldRegion.getWorld());
for (final BlockVector2D pt : new ArrayList<BlockVector2D>(oldRegion.polygonize(Integer.MAX_VALUE))) {
region.addVertex(pt.toVector(minY));
region.addVertex(pt.toVector(maxY));
}
learnChanges();
}
}
@Nullable
@Override
public World getWorld() {
return region.getWorld();
}
@Override
public void setWorld(@Nullable World world) {
region.setWorld(world);
}
@Override
public boolean selectPrimary(Vector position, SelectorLimits limits) {
checkNotNull(position);
clear();
pos1 = position.toBlockVector();
return region.addVertex(position);
}
@Override
public boolean selectSecondary(Vector position, SelectorLimits limits) {
checkNotNull(position);
Optional<Integer> vertexLimit = limits.getPolyhedronVertexLimit();
if (vertexLimit.isPresent() && region.getVertices().size() > vertexLimit.get()) {
return false;
}
return region.addVertex(position);
}
@Override
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
return pos1;
}
@Override
public Region getRegion() throws IncompleteRegionException {
if (!region.isDefined()) {
throw new IncompleteRegionException();
}
return region;
}
@Override
public Region getIncompleteRegion() {
return region;
}
@Override
public boolean isDefined() {
return region.isDefined();
}
@Override
public int getArea() {
return region.getArea();
}
@Override
public void learnChanges() {
pos1 = region.getVertices().iterator().next().toBlockVector();
}
@Override
public void clear() {
region.clear();
}
@Override
public String getTypeName() {
return "Convex Polyhedron";
}
@Override
public List<String> getInformationLines() {
List<String> ret = new ArrayList<String>();
ret.add("Vertices: "+region.getVertices().size());
ret.add("Triangles: "+region.getTriangles().size());
return ret;
}
@Override
public void explainPrimarySelection(Actor player, LocalSession session, Vector pos) {
checkNotNull(player);
checkNotNull(session);
checkNotNull(pos);
session.describeCUI(player);
BBC.SELECTOR_POS.send(player, 1, pos, region.getArea());
}
@Override
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
checkNotNull(player);
checkNotNull(session);
checkNotNull(pos);
session.describeCUI(player);
BBC.SELECTOR_POS.send(player, region.getVertices().size(), pos, region.getArea());
}
@Override
public void explainRegionAdjust(Actor player, LocalSession session) {
checkNotNull(player);
checkNotNull(session);
session.describeCUI(player);
}
@Override
public int getProtocolVersion() {
return 3;
}
@Override
public String getTypeID() {
return "polyhedron";
}
@Override
public void describeCUI(LocalSession session, Actor player) {
checkNotNull(player);
checkNotNull(session);
Collection<Vector> vertices = region.getVertices();
Collection<Triangle> triangles = region.getTriangles();
Map<Vector, Integer> vertexIds = new HashMap<Vector, Integer>(vertices.size());
int lastVertexId = -1;
for (Vector vertex : vertices) {
vertexIds.put(vertex, ++lastVertexId);
session.dispatchCUIEvent(player, new SelectionPointEvent(lastVertexId, vertex, getArea()));
}
for (Triangle triangle : triangles) {
final int[] v = new int[3];
for (int i = 0; i < 3; ++i) {
v[i] = vertexIds.get(triangle.getVertex(i));
}
session.dispatchCUIEvent(player, new SelectionPolygonEvent(v));
}
}
@Override
public String getLegacyTypeID() {
return "cuboid";
}
@Override
public void describeLegacyCUI(LocalSession session, Actor player) {
checkNotNull(player);
checkNotNull(session);
if (isDefined()) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
}
}
public static Class<?> inject() {
return ConvexPolyhedralRegionSelector.class;
}
}

View File

@ -157,9 +157,9 @@ public class CuboidRegionSelector extends com.sk89q.worldedit.regions.CuboidRegi
Message msg;
if (position1 != null && position2 != null) {
msg = BBC.SELECTOR_CUBOID_POS1.m(position1, "(" + region.getArea() + ")");
msg = BBC.SELECTOR_POS.m(1, position1, region.getArea());
} else {
msg = BBC.SELECTOR_CUBOID_POS1.m(position1, "");
msg = BBC.SELECTOR_POS.m(1, position1, "");
}
String cmd = Commands.getAlias(SelectionCommands.class, "/pos1") + " " + pos.getBlockX() + "," + pos.getBlockY() + "," + pos.getBlockZ();
msg.suggestTip(cmd).send(player);
@ -175,9 +175,9 @@ public class CuboidRegionSelector extends com.sk89q.worldedit.regions.CuboidRegi
Message msg;
if (position1 != null && position2 != null) {
msg = BBC.SELECTOR_CUBOID_POS2.m(position2, "(" + region.getArea() + ")");
msg = BBC.SELECTOR_POS.m(2, position2, region.getArea());
} else {
msg = BBC.SELECTOR_CUBOID_POS2.m(position2, "");
msg = BBC.SELECTOR_POS.m(2, position2, "");
}
String cmd = Commands.getAlias(SelectionCommands.class, "/pos2") + " " + pos.getBlockX() + "," + pos.getBlockY() + "," + pos.getBlockZ();
msg.suggestTip(cmd).send(player);

View File

@ -0,0 +1,285 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.selector;
import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIRegion;
import com.sk89q.worldedit.internal.cui.SelectionCylinderEvent;
import com.sk89q.worldedit.internal.cui.SelectionMinMaxEvent;
import com.sk89q.worldedit.internal.cui.SelectionPointEvent;
import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import com.sk89q.worldedit.world.World;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Creates a {@code CylinderRegionSelector} from a user's selections.
*/
public class CylinderRegionSelector extends com.sk89q.worldedit.regions.CylinderRegionSelector implements RegionSelector, CUIRegion {
protected static transient final NumberFormat NUMBER_FORMAT;
protected transient CylinderRegion region;
static {
NUMBER_FORMAT = (NumberFormat) NumberFormat.getInstance().clone();
NUMBER_FORMAT.setMaximumFractionDigits(3);
}
/**
* Create a new region selector with a {@code null} world.
*/
public CylinderRegionSelector() {
this((World) null);
}
/**
* Create a new region selector.
*
* @param world the world, which may be {@code null}
*/
public CylinderRegionSelector(@Nullable World world) {
region = new CylinderRegion(world);
}
/**
* Create a new selector from the given one.
*
* @param oldSelector the old selector
*/
public CylinderRegionSelector(RegionSelector oldSelector) {
this(checkNotNull(oldSelector).getIncompleteRegion().getWorld());
if (oldSelector instanceof CylinderRegionSelector) {
final CylinderRegionSelector cylSelector = (CylinderRegionSelector) oldSelector;
region = new CylinderRegion(cylSelector.region);
} else {
final Region oldRegion;
try {
oldRegion = oldSelector.getRegion();
} catch (IncompleteRegionException e) {
return;
}
Vector pos1 = oldRegion.getMinimumPoint();
Vector pos2 = oldRegion.getMaximumPoint();
Vector center = pos1.add(pos2).divide(2).floor();
region.setCenter(center.toVector2D());
region.setRadius(pos2.toVector2D().subtract(center.toVector2D()));
region.setMaximumY(Math.max(pos1.getBlockY(), pos2.getBlockY()));
region.setMinimumY(Math.min(pos1.getBlockY(), pos2.getBlockY()));
}
}
/**
* Create a new selector.
*
* @param world the world
* @param center the center
* @param radius the radius
* @param minY the minimum Y
* @param maxY the maximum Y
*/
public CylinderRegionSelector(@Nullable World world, Vector2D center, Vector2D radius, int minY, int maxY) {
this(world);
region.setCenter(center);
region.setRadius(radius);
region.setMinimumY(Math.min(minY, maxY));
region.setMaximumY(Math.max(minY, maxY));
}
@Nullable
@Override
public World getWorld() {
return region.getWorld();
}
@Override
public void setWorld(@Nullable World world) {
region.setWorld(world);
}
@Override
public boolean selectPrimary(Vector position, SelectorLimits limits) {
if (!region.getCenter().equals(Vector.ZERO) && position.compareTo(region.getCenter()) == 0) {
return false;
}
region = new CylinderRegion(region.getWorld());
region.setCenter(position.toVector2D());
region.setY(position.getBlockY());
return true;
}
@Override
public boolean selectSecondary(Vector position, SelectorLimits limits) {
Vector center = region.getCenter();
if ((center.compareTo(Vector.ZERO)) == 0) {
return true;
}
final Vector2D diff = position.subtract(center).toVector2D();
final Vector2D minRadius = Vector2D.getMaximum(diff, diff.multiply(-1.0));
region.extendRadius(minRadius);
region.setY(position.getBlockY());
return true;
}
@Override
public void explainPrimarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_CENTER.send(player, pos, 0);
session.describeCUI(player);
}
@Override
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
Vector center = region.getCenter();
if (!center.equals(Vector.ZERO)) {
BBC.SELECTOR_RADIUS.send(player, NUMBER_FORMAT.format(region.getRadius().getX()) + "/" + NUMBER_FORMAT.format(region.getRadius().getZ()), region.getArea());
} else {
BBC.SELECTION_WAND.send(player);
return;
}
session.describeCUI(player);
}
@Override
public void explainRegionAdjust(Actor player, LocalSession session) {
session.describeCUI(player);
}
@Override
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
if (!isDefined()) {
throw new IncompleteRegionException();
}
return region.getCenter().toBlockVector();
}
@Override
public CylinderRegion getRegion() throws IncompleteRegionException {
if (!isDefined()) {
throw new IncompleteRegionException();
}
return region;
}
@Override
public CylinderRegion getIncompleteRegion() {
return region;
}
@Override
public boolean isDefined() {
return !region.getRadius().equals(Vector2D.ZERO);
}
@Override
public void learnChanges() {
}
@Override
public void clear() {
region = new CylinderRegion(region.getWorld());
}
@Override
public String getTypeName() {
return "Cylinder";
}
@Override
public List<String> getInformationLines() {
final List<String> lines = new ArrayList<String>();
if (!region.getCenter().equals(Vector.ZERO)) {
lines.add("Center: " + region.getCenter());
}
if (!region.getRadius().equals(Vector2D.ZERO)) {
lines.add("Radius: " + region.getRadius());
}
return lines;
}
@Override
public int getArea() {
return region.getArea();
}
@Override
public void describeCUI(LocalSession session, Actor player) {
session.dispatchCUIEvent(player, new SelectionCylinderEvent(region.getCenter(), region.getRadius()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
}
@Override
public void describeLegacyCUI(LocalSession session, Actor player) {
if (isDefined()) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
}
}
@Override
public int getProtocolVersion() {
return 1;
}
@Override
public String getTypeID() {
return "cylinder";
}
@Override
public String getLegacyTypeID() {
return "cuboid";
}
public static Class<?> inject() {
return CylinderRegionSelector.class;
}
}

View File

@ -0,0 +1,255 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.selector;
import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIRegion;
import com.sk89q.worldedit.internal.cui.SelectionEllipsoidPointEvent;
import com.sk89q.worldedit.internal.cui.SelectionPointEvent;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Creates a {@code EllipsoidRegionSelector} from a user's selections.
*/
public class EllipsoidRegionSelector extends com.sk89q.worldedit.regions.EllipsoidRegionSelector implements RegionSelector, CUIRegion {
protected transient EllipsoidRegion region;
protected transient boolean started = false;
/**
* Create a new selector with a {@code null} world.
*/
public EllipsoidRegionSelector() {
this((World) null);
}
/**
* Create a new selector.
*
* @param world the world, which may be {@code null}
*/
public EllipsoidRegionSelector(@Nullable World world) {
region = new EllipsoidRegion(world, new Vector(), new Vector());
}
/**
* Create a new selector from the given selector.
*
* @param oldSelector the old selector
*/
public EllipsoidRegionSelector(RegionSelector oldSelector) {
this(checkNotNull(oldSelector).getIncompleteRegion().getWorld());
if (oldSelector instanceof EllipsoidRegionSelector) {
final EllipsoidRegionSelector ellipsoidRegionSelector = (EllipsoidRegionSelector) oldSelector;
region = new EllipsoidRegion(ellipsoidRegionSelector.getIncompleteRegion());
} else {
Region oldRegion;
try {
oldRegion = oldSelector.getRegion();
} catch (IncompleteRegionException e) {
return;
}
BlockVector pos1 = oldRegion.getMinimumPoint().toBlockVector();
BlockVector pos2 = oldRegion.getMaximumPoint().toBlockVector();
Vector center = pos1.add(pos2).divide(2).floor();
region.setCenter(center);
region.setRadius(pos2.subtract(center));
}
}
/**
* Create a new selector.
*
* @param world the world
* @param center the center
* @param radius the radius
*/
public EllipsoidRegionSelector(@Nullable World world, Vector center, Vector radius) {
this(world);
region.setCenter(center);
region.setRadius(radius);
}
@Nullable
@Override
public World getWorld() {
return region.getWorld();
}
@Override
public void setWorld(@Nullable World world) {
region.setWorld(world);
}
@Override
public boolean selectPrimary(Vector position, SelectorLimits limits) {
if (position.equals(region.getCenter()) && region.getRadius().lengthSq() == 0) {
return false;
}
region.setCenter(position.toBlockVector());
region.setRadius(new Vector());
started = true;
return true;
}
@Override
public boolean selectSecondary(Vector position, SelectorLimits limits) {
if (!started) {
return false;
}
final Vector diff = position.subtract(region.getCenter());
final Vector minRadius = Vector.getMaximum(diff, diff.multiply(-1.0));
region.extendRadius(minRadius);
return true;
}
@Override
public void explainPrimarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_CENTER.send(player, region.getCenter(), region.getArea());
session.describeCUI(player);
}
@Override
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_RADIUS.send(player, region.getRadius(), region.getArea());
session.describeCUI(player);
}
@Override
public void explainRegionAdjust(Actor player, LocalSession session) {
session.describeCUI(player);
}
@Override
public boolean isDefined() {
return started && region.getRadius().lengthSq() > 0;
}
@Override
public EllipsoidRegion getRegion() throws IncompleteRegionException {
if (!isDefined()) {
throw new IncompleteRegionException();
}
return region;
}
@Override
public EllipsoidRegion getIncompleteRegion() {
return region;
}
@Override
public void learnChanges() {
}
@Override
public void clear() {
region.setCenter(new Vector());
region.setRadius(new Vector());
}
@Override
public String getTypeName() {
return "ellipsoid";
}
@Override
public List<String> getInformationLines() {
final List<String> lines = new ArrayList<String>();
final Vector center = region.getCenter();
if (center.lengthSq() > 0) {
lines.add("Center: " + center);
}
final Vector radius = region.getRadius();
if (radius.lengthSq() > 0) {
lines.add("X/Y/Z radius: " + radius);
}
return lines;
}
@Override
public int getArea() {
return region.getArea();
}
@Override
public void describeCUI(LocalSession session, Actor player) {
session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(0, region.getCenter()));
session.dispatchCUIEvent(player, new SelectionEllipsoidPointEvent(1, region.getRadius()));
}
@Override
public void describeLegacyCUI(LocalSession session, Actor player) {
session.dispatchCUIEvent(player, new SelectionPointEvent(0, region.getMinimumPoint(), getArea()));
session.dispatchCUIEvent(player, new SelectionPointEvent(1, region.getMaximumPoint(), getArea()));
}
@Override
public String getLegacyTypeID() {
return "cuboid";
}
@Override
public int getProtocolVersion() {
return 1;
}
@Override
public String getTypeID() {
return "ellipsoid";
}
@Override
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
return region.getCenter().toBlockVector();
}
public static Class<?> inject() {
return EllipsoidRegionSelector.class;
}
}

View File

@ -0,0 +1,148 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.selector;
import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
/**
* Creates a {@code CuboidRegion} from a user's selections by expanding
* the region on every right click.
*/
public class ExtendingCuboidRegionSelector extends CuboidRegionSelector {
/**
* Create a new selector with a {@code null} world.
*/
public ExtendingCuboidRegionSelector() {
super((World) null);
}
/**
* Create a new selector.
*
* @param world the world, which may be {@code null}
*/
public ExtendingCuboidRegionSelector(@Nullable World world) {
super(world);
}
/**
* Create a new selector from another one.
*
* @param oldSelector the other selector
*/
public ExtendingCuboidRegionSelector(RegionSelector oldSelector) {
super(oldSelector);
if (position1 == null || position2 == null) {
return;
}
position1 = region.getMinimumPoint().toBlockVector();
position2 = region.getMaximumPoint().toBlockVector();
region.setPos1(position1);
region.setPos2(position2);
}
/**
* Create a new selector.
*
* @param world the world
* @param position1 the first position
* @param position2 the second position
*/
public ExtendingCuboidRegionSelector(@Nullable World world, Vector position1, Vector position2) {
this(world);
position1 = Vector.getMinimum(position1, position2);
position2 = Vector.getMaximum(position1, position2);
region.setPos1(position1);
region.setPos2(position2);
}
@Override
public boolean selectPrimary(Vector position, SelectorLimits limits) {
if (position1 != null && position2 != null && position.compareTo(position1) == 0 && position.compareTo(position2) == 0) {
return false;
}
position1 = position2 = position.toBlockVector();
region.setPos1(position1);
region.setPos2(position2);
return true;
}
@Override
public boolean selectSecondary(Vector position, SelectorLimits limits) {
if (position1 == null || position2 == null) {
return selectPrimary(position, limits);
}
if (region.contains(position)) {
return false;
}
double x1 = Math.min(position.getX(), position1.getX());
double y1 = Math.min(position.getY(), position1.getY());
double z1 = Math.min(position.getZ(), position1.getZ());
double x2 = Math.max(position.getX(), position2.getX());
double y2 = Math.max(position.getY(), position2.getY());
double z2 = Math.max(position.getZ(), position2.getZ());
final BlockVector o1 = position1;
final BlockVector o2 = position2;
position1 = new BlockVector(x1, y1, z1);
position2 = new BlockVector(x2, y2, z2);
region.setPos1(position1);
region.setPos2(position2);
assert(region.contains(o1));
assert(region.contains(o2));
assert(region.contains(position));
return true;
}
@Override
public void explainPrimarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_POS.send(player, 1, pos, region.getArea());
explainRegionAdjust(player, session);
}
@Override
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_EXPANDED.send(player, 2, pos, region.getArea());
explainRegionAdjust(player, session);
}
public static Class<?> inject() {
return ExtendingCuboidRegionSelector.class;
}
}

View File

@ -0,0 +1,295 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.selector;
import com.boydti.fawe.config.BBC;
import com.google.common.base.Optional;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.cui.CUIRegion;
import com.sk89q.worldedit.internal.cui.SelectionMinMaxEvent;
import com.sk89q.worldedit.internal.cui.SelectionPoint2DEvent;
import com.sk89q.worldedit.internal.cui.SelectionShapeEvent;
import com.sk89q.worldedit.regions.Polygonal2DRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import com.sk89q.worldedit.world.World;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Creates a {@code Polygonal2DRegion} from a user's selections.
*/
public class Polygonal2DRegionSelector extends com.sk89q.worldedit.regions.Polygonal2DRegionSelector implements RegionSelector, CUIRegion {
private transient BlockVector pos1;
private transient Polygonal2DRegion region;
/**
* Create a new selector with a {@code null} world.
*/
public Polygonal2DRegionSelector() {
this((World) null);
}
/**
* Create a new selector with the given world.
*
* @param world the world
*/
public Polygonal2DRegionSelector(@Nullable World world) {
region = new Polygonal2DRegion(world);
}
/**
* Create a new selector from another one.
*
* @param oldSelector the old selector
*/
public Polygonal2DRegionSelector(RegionSelector oldSelector) {
this(checkNotNull(oldSelector).getIncompleteRegion().getWorld());
if (oldSelector instanceof Polygonal2DRegionSelector) {
final Polygonal2DRegionSelector polygonal2DRegionSelector = (Polygonal2DRegionSelector) oldSelector;
pos1 = polygonal2DRegionSelector.pos1;
region = new Polygonal2DRegion(polygonal2DRegionSelector.region);
} else {
final Region oldRegion;
try {
oldRegion = oldSelector.getRegion();
} catch (IncompleteRegionException e) {
return;
}
final int minY = oldRegion.getMinimumPoint().getBlockY();
final int maxY = oldRegion.getMaximumPoint().getBlockY();
List<BlockVector2D> points = oldRegion.polygonize(Integer.MAX_VALUE);
pos1 = points.get(0).toVector(minY).toBlockVector();
region = new Polygonal2DRegion(oldRegion.getWorld(), points, minY, maxY);
}
}
/**
* @deprecated cast {@code world} to {@link com.sk89q.worldedit.world.World}
*/
@Deprecated
public Polygonal2DRegionSelector(@Nullable LocalWorld world, List<BlockVector2D> points, int minY, int maxY) {
this((World) world, points, minY, maxY);
}
/**
* Create a new selector.
*
* @param world the world
* @param points a list of points
* @param minY the minimum Y
* @param maxY the maximum Y
*/
public Polygonal2DRegionSelector(@Nullable World world, List<BlockVector2D> points, int minY, int maxY) {
checkNotNull(points);
final BlockVector2D pos2D = points.get(0);
pos1 = new BlockVector(pos2D.getX(), minY, pos2D.getZ());
region = new Polygonal2DRegion(world, points, minY, maxY);
}
@Nullable
@Override
public World getWorld() {
return region.getWorld();
}
@Override
public void setWorld(@Nullable World world) {
region.setWorld(world);
}
@Override
public boolean selectPrimary(Vector position, SelectorLimits limits) {
if (position.equals(pos1)) {
return false;
}
pos1 = position.toBlockVector();
region = new Polygonal2DRegion(region.getWorld());
region.addPoint(position);
region.expandY(position.getBlockY());
return true;
}
@Override
public boolean selectSecondary(Vector position, SelectorLimits limits) {
if (region.size() > 0) {
final List<BlockVector2D> points = region.getPoints();
final BlockVector2D lastPoint = points.get(region.size() - 1);
if (lastPoint.getBlockX() == position.getBlockX() && lastPoint.getBlockZ() == position.getBlockZ()) {
return false;
}
Optional<Integer> vertexLimit = limits.getPolygonVertexLimit();
if (vertexLimit.isPresent() && points.size() > vertexLimit.get()) {
return false;
}
}
region.addPoint(position);
region.expandY(position.getBlockY());
return true;
}
@Override
public void explainPrimarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_POS.send(player, 1, pos, region.getArea());
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID()));
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(0, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
}
@Override
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_POS.send(player, region.size(), pos, region.getArea());
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(region.size() - 1, pos, getArea()));
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
}
@Override
public void explainRegionAdjust(Actor player, LocalSession session) {
session.dispatchCUIEvent(player, new SelectionShapeEvent(getTypeID()));
describeCUI(session, player);
}
@Override
public BlockVector getPrimaryPosition() throws IncompleteRegionException {
if (pos1 == null) {
throw new IncompleteRegionException();
}
return pos1;
}
@Override
public Polygonal2DRegion getRegion() throws IncompleteRegionException {
if (!isDefined()) {
throw new IncompleteRegionException();
}
return region;
}
@Override
public Polygonal2DRegion getIncompleteRegion() {
return region;
}
@Override
public boolean isDefined() {
return region.size() > 2;
}
@Override
public void learnChanges() {
BlockVector2D pt = region.getPoints().get(0);
pos1 = new BlockVector(pt.getBlockX(), region.getMinimumPoint().getBlockY(), pt.getBlockZ());
}
@Override
public void clear() {
pos1 = null;
region = new Polygonal2DRegion(region.getWorld());
}
@Override
public String getTypeName() {
return "2Dx1D polygon";
}
@Override
public List<String> getInformationLines() {
return Collections.singletonList("# points: " + region.size());
}
@Override
public int getArea() {
return region.getArea();
}
/**
* Get the number of points.
*
* @return the number of points
*/
@Override
public int getPointCount() {
return region.getPoints().size();
}
@Override
public void describeCUI(LocalSession session, Actor player) {
final List<BlockVector2D> points = region.getPoints();
for (int id = 0; id < points.size(); id++) {
session.dispatchCUIEvent(player, new SelectionPoint2DEvent(id, points.get(id), getArea()));
}
session.dispatchCUIEvent(player, new SelectionMinMaxEvent(region.getMinimumY(), region.getMaximumY()));
}
@Override
public void describeLegacyCUI(LocalSession session, Actor player) {
describeCUI(session, player);
}
@Override
public int getProtocolVersion() {
return 0;
}
@Override
public String getTypeID() {
return "polygon2d";
}
@Override
public String getLegacyTypeID() {
return "polygon2d";
}
public static Class<?> inject() {
return Polygonal2DRegionSelector.class;
}
}

View File

@ -0,0 +1,102 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.regions.selector;
import com.boydti.fawe.config.BBC;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
import com.sk89q.worldedit.world.World;
import javax.annotation.Nullable;
/**
* Creates a {@code SphereRegion} from a user's selections.
*/
public class SphereRegionSelector extends EllipsoidRegionSelector {
/**
* Create a new selector with a {@code null world}.
*/
public SphereRegionSelector() {
super();
}
/**
* Create a new selector.
*
* @param world the world, which may be {@code null}
*/
public SphereRegionSelector(@Nullable World world) {
super(world);
}
/**
* Create a new selector from another one
*
* @param oldSelector the old selector
*/
public SphereRegionSelector(RegionSelector oldSelector) {
super(oldSelector);
final Vector radius = region.getRadius();
final double radiusScalar = Math.max(Math.max(radius.getX(), radius.getY()), radius.getZ());
region.setRadius(new Vector(radiusScalar, radiusScalar, radiusScalar));
}
/**
* Create a new selector.
*
* @param world the world
* @param center the center position
* @param radius the radius
*/
public SphereRegionSelector(@Nullable World world, Vector center, int radius) {
super(world, center, new Vector(radius, radius, radius));
}
@Override
public boolean selectSecondary(Vector position, SelectorLimits limits) {
if (!started) {
return false;
}
final double radiusScalar = Math.ceil(position.distance(region.getCenter()));
region.setRadius(new Vector(radiusScalar, radiusScalar, radiusScalar));
return true;
}
@Override
public void explainSecondarySelection(Actor player, LocalSession session, Vector pos) {
BBC.SELECTOR_RADIUS.send(player, region.getRadius().getX(), region.getArea());
session.describeCUI(player);
}
@Override
public String getTypeName() {
return "sphere";
}
public static Class<?> inject() {
return SphereRegionSelector.class;
}
}