From 7c4a67d32b85c2bf86d97a0ced5703760ea53c03 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 15:46:46 -0700
Subject: [PATCH 001/106] FlatRegionApplicator -> FlatRegionVisitor.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 6 +++---
.../java/com/sk89q/worldedit/commands/RegionCommands.java | 6 +++---
.../{FlatRegionApplicator.java => FlatRegionVisitor.java} | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
rename src/main/java/com/sk89q/worldedit/operation/{FlatRegionApplicator.java => FlatRegionVisitor.java} (93%)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index f07c45ac8..d4a186dd2 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -29,12 +29,12 @@ import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
import com.sk89q.worldedit.generator.ForestGenerator;
import com.sk89q.worldedit.generator.GardenPatchGenerator;
+import com.sk89q.worldedit.operation.FlatRegionVisitor;
import com.sk89q.worldedit.operation.GroundScatterFunction;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.operation.FlatRegionApplicator;
import com.sk89q.worldedit.operation.OperationHelper;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.regions.CuboidRegion;
@@ -2591,7 +2591,7 @@ public class EditSession {
scatter.setRange(region);
// Generate those patches!
- FlatRegionApplicator operation = new FlatRegionApplicator(region, scatter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, scatter);
OperationHelper.completeLegacy(operation);
return operation.getAffected();
@@ -2654,7 +2654,7 @@ public class EditSession {
* @return number of trees created
* @throws MaxChangedBlocksException
* @deprecated Use {@link com.sk89q.worldedit.generator.ForestGenerator} with a
- * {@link com.sk89q.worldedit.operation.FlatRegionApplicator}
+ * {@link com.sk89q.worldedit.operation.FlatRegionVisitor}
*/
@Deprecated
public int makeForest(Iterable it, int upperY, int lowerY,
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index be7725879..1096b0176 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -31,9 +31,9 @@ import com.sk89q.worldedit.filtering.GaussianKernel;
import com.sk89q.worldedit.filtering.HeightMapFilter;
import com.sk89q.worldedit.generator.FloraGenerator;
import com.sk89q.worldedit.generator.ForestGenerator;
+import com.sk89q.worldedit.operation.FlatRegionVisitor;
import com.sk89q.worldedit.operation.GroundScatterFunction;
import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.operation.FlatRegionApplicator;
import com.sk89q.worldedit.operation.OperationHelper;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
@@ -552,7 +552,7 @@ public class RegionCommands {
scatter.setRange(region);
// Generate that forest
- FlatRegionApplicator operation = new FlatRegionApplicator(region, scatter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, scatter);
OperationHelper.complete(operation);
player.print(operation.getAffected() + " trees created.");
@@ -581,7 +581,7 @@ public class RegionCommands {
scatter.setRange(region);
// Generate that flora
- FlatRegionApplicator operation = new FlatRegionApplicator(region, scatter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, scatter);
OperationHelper.complete(operation);
player.print(operation.getAffected() + " flora created.");
diff --git a/src/main/java/com/sk89q/worldedit/operation/FlatRegionApplicator.java b/src/main/java/com/sk89q/worldedit/operation/FlatRegionVisitor.java
similarity index 93%
rename from src/main/java/com/sk89q/worldedit/operation/FlatRegionApplicator.java
rename to src/main/java/com/sk89q/worldedit/operation/FlatRegionVisitor.java
index 0f7d42933..9fe3e86a2 100644
--- a/src/main/java/com/sk89q/worldedit/operation/FlatRegionApplicator.java
+++ b/src/main/java/com/sk89q/worldedit/operation/FlatRegionVisitor.java
@@ -28,13 +28,13 @@ import com.sk89q.worldedit.regions.Region;
/**
* Utility class to apply region functions to {@link com.sk89q.worldedit.regions.Region}.
*/
-public class FlatRegionApplicator implements Operation {
+public class FlatRegionVisitor implements Operation {
private final FlatRegion flatRegion;
private final FlatRegionFunction function;
private int affected = 0;
- public FlatRegionApplicator(Region region, FlatRegionFunction function) {
+ public FlatRegionVisitor(Region region, FlatRegionFunction function) {
this.function = function;
if (region instanceof FlatRegion) {
From 52bbbb179702fdff31135299da717cf06ca73117 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:06:24 -0700
Subject: [PATCH 002/106] Added CombinedMask(Mask ...mask) constructor.
---
.../com/sk89q/worldedit/masks/CombinedMask.java | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java b/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java
index fb12c8246..79eca640b 100644
--- a/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java
@@ -19,13 +19,14 @@
package com.sk89q.worldedit.masks;
-import java.util.ArrayList;
-import java.util.List;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
+import java.util.ArrayList;
+import java.util.List;
+
public class CombinedMask extends AbstractMask {
private final List masks = new ArrayList();
@@ -33,7 +34,13 @@ public class CombinedMask extends AbstractMask {
}
public CombinedMask(Mask mask) {
- masks.add(mask);
+ add(mask);
+ }
+
+ public CombinedMask(Mask ...mask) {
+ for (Mask m : mask) {
+ add(m);
+ }
}
public CombinedMask(List masks) {
From 0cafe4abb867cd98ebd61566127c09d13bb351df Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:07:47 -0700
Subject: [PATCH 003/106] Added BoundedYMask that requires that Y is in a
range.
---
.../sk89q/worldedit/masks/BoundedYMask.java | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java
diff --git a/src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java b/src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java
new file mode 100644
index 000000000..21980312d
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java
@@ -0,0 +1,47 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+
+/**
+ * Fails all tests against locations outside a range of Y values.
+ */
+public class BoundedYMask extends AbstractMask {
+
+ private final int minY;
+ private final int maxY;
+
+ public BoundedYMask(int minY, int maxY) {
+ if (minY > maxY) {
+ throw new IllegalArgumentException("minY must be less than or equal to maxY");
+ }
+ this.minY = minY;
+ this.maxY = maxY;
+ }
+
+ @Override
+ public boolean matches(EditSession editSession, Vector pos) {
+ int y = pos.getBlockY();
+ return y >= minY && y <= maxY;
+ }
+
+}
From c7fcbb299d0ba901783f3ffce988fa7709d9c6f5 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:08:22 -0700
Subject: [PATCH 004/106] Added FuzzyBlockMask, which uses
BaseBlock.containsFuzzy.
---
.../sk89q/worldedit/masks/FuzzyBlockMask.java | 50 +++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
diff --git a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
new file mode 100644
index 000000000..5386b7520
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
@@ -0,0 +1,50 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+import java.util.Set;
+
+/**
+ * Uses {@link BaseBlock#containsFuzzy(java.util.Collection, BaseBlock)} to
+ * match blocks.
+ */
+public class FuzzyBlockMask extends AbstractMask {
+
+ private final Set filter;
+
+ /**
+ * Create a new fuzzy block mask.
+ *
+ * @param filter a list of block types to match
+ */
+ public FuzzyBlockMask(Set filter) {
+ this.filter = filter;
+ }
+
+ @Override
+ public boolean matches(EditSession editSession, Vector pos) {
+ BaseBlock compare = new BaseBlock(editSession.getBlockType(pos), editSession.getBlockData(pos));
+ return BaseBlock.containsFuzzy(filter, compare);
+ }
+}
From 79643790ccfa46e4cd48ea0cc8527be27e01601c Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:09:24 -0700
Subject: [PATCH 005/106] Added BlockCount, which counts the number of blocks
matching a mask.
---
.../sk89q/worldedit/operation/BlockCount.java | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/operation/BlockCount.java
diff --git a/src/main/java/com/sk89q/worldedit/operation/BlockCount.java b/src/main/java/com/sk89q/worldedit/operation/BlockCount.java
new file mode 100644
index 000000000..3ac2533e6
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/BlockCount.java
@@ -0,0 +1,64 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.masks.Mask;
+
+/**
+ * Counts the number of blocks that match a given mask.
+ */
+ public class BlockCount implements RegionFunction {
+
+ private final EditSession editSession;
+ private Mask mask;
+ private int count;
+
+ /**
+ * Create a new block counter.
+ *
+ * @param editSession the edit session
+ * @param mask the mask
+ */
+ public BlockCount(EditSession editSession, Mask mask) {
+ this.editSession = editSession;
+ this.mask = mask;
+ }
+
+ /**
+ * Returns the number of blocks that have been counted.
+ *
+ * @return the number of blocks
+ */
+ public int getCount() {
+ return count;
+ }
+
+ @Override
+ public boolean apply(Vector position) throws WorldEditException {
+ if (mask.matches(editSession, position)) {
+ count++;
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
From a7300cf9ef2bc1be46bd1ee9821e0b16c6996163 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:09:34 -0700
Subject: [PATCH 006/106] Aded BlockReplace, which replaces blocks with a
pattern.
---
.../worldedit/operation/BlockReplace.java | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/operation/BlockReplace.java
diff --git a/src/main/java/com/sk89q/worldedit/operation/BlockReplace.java b/src/main/java/com/sk89q/worldedit/operation/BlockReplace.java
new file mode 100644
index 000000000..8153584ff
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/BlockReplace.java
@@ -0,0 +1,52 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.patterns.Pattern;
+
+/**
+ * Replaces blocks with the given pattern.
+ */
+public class BlockReplace implements RegionFunction {
+
+ private final EditSession editSession;
+ private Pattern pattern;
+
+ /**
+ * Create a new instance.
+ *
+ * @param editSession the edit session
+ * @param pattern a pattern
+ */
+ public BlockReplace(EditSession editSession, Pattern pattern) {
+ this.editSession = editSession;
+ this.pattern = pattern;
+ }
+
+ @Override
+ public boolean apply(Vector position) throws WorldEditException {
+ return editSession.setBlock(position, pattern.next(position));
+ }
+
+}
\ No newline at end of file
From 45c2868d4cb8f36a610b8deb37c5519d267827cb Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:09:55 -0700
Subject: [PATCH 007/106] Added various visitors (BFS, Downward, Recursive,
Region).
---
.../operation/BreadthFirstSearch.java | 172 ++++++++++++++++++
.../worldedit/operation/DownwardVisitor.java | 66 +++++++
.../worldedit/operation/RecursiveVisitor.java | 49 +++++
.../worldedit/operation/RegionVisitor.java | 65 +++++++
4 files changed, 352 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java
create mode 100644 src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java
create mode 100644 src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java
create mode 100644 src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java
diff --git a/src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java b/src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java
new file mode 100644
index 000000000..47d9feaa5
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java
@@ -0,0 +1,172 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.BlockVector;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+
+import java.util.*;
+
+/**
+ * Performs a breadth-first search starting from points added with
+ * {@link #visit(com.sk89q.worldedit.Vector)}. The search continues
+ * to a certain adjacent point provided that the method
+ * {@link #isVisitable(com.sk89q.worldedit.Vector, com.sk89q.worldedit.Vector)}
+ * returns true for that point.
+ *
+ * As an abstract implementation, this class can be used to implement
+ * functionality that starts at certain points and extends outward from
+ * those points.
+ */
+public abstract class BreadthFirstSearch implements Operation {
+
+ private final RegionFunction function;
+ private final Queue queue = new ArrayDeque();
+ private final Set visited = new HashSet();
+ private final List directions = new ArrayList();
+ private int affected = 0;
+
+ /**
+ * Create a new instance.
+ *
+ * @param function the function to apply to visited blocks
+ */
+ public BreadthFirstSearch(RegionFunction function) {
+ this.function = function;
+ addAxes();
+ }
+
+ /**
+ * Get the list of directions will be visited.
+ *
+ * Directions are {@link com.sk89q.worldedit.Vector}s that determine
+ * what adjacent points area available. Vectors should not be
+ * unit vectors. An example of a valid direction is {@code new Vector(1, 0, 1)}.
+ *
+ * The list of directions can be cleared.
+ *
+ * @return the list of directions
+ */
+ protected List getDirections() {
+ return directions;
+ }
+
+ /**
+ * Add the directions along the axes as directions to visit.
+ */
+ protected void addAxes() {
+ directions.add(new Vector(0, -1, 0));
+ directions.add(new Vector(0, 1, 0));
+ directions.add(new Vector(-1, 0, 0));
+ directions.add(new Vector(1, 0, 0));
+ directions.add(new Vector(0, 0, -1));
+ directions.add(new Vector(0, 0, 1));
+ }
+
+ /**
+ * Add the diagonal directions as directions to visit.
+ */
+ protected void addDiagonal() {
+ directions.add(new Vector(1, 0, 1));
+ directions.add(new Vector(-1, 0, -1));
+ directions.add(new Vector(1, 0, -1));
+ directions.add(new Vector(-1, 0, 1));
+ }
+
+ /**
+ * Add the given location to the list of locations to visit, provided
+ * that it has not been visited. The position passed to this method
+ * will still be visited even if it fails
+ * {@link #isVisitable(com.sk89q.worldedit.Vector, com.sk89q.worldedit.Vector)}.
+ *
+ * This method should be used before the search begins, because if
+ * the position does fail the test, and the search has already
+ * visited it (because it is connected to another root point),
+ * the search will mark the position as "visited" and a call to this
+ * method will do nothing.
+ *
+ * @param position the position
+ */
+ public void visit(Vector position) {
+ BlockVector blockVector = position.toBlockVector();
+ if (!visited.contains(blockVector)) {
+ queue.add(blockVector);
+ visited.add(blockVector);
+ }
+ }
+
+ /**
+ * Try to visit the given 'to' location.
+ *
+ * @param from the origin block
+ * @param to the block under question
+ */
+ private void visit(Vector from, Vector to) {
+ BlockVector blockVector = to.toBlockVector();
+ if (!visited.contains(blockVector)) {
+ visited.add(blockVector);
+ if (isVisitable(from, to)) {
+ queue.add(blockVector);
+ }
+ }
+ }
+
+ /**
+ * Return whether the given 'to' block should be visited, starting from the
+ * 'from' block.
+ *
+ * @param from the origin block
+ * @param to the block under question
+ * @return true if the 'to' block should be visited
+ */
+ protected abstract boolean isVisitable(Vector from, Vector to);
+
+ /**
+ * Get the number of affected objects.
+ *
+ * @return the number of affected
+ */
+ public int getAffected() {
+ return affected;
+ }
+
+ @Override
+ public Operation resume() throws WorldEditException {
+ Vector position;
+
+ while ((position = queue.poll()) != null) {
+ if (function.apply(position)) {
+ affected++;
+ }
+
+ for (Vector dir : directions) {
+ visit(position, position.add(dir));
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void cancel() {
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java b/src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java
new file mode 100644
index 000000000..393ca35c7
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java
@@ -0,0 +1,66 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.masks.Mask;
+
+import java.util.List;
+
+/**
+ * Visits adjacent points on the same X-Z plane as long as the points
+ * pass the given mask, and then executes the provided region
+ * function on the entire column.
+ *
+ * This is used by //fill
.
+ */
+public class DownwardVisitor extends RecursiveVisitor {
+
+ private int baseY;
+
+ /**
+ * Create a new visitor.
+ *
+ * @param editSession the edit session
+ * @param mask the mask
+ * @param function the function
+ * @param baseY the base Y
+ */
+ public DownwardVisitor(EditSession editSession, Mask mask, RegionFunction function, int baseY) {
+ super(editSession, mask, function);
+
+ this.baseY = baseY;
+
+ List directions = getDirections();
+ directions.clear();
+ directions.add(new Vector(1, 0, 0));
+ directions.add(new Vector(-1, 0, 0));
+ directions.add(new Vector(0, 0, 1));
+ directions.add(new Vector(0, 0, -1));
+ directions.add(new Vector(0, -1, 0));
+ }
+
+ @Override
+ protected boolean isVisitable(Vector from, Vector to) {
+ int fromY = from.getBlockY();
+ return (fromY == baseY || to.subtract(from).getBlockY() < 0) && super.isVisitable(from, to);
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java b/src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java
new file mode 100644
index 000000000..7bc6eb82c
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java
@@ -0,0 +1,49 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.masks.Mask;
+
+/**
+ * An implementation of an {@link BreadthFirstSearch} that uses a mask to
+ * determine where a block should be visited.
+ */
+public class RecursiveVisitor extends BreadthFirstSearch {
+
+ private final EditSession editSession;
+ private final Mask mask;
+
+ public RecursiveVisitor(EditSession editSession, Mask mask, RegionFunction function) {
+ super(function);
+ this.editSession = editSession;
+ this.mask = mask;
+ }
+
+ @Override
+ protected boolean isVisitable(Vector from, Vector to) {
+ int y = to.getBlockY();
+ if (y < 0 || y > editSession.getWorld().getMaxY()) {
+ return false;
+ }
+ return mask.matches(editSession, to);
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java b/src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java
new file mode 100644
index 000000000..51772d57b
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java
@@ -0,0 +1,65 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.regions.Region;
+
+/**
+ * Utility class to apply region functions to {@link com.sk89q.worldedit.regions.Region}.
+ */
+public class RegionVisitor implements Operation {
+
+ private final Region region;
+ private final RegionFunction function;
+ private int affected = 0;
+
+ public RegionVisitor(Region region, RegionFunction function) {
+ this.region = region;
+ this.function = function;
+ }
+
+ /**
+ * Get the number of affected objects.
+ *
+ * @return the number of affected
+ */
+ public int getAffected() {
+ return affected;
+ }
+
+ @Override
+ public Operation resume() throws WorldEditException {
+ for (Vector pt : region) {
+ if (function.apply(pt)) {
+ affected++;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void cancel() {
+ }
+
+}
+
From 2562a2f577ff09fa72511a25fbb54679eb7de157 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:10:12 -0700
Subject: [PATCH 008/106] Added OperationHelper.completeBlindly().
---
.../worldedit/operation/OperationHelper.java | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/main/java/com/sk89q/worldedit/operation/OperationHelper.java b/src/main/java/com/sk89q/worldedit/operation/OperationHelper.java
index 76c372445..a3585646f 100644
--- a/src/main/java/com/sk89q/worldedit/operation/OperationHelper.java
+++ b/src/main/java/com/sk89q/worldedit/operation/OperationHelper.java
@@ -61,4 +61,21 @@ public final class OperationHelper {
}
}
+ /**
+ * Complete a given operation synchronously until it completes. Re-throw all
+ * {@link com.sk89q.worldedit.WorldEditException} exceptions as
+ * {@link java.lang.RuntimeException}s.
+ *
+ * @param op operation to execute
+ */
+ public static void completeBlindly(Operation op) {
+ while (op != null) {
+ try {
+ op = op.resume();
+ } catch (WorldEditException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
}
From dbb7b085f04a02a4dc1e176cf8510e654e784acb Mon Sep 17 00:00:00 2001
From: sk89q
Date: Wed, 26 Mar 2014 23:10:47 -0700
Subject: [PATCH 009/106] Changed //count, //fill, //fillr to use visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 278 +++---------------
.../worldedit/commands/UtilityCommands.java | 2 +-
2 files changed, 47 insertions(+), 233 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index d4a186dd2..89df5a0c5 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -29,15 +29,15 @@ import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
import com.sk89q.worldedit.generator.ForestGenerator;
import com.sk89q.worldedit.generator.GardenPatchGenerator;
-import com.sk89q.worldedit.operation.FlatRegionVisitor;
-import com.sk89q.worldedit.operation.GroundScatterFunction;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
-import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.operation.OperationHelper;
+import com.sk89q.worldedit.masks.*;
+import com.sk89q.worldedit.operation.*;
import com.sk89q.worldedit.patterns.Pattern;
+import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.CuboidRegion;
+import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.shape.ArbitraryBiomeShape;
@@ -538,47 +538,16 @@ public class EditSession {
/**
* Count the number of blocks of a list of types in a region.
*
- * @param region
- * @param searchBlocks
- * @return
+ * @param region the region
+ * @param searchBlocks the list of blocks to search
+ * @return the number of blocks that matched the pattern
*/
public int countBlocks(Region region, Set searchBlocks) {
- int count = 0;
-
- if (region instanceof CuboidRegion) {
- // Doing this for speed
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector pt = new Vector(x, y, z);
-
- BaseBlock compare = new BaseBlock(getBlockType(pt), getBlockData(pt));
- if (BaseBlock.containsFuzzy(searchBlocks, compare)) {
- ++count;
- }
- }
- }
- }
- } else {
- for (Vector pt : region) {
- BaseBlock compare = new BaseBlock(getBlockType(pt), getBlockData(pt));
- if (BaseBlock.containsFuzzy(searchBlocks, compare)) {
- ++count;
- }
- }
- }
-
- return count;
+ FuzzyBlockMask mask = new FuzzyBlockMask(searchBlocks);
+ BlockCount counter = new BlockCount(this, mask);
+ RegionVisitor visitor = new RegionVisitor(region, counter);
+ OperationHelper.completeBlindly(visitor); // We can't throw exceptions, nor do we expect any
+ return counter.getCount();
}
/**
@@ -803,211 +772,56 @@ public class EditSession {
/**
* Fills an area recursively in the X/Z directions.
*
- * @param origin
- * @param block
- * @param radius
- * @param depth
- * @param recursive
+ * @param origin the location to start from
+ * @param block the block to fill with
+ * @param radius the radius of the spherical area to fill
+ * @param depth the maximum depth, starting from the origin
+ * @param recursive whether a breadth-first search should be performed
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int fillXZ(Vector origin, BaseBlock block, double radius, int depth,
- boolean recursive) throws MaxChangedBlocksException {
-
- int affected = 0;
- int originX = origin.getBlockX();
- int originY = origin.getBlockY();
- int originZ = origin.getBlockZ();
-
- HashSet visited = new HashSet();
- Stack queue = new Stack();
-
- queue.push(new BlockVector(originX, originY, originZ));
-
- while (!queue.empty()) {
- BlockVector pt = queue.pop();
- int cx = pt.getBlockX();
- int cy = pt.getBlockY();
- int cz = pt.getBlockZ();
-
- if (cy < 0 || cy > originY || visited.contains(pt)) {
- continue;
- }
-
- visited.add(pt);
-
- if (recursive) {
- if (origin.distance(pt) > radius) {
- continue;
- }
-
- if (getBlock(pt).isAir()) {
- if (setBlock(pt, block)) {
- ++affected;
- }
- } else {
- continue;
- }
-
- queue.push(new BlockVector(cx, cy - 1, cz));
- queue.push(new BlockVector(cx, cy + 1, cz));
- } else {
- double dist = Math.sqrt(Math.pow(originX - cx, 2)
- + Math.pow(originZ - cz, 2));
- int minY = originY - depth + 1;
-
- if (dist > radius) {
- continue;
- }
-
- if (getBlock(pt).isAir()) {
- affected += fillY(cx, originY, cz, block, minY);
- } else {
- continue;
- }
- }
-
- queue.push(new BlockVector(cx + 1, cy, cz));
- queue.push(new BlockVector(cx - 1, cy, cz));
- queue.push(new BlockVector(cx, cy, cz + 1));
- queue.push(new BlockVector(cx, cy, cz - 1));
- }
-
- return affected;
- }
-
- /**
- * Recursively fills a block and below until it hits another block.
- *
- * @param x
- * @param cy
- * @param z
- * @param block
- * @param minY
- * @throws MaxChangedBlocksException
- * @return
- */
- private int fillY(int x, int cy, int z, BaseBlock block, int minY)
+ public int fillXZ(Vector origin, BaseBlock block, double radius, int depth, boolean recursive)
throws MaxChangedBlocksException {
- int affected = 0;
-
- for (int y = cy; y >= minY; --y) {
- Vector pt = new Vector(x, y, z);
-
- if (getBlock(pt).isAir()) {
- setBlock(pt, block);
- ++affected;
- } else {
- break;
- }
- }
-
- return affected;
+ return fillXZ(origin, new SingleBlockPattern(block), radius, depth, recursive);
}
/**
* Fills an area recursively in the X/Z directions.
*
* @param origin
- * @param pattern
- * @param radius
- * @param depth
- * @param recursive
+ * @param pattern the pattern to fill with
+ * @param radius the radius of the spherical area to fill
+ * @param depth the maximum depth, starting from the origin
+ * @param recursive whether a breadth-first search should be performed
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int fillXZ(Vector origin, Pattern pattern, double radius, int depth,
- boolean recursive) throws MaxChangedBlocksException {
-
- int affected = 0;
- int originX = origin.getBlockX();
- int originY = origin.getBlockY();
- int originZ = origin.getBlockZ();
-
- HashSet visited = new HashSet();
- Stack queue = new Stack();
-
- queue.push(new BlockVector(originX, originY, originZ));
-
- while (!queue.empty()) {
- BlockVector pt = queue.pop();
- int cx = pt.getBlockX();
- int cy = pt.getBlockY();
- int cz = pt.getBlockZ();
-
- if (cy < 0 || cy > originY || visited.contains(pt)) {
- continue;
- }
-
- visited.add(pt);
-
- if (recursive) {
- if (origin.distance(pt) > radius) {
- continue;
- }
-
- if (getBlock(pt).isAir()) {
- if (setBlock(pt, pattern.next(pt))) {
- ++affected;
- }
- } else {
- continue;
- }
-
- queue.push(new BlockVector(cx, cy - 1, cz));
- queue.push(new BlockVector(cx, cy + 1, cz));
- } else {
- double dist = Math.sqrt(Math.pow(originX - cx, 2)
- + Math.pow(originZ - cz, 2));
- int minY = originY - depth + 1;
-
- if (dist > radius) {
- continue;
- }
-
- if (getBlock(pt).isAir()) {
- affected += fillY(cx, originY, cz, pattern, minY);
- } else {
- continue;
- }
- }
-
- queue.push(new BlockVector(cx + 1, cy, cz));
- queue.push(new BlockVector(cx - 1, cy, cz));
- queue.push(new BlockVector(cx, cy, cz + 1));
- queue.push(new BlockVector(cx, cy, cz - 1));
- }
-
- return affected;
- }
-
- /**
- * Recursively fills a block and below until it hits another block.
- *
- * @param x
- * @param cy
- * @param z
- * @param pattern
- * @param minY
- * @throws MaxChangedBlocksException
- * @return
- */
- private int fillY(int x, int cy, int z, Pattern pattern, int minY)
+ public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive)
throws MaxChangedBlocksException {
- int affected = 0;
- for (int y = cy; y >= minY; --y) {
- Vector pt = new Vector(x, y, z);
+ CombinedMask mask = new CombinedMask(
+ new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))),
+ new BoundedYMask(origin.getBlockY() - depth + 1, origin.getBlockY()),
+ new InvertedMask(new ExistingBlockMask()));
- if (getBlock(pt).isAir()) {
- setBlock(pt, pattern.next(pt));
- ++affected;
- } else {
- break;
- }
+ // Want to replace blocks
+ BlockReplace replace = new BlockReplace(this, pattern);
+
+ // Pick how we're going to visit blocks
+ RecursiveVisitor visitor;
+ if (recursive) {
+ visitor = new RecursiveVisitor(this, mask, replace);
+ } else {
+ visitor = new DownwardVisitor(this, mask, replace, origin.getBlockY());
}
- return affected;
+ // Start at the origin
+ visitor.visit(origin);
+
+ // Execute
+ OperationHelper.completeLegacy(visitor);
+
+ return visitor.getAffected();
}
/**
diff --git a/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java
index 12b88fbf6..b194f74d7 100644
--- a/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/UtilityCommands.java
@@ -91,7 +91,7 @@ public class UtilityCommands {
Pattern pattern = we.getBlockPattern(player, args.getString(0));
double radius = Math.max(1, args.getDouble(1));
we.checkMaxRadius(radius);
- int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : 1;
+ int depth = args.argsLength() > 2 ? Math.max(1, args.getInteger(2)) : Integer.MAX_VALUE;
Vector pos = session.getPlacementPosition(player);
int affected = 0;
From 377182da5f9d2a1e73f3dc66b7ff2e44a90fac33 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 19:56:39 -0700
Subject: [PATCH 010/106] Added Guava... for now.
We have to check to some serious breakage across the board before we can
release.
---
pom.xml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/pom.xml b/pom.xml
index fdbd42b3b..7254a85ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -125,6 +125,14 @@
jar
true
+
+
+ com.google.guava
+ guava
+ 10.0.1
+ compile
+ jar
+
org.bukkit
From b21f944570241277b67d59c876982e8a37f7e796 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 19:57:24 -0700
Subject: [PATCH 011/106] Changed /remove[above|below], //set to use visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 180 +++++-------------
1 file changed, 46 insertions(+), 134 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 89df5a0c5..8d50d22fe 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -48,6 +48,9 @@ import com.sk89q.worldedit.util.TreeGenerator;
import java.util.*;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* This class can wrap all block editing operations into one "edit session" that
* stores the state of the blocks before modification. This allows for easy undo
@@ -825,73 +828,45 @@ public class EditSession {
}
/**
- * Remove blocks above.
+ * Remove a cuboid above the given position with a given apothem and a given height.
*
- * @param pos
- * @param size
- * @param height
+ * @param position base position
+ * @param apothem an apothem of the cuboid, where the minimum is 1
+ * @param height the height of the cuboid, where the minimum is 1
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
- public int removeAbove(Vector pos, int size, int height)
- throws MaxChangedBlocksException {
- int maxY = Math.min(world.getMaxY(), pos.getBlockY() + height - 1);
- --size;
- int affected = 0;
+ public int removeAbove(Vector position, int apothem, int height) throws MaxChangedBlocksException {
+ checkNotNull(position, "position must not be null");
+ checkArgument(apothem >= 1, "apothem >= 1");
+ checkArgument(height >= 1, "height >= 1");
- int oX = pos.getBlockX();
- int oY = pos.getBlockY();
- int oZ = pos.getBlockZ();
-
- for (int x = oX - size; x <= oX + size; ++x) {
- for (int z = oZ - size; z <= oZ + size; ++z) {
- for (int y = oY; y <= maxY; ++y) {
- Vector pt = new Vector(x, y, z);
-
- if (getBlockType(pt) != BlockID.AIR) {
- setBlock(pt, new BaseBlock(BlockID.AIR));
- ++affected;
- }
- }
- }
- }
-
- return affected;
+ Region region = new CuboidRegion(
+ position.add(-apothem + 1, 0, -apothem + 1),
+ position.add(apothem - 1, height - 1, apothem - 1));
+ Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
+ return setBlocks(region, pattern);
}
/**
- * Remove blocks below.
+ * Remove a cuboid below the given position with a given apothem and a given height.
*
- * @param pos
- * @param size
- * @param height
+ * @param position base position
+ * @param apothem an apothem of the cuboid, where the minimum is 1
+ * @param height the height of the cuboid, where the minimum is 1
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
- public int removeBelow(Vector pos, int size, int height)
- throws MaxChangedBlocksException {
- int minY = Math.max(0, pos.getBlockY() - height);
- --size;
- int affected = 0;
+ public int removeBelow(Vector position, int apothem, int height) throws MaxChangedBlocksException {
+ checkNotNull(position, "position must not be null");
+ checkArgument(apothem >= 1, "apothem >= 1");
+ checkArgument(height >= 1, "height >= 1");
- int oX = pos.getBlockX();
- int oY = pos.getBlockY();
- int oZ = pos.getBlockZ();
-
- for (int x = oX - size; x <= oX + size; ++x) {
- for (int z = oZ - size; z <= oZ + size; ++z) {
- for (int y = oY; y >= minY; --y) {
- Vector pt = new Vector(x, y, z);
-
- if (getBlockType(pt) != BlockID.AIR) {
- setBlock(pt, new BaseBlock(BlockID.AIR));
- ++affected;
- }
- }
- }
- }
-
- return affected;
+ Region region = new CuboidRegion(
+ position.add(-apothem + 1, 0, -apothem + 1),
+ position.add(apothem - 1, -height + 1, apothem - 1));
+ Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
+ return setBlocks(region, pattern);
}
/**
@@ -933,95 +908,32 @@ public class EditSession {
}
/**
- * Sets all the blocks inside a region to a certain block type.
+ * Sets all the blocks inside a region to a given block type.
*
- * @param region
- * @param block
+ * @param region the region
+ * @param block the block
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int setBlocks(Region region, BaseBlock block)
- throws MaxChangedBlocksException {
- int affected = 0;
-
- if (region instanceof CuboidRegion) {
- // Doing this for speed
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector pt = new Vector(x, y, z);
-
- if (setBlock(pt, block)) {
- ++affected;
- }
- }
- }
- }
- } else {
- for (Vector pt : region) {
- if (setBlock(pt, block)) {
- ++affected;
- }
- }
- }
-
- return affected;
+ public int setBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
+ return setBlocks(region, new SingleBlockPattern(block));
}
/**
- * Sets all the blocks inside a region to a certain block type.
+ * Sets all the blocks inside a region to a given pattern.
*
- * @param region
- * @param pattern
+ * @param region the region
+ * @param pattern the pattern that provides the replacement block
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int setBlocks(Region region, Pattern pattern)
- throws MaxChangedBlocksException {
- int affected = 0;
-
- if (region instanceof CuboidRegion) {
- // Doing this for speed
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector pt = new Vector(x, y, z);
-
- if (setBlock(pt, pattern.next(pt))) {
- ++affected;
- }
- }
- }
- }
- } else {
- for (Vector pt : region) {
- if (setBlock(pt, pattern.next(pt))) {
- ++affected;
- }
- }
- }
-
- return affected;
+ public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
+ checkNotNull(region, "region must not be null");
+ checkNotNull(pattern, "pattern must not be null");
+ BlockReplace replace = new BlockReplace(this, pattern);
+ RegionVisitor visitor = new RegionVisitor(region, replace);
+ OperationHelper.completeLegacy(visitor);
+ return visitor.getAffected();
}
/**
From 8c3912b5e73f77baa4e436e7bad78d410e80930c Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 20:47:01 -0700
Subject: [PATCH 012/106] Added FuzzyBlockMask(BaseBlock... block) constructor.
---
.../com/sk89q/worldedit/masks/FuzzyBlockMask.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
index 5386b7520..4b34aab89 100644
--- a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
@@ -23,6 +23,7 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -42,6 +43,19 @@ public class FuzzyBlockMask extends AbstractMask {
this.filter = filter;
}
+ /**
+ * Create a new fuzzy block mask.
+ *
+ * @param block a list of block types to match
+ */
+ public FuzzyBlockMask(BaseBlock... block) {
+ Set filter = new HashSet();
+ for (BaseBlock b : block) {
+ filter.add(b);
+ }
+ this.filter = filter;
+ }
+
@Override
public boolean matches(EditSession editSession, Vector pos) {
BaseBlock compare = new BaseBlock(editSession.getBlockType(pos), editSession.getBlockData(pos));
From 2311964b820d0adcf5ed5e25c54bf98393c1e178 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 20:47:25 -0700
Subject: [PATCH 013/106] Added RegionMaskFilter to filter a RegionFunction.
---
.../worldedit/operation/RegionMaskFilter.java | 57 +++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java
diff --git a/src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java b/src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java
new file mode 100644
index 000000000..6a8640401
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java
@@ -0,0 +1,57 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.masks.Mask;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Passes positions that match the given mask onto the provided function.
+ */
+public class RegionMaskFilter implements RegionFunction {
+
+ private final EditSession editSession;
+ private final Mask mask;
+ private final RegionFunction function;
+
+ public RegionMaskFilter(EditSession editSession, Mask mask, RegionFunction function) {
+ checkNotNull(function, "function must not be null");
+ checkNotNull(editSession, "editSession must not be null");
+ checkNotNull(mask, "mask must not be null");
+
+ this.editSession = editSession;
+ this.mask = mask;
+ this.function = function;
+ }
+
+ @Override
+ public boolean apply(Vector position) throws WorldEditException {
+ if (mask.matches(editSession, position)) {
+ return function.apply(position);
+ } else {
+ return false;
+ }
+ }
+
+}
From 5cfc05c616690079bff0a88b6f0bf772f4a9b37c Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 20:48:36 -0700
Subject: [PATCH 014/106] Converted /removenear, //replace to visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 260 +++++-------------
1 file changed, 63 insertions(+), 197 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 8d50d22fe..5f3e1f88e 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -791,16 +791,19 @@ public class EditSession {
/**
* Fills an area recursively in the X/Z directions.
*
- * @param origin
+ * @param origin the origin to start the fill from
* @param pattern the pattern to fill with
- * @param radius the radius of the spherical area to fill
- * @param depth the maximum depth, starting from the origin
+ * @param radius the radius of the spherical area to fill, with 0 as the smallest radius
+ * @param depth the maximum depth, starting from the origin, with 1 as the smallest depth
* @param recursive whether a breadth-first search should be performed
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive)
- throws MaxChangedBlocksException {
+ public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
+ checkNotNull(origin, "origin must not be null");
+ checkNotNull(pattern, "pattern must not be null");
+ checkArgument(radius >= 0, "radius >= 0");
+ checkArgument(depth >= 1, "depth >= 1");
CombinedMask mask = new CombinedMask(
new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))),
@@ -831,10 +834,10 @@ public class EditSession {
* Remove a cuboid above the given position with a given apothem and a given height.
*
* @param position base position
- * @param apothem an apothem of the cuboid, where the minimum is 1
+ * @param apothem an apothem of the cuboid (on the XZ plane), where the minimum is 1
* @param height the height of the cuboid, where the minimum is 1
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int removeAbove(Vector position, int apothem, int height) throws MaxChangedBlocksException {
checkNotNull(position, "position must not be null");
@@ -852,10 +855,10 @@ public class EditSession {
* Remove a cuboid below the given position with a given apothem and a given height.
*
* @param position base position
- * @param apothem an apothem of the cuboid, where the minimum is 1
+ * @param apothem an apothem of the cuboid (on the XZ plane), where the minimum is 1
* @param height the height of the cuboid, where the minimum is 1
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int removeBelow(Vector position, int apothem, int height) throws MaxChangedBlocksException {
checkNotNull(position, "position must not be null");
@@ -870,41 +873,23 @@ public class EditSession {
}
/**
- * Remove nearby blocks of a type.
+ * Remove blocks of a certain type nearby a given position.
*
- * @param pos
- * @param blockType
- * @param size
+ * @param position center position of cuboid
+ * @param blockType the block type to match
+ * @param apothem an apothem of the cuboid, where the minimum is 1
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int removeNear(Vector pos, int blockType, int size)
- throws MaxChangedBlocksException {
- int affected = 0;
- BaseBlock air = new BaseBlock(BlockID.AIR);
+ public int removeNear(Vector position, int blockType, int apothem) throws MaxChangedBlocksException {
+ checkNotNull(position, "position must not be null");
+ checkArgument(apothem >= 1, "apothem >= 1");
- int minX = pos.getBlockX() - size;
- int maxX = pos.getBlockX() + size;
- int minY = Math.max(0, pos.getBlockY() - size);
- int maxY = Math.min(world.getMaxY(), pos.getBlockY() + size);
- int minZ = pos.getBlockZ() - size;
- int maxZ = pos.getBlockZ() + size;
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector p = new Vector(x, y, z);
-
- if (getBlockType(p) == blockType) {
- if (setBlock(p, air)) {
- ++affected;
- }
- }
- }
- }
- }
-
- return affected;
+ Mask mask = new FuzzyBlockMask(new BaseBlock(blockType, -1));
+ Vector adjustment = new Vector(1, 1, 1).multiply(apothem - 1);
+ Region region = new CuboidRegion(position.add(adjustment.multiply(-1)), position.add(adjustment));
+ Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
+ return replaceBlocks(region, mask, pattern);
}
/**
@@ -930,6 +915,7 @@ public class EditSession {
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region, "region must not be null");
checkNotNull(pattern, "pattern must not be null");
+
BlockReplace replace = new BlockReplace(this, pattern);
RegionVisitor visitor = new RegionVisitor(region, replace);
OperationHelper.completeLegacy(visitor);
@@ -937,174 +923,54 @@ public class EditSession {
}
/**
- * Replaces all the blocks of a type inside a region to another block type.
+ * Replaces all the blocks matching a given filter, within a given region, to a block
+ * returned by a given pattern.
*
- * @param region
- * @param fromBlockTypes -1 for non-air
- * @param toBlock
+ * @param region the region to replace the blocks within
+ * @param filter a list of block types to match, or null to use {@link com.sk89q.worldedit.masks.ExistingBlockMask}
+ * @param replacement the replacement block
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int replaceBlocks(Region region, Set fromBlockTypes, BaseBlock toBlock) throws MaxChangedBlocksException {
- Set definiteBlockTypes = new HashSet();
- Set fuzzyBlockTypes = new HashSet();
-
- if (fromBlockTypes != null) {
- for (BaseBlock block : fromBlockTypes) {
- if (block.getData() == -1) {
- fuzzyBlockTypes.add(block.getType());
- } else {
- definiteBlockTypes.add(block);
- }
- }
- }
-
- int affected = 0;
-
- if (region instanceof CuboidRegion) {
- // Doing this for speed
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector pt = new Vector(x, y, z);
- BaseBlock curBlockType = getBlock(pt);
-
- if (fromBlockTypes == null) {
- //replace
- if (curBlockType.isAir()) {
- continue;
- }
- } else {
- //replace
- if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
- continue;
- }
- }
-
- if (setBlock(pt, toBlock)) {
- ++affected;
- }
- }
- }
- }
- } else {
- for (Vector pt : region) {
- BaseBlock curBlockType = getBlock(pt);
-
- if (fromBlockTypes == null) {
- //replace
- if (curBlockType.isAir()) {
- continue;
- }
- } else {
- //replace
- if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
- continue;
- }
- }
-
- if (setBlock(pt, toBlock)) {
- ++affected;
- }
- }
- }
-
- return affected;
+ public int replaceBlocks(Region region, Set filter, BaseBlock replacement) throws MaxChangedBlocksException {
+ return replaceBlocks(region, filter, new SingleBlockPattern(replacement));
}
/**
- * Replaces all the blocks of a type inside a region to another block type.
+ * Replaces all the blocks matching a given filter, within a given region, to a block
+ * returned by a given pattern.
*
- * @param region
- * @param fromBlockTypes -1 for non-air
- * @param pattern
+ * @param region the region to replace the blocks within
+ * @param filter a list of block types to match, or null to use {@link com.sk89q.worldedit.masks.ExistingBlockMask}
+ * @param pattern the pattern that provides the new blocks
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int replaceBlocks(Region region, Set fromBlockTypes, Pattern pattern) throws MaxChangedBlocksException {
- Set definiteBlockTypes = new HashSet();
- Set fuzzyBlockTypes = new HashSet();
- if (fromBlockTypes != null) {
- for (BaseBlock block : fromBlockTypes) {
- if (block.getData() == -1) {
- fuzzyBlockTypes.add(block.getType());
- } else {
- definiteBlockTypes.add(block);
- }
- }
- }
+ public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException {
+ Mask mask = filter == null ? new ExistingBlockMask() : new FuzzyBlockMask(filter);
+ return replaceBlocks(region, mask, pattern);
+ }
- int affected = 0;
+ /**
+ * Replaces all the blocks matching a given mask, within a given region, to a block
+ * returned by a given pattern.
+ *
+ * @param region the region to replace the blocks within
+ * @param mask the mask that blocks must match
+ * @param pattern the pattern that provides the new blocks
+ * @return number of blocks affected
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
+ */
+ public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
+ checkNotNull(region, "region must not be null");
+ checkNotNull(mask, "mask must not be null");
+ checkNotNull(pattern, "pattern must not be null");
- if (region instanceof CuboidRegion) {
- // Doing this for speed
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector pt = new Vector(x, y, z);
- BaseBlock curBlockType = getBlock(pt);
-
- if (fromBlockTypes == null) {
- //replace
- if (curBlockType.isAir()) {
- continue;
- }
- } else {
- //replace
- if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
- continue;
- }
- }
-
- if (setBlock(pt, pattern.next(pt))) {
- ++affected;
- }
- }
- }
- }
- } else {
- for (Vector pt : region) {
- BaseBlock curBlockType = getBlock(pt);
-
- if (fromBlockTypes == null) {
- //replace
- if (curBlockType.isAir()) {
- continue;
- }
- } else {
- //replace
- if (!definiteBlockTypes.contains(curBlockType) && !fuzzyBlockTypes.contains(curBlockType.getType())) {
- continue;
- }
- }
-
- if (setBlock(pt, pattern.next(pt))) {
- ++affected;
- }
- }
- }
-
- return affected;
+ BlockReplace replace = new BlockReplace(this, pattern);
+ RegionMaskFilter filter = new RegionMaskFilter(this, mask, replace);
+ RegionVisitor visitor = new RegionVisitor(region, filter);
+ OperationHelper.completeLegacy(visitor);
+ return visitor.getAffected();
}
public int center(Region region, Pattern pattern)
From d9ad0014f05e7338cfb57a4bab45d11aebff62ab Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 20:54:35 -0700
Subject: [PATCH 015/106] Made CuboidRegion(world, ...) constructor clamp to
world.
---
src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
index 99d3f8925..37c944da4 100644
--- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
+++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
@@ -64,6 +64,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
super(world);
this.pos1 = pos1;
this.pos2 = pos2;
+ recalculate();
}
/**
From 570b4ebd937cb434af8b4f5890064198bf70dca2 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 20:57:20 -0700
Subject: [PATCH 016/106] Made CuboidRegions in EditSession clamp Y to world.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 5f3e1f88e..10a089635 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -845,6 +845,7 @@ public class EditSession {
checkArgument(height >= 1, "height >= 1");
Region region = new CuboidRegion(
+ getWorld(), // Causes clamping of Y range
position.add(-apothem + 1, 0, -apothem + 1),
position.add(apothem - 1, height - 1, apothem - 1));
Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
@@ -866,6 +867,7 @@ public class EditSession {
checkArgument(height >= 1, "height >= 1");
Region region = new CuboidRegion(
+ getWorld(), // Causes clamping of Y range
position.add(-apothem + 1, 0, -apothem + 1),
position.add(apothem - 1, -height + 1, apothem - 1));
Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
@@ -887,7 +889,10 @@ public class EditSession {
Mask mask = new FuzzyBlockMask(new BaseBlock(blockType, -1));
Vector adjustment = new Vector(1, 1, 1).multiply(apothem - 1);
- Region region = new CuboidRegion(position.add(adjustment.multiply(-1)), position.add(adjustment));
+ Region region = new CuboidRegion(
+ getWorld(), // Causes clamping of Y range
+ position.add(adjustment.multiply(-1)),
+ position.add(adjustment));
Pattern pattern = new SingleBlockPattern(new BaseBlock(BlockID.AIR));
return replaceBlocks(region, mask, pattern);
}
@@ -2175,7 +2180,10 @@ public class EditSession {
generator.setPlant(GardenPatchGenerator.getPumpkinPattern());
// In a region of the given radius
- Region region = new CuboidRegion(position.add(-apothem, -5, -apothem), position.add(apothem, 10, apothem));
+ Region region = new CuboidRegion(
+ getWorld(), // Causes clamping of Y range
+ position.add(-apothem, -5, -apothem),
+ position.add(apothem, 10, apothem));
// And we want to scatter them
GroundScatterFunction scatter = new GroundScatterFunction(this, generator);
From e022804c276a0d3934d28644c213bf68a052e170 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 21:04:07 -0700
Subject: [PATCH 017/106] Changed //center to use visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 37 ++++++++++---------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 10a089635..0c57d8403 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -978,25 +978,26 @@ public class EditSession {
return visitor.getAffected();
}
- public int center(Region region, Pattern pattern)
- throws MaxChangedBlocksException {
+ /**
+ * Sets the blocks at the center of the given region to the given pattern.
+ * If the center sits between two blocks on a certain axis, then two blocks
+ * will be placed to mark the center.
+ *
+ * @param region the region to find the center of
+ * @param pattern the replacement pattern
+ * @return the number of blocks placed
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
+ */
+ public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
+ checkNotNull(region, "region must not be null");
+ checkNotNull(pattern, "pattern must not be null");
+
Vector center = region.getCenter();
- int x2 = center.getBlockX();
- int y2 = center.getBlockY();
- int z2 = center.getBlockZ();
-
- int affected = 0;
- for (int x = (int) center.getX(); x <= x2; x++) {
- for (int y = (int) center.getY(); y <= y2; y++) {
- for (int z = (int) center.getZ(); z <= z2; z++) {
- if (setBlock(new Vector(x, y, z), pattern)) {
- affected++;
- }
- }
- }
- }
-
- return affected;
+ Region centerRegion = new CuboidRegion(
+ getWorld(), // Causes clamping of Y range
+ new Vector((int) center.getX(), (int) center.getY(), (int) center.getZ()),
+ center.toBlockVector());
+ return setBlocks(centerRegion, pattern);
}
/**
From a6e979ec6c51387d3d7c9b0f7db0a5bda736f4e0 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 21:07:38 -0700
Subject: [PATCH 018/106] Moved visitors to com.sk89q.worldedit.visitor.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 6 +++++-
.../java/com/sk89q/worldedit/commands/RegionCommands.java | 2 +-
.../{operation => visitor}/BreadthFirstSearch.java | 4 +++-
.../worldedit/{operation => visitor}/DownwardVisitor.java | 3 ++-
.../worldedit/{operation => visitor}/FlatRegionVisitor.java | 4 +++-
.../worldedit/{operation => visitor}/RecursiveVisitor.java | 3 ++-
.../worldedit/{operation => visitor}/RegionVisitor.java | 4 +++-
7 files changed, 19 insertions(+), 7 deletions(-)
rename src/main/java/com/sk89q/worldedit/{operation => visitor}/BreadthFirstSearch.java (97%)
rename src/main/java/com/sk89q/worldedit/{operation => visitor}/DownwardVisitor.java (95%)
rename src/main/java/com/sk89q/worldedit/{operation => visitor}/FlatRegionVisitor.java (93%)
rename src/main/java/com/sk89q/worldedit/{operation => visitor}/RecursiveVisitor.java (94%)
rename src/main/java/com/sk89q/worldedit/{operation => visitor}/RegionVisitor.java (92%)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 0c57d8403..aa1c5b040 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -45,6 +45,10 @@ import com.sk89q.worldedit.shape.ArbitraryShape;
import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator;
+import com.sk89q.worldedit.visitor.DownwardVisitor;
+import com.sk89q.worldedit.visitor.FlatRegionVisitor;
+import com.sk89q.worldedit.visitor.RecursiveVisitor;
+import com.sk89q.worldedit.visitor.RegionVisitor;
import java.util.*;
@@ -2255,7 +2259,7 @@ public class EditSession {
* @return number of trees created
* @throws MaxChangedBlocksException
* @deprecated Use {@link com.sk89q.worldedit.generator.ForestGenerator} with a
- * {@link com.sk89q.worldedit.operation.FlatRegionVisitor}
+ * {@link com.sk89q.worldedit.visitor.FlatRegionVisitor}
*/
@Deprecated
public int makeForest(Iterable it, int upperY, int lowerY,
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index 1096b0176..b3d79cfb9 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -31,7 +31,7 @@ import com.sk89q.worldedit.filtering.GaussianKernel;
import com.sk89q.worldedit.filtering.HeightMapFilter;
import com.sk89q.worldedit.generator.FloraGenerator;
import com.sk89q.worldedit.generator.ForestGenerator;
-import com.sk89q.worldedit.operation.FlatRegionVisitor;
+import com.sk89q.worldedit.visitor.FlatRegionVisitor;
import com.sk89q.worldedit.operation.GroundScatterFunction;
import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.operation.OperationHelper;
diff --git a/src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java b/src/main/java/com/sk89q/worldedit/visitor/BreadthFirstSearch.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java
rename to src/main/java/com/sk89q/worldedit/visitor/BreadthFirstSearch.java
index 47d9feaa5..3b9979467 100644
--- a/src/main/java/com/sk89q/worldedit/operation/BreadthFirstSearch.java
+++ b/src/main/java/com/sk89q/worldedit/visitor/BreadthFirstSearch.java
@@ -17,11 +17,13 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.visitor;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.operation.Operation;
+import com.sk89q.worldedit.operation.RegionFunction;
import java.util.*;
diff --git a/src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java b/src/main/java/com/sk89q/worldedit/visitor/DownwardVisitor.java
similarity index 95%
rename from src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java
rename to src/main/java/com/sk89q/worldedit/visitor/DownwardVisitor.java
index 393ca35c7..78614ebe1 100644
--- a/src/main/java/com/sk89q/worldedit/operation/DownwardVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/visitor/DownwardVisitor.java
@@ -17,11 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.visitor;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.operation.RegionFunction;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/operation/FlatRegionVisitor.java b/src/main/java/com/sk89q/worldedit/visitor/FlatRegionVisitor.java
similarity index 93%
rename from src/main/java/com/sk89q/worldedit/operation/FlatRegionVisitor.java
rename to src/main/java/com/sk89q/worldedit/visitor/FlatRegionVisitor.java
index 9fe3e86a2..816219205 100644
--- a/src/main/java/com/sk89q/worldedit/operation/FlatRegionVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/visitor/FlatRegionVisitor.java
@@ -17,10 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.visitor;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.operation.FlatRegionFunction;
+import com.sk89q.worldedit.operation.Operation;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.Region;
diff --git a/src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java b/src/main/java/com/sk89q/worldedit/visitor/RecursiveVisitor.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java
rename to src/main/java/com/sk89q/worldedit/visitor/RecursiveVisitor.java
index 7bc6eb82c..aa9ef421a 100644
--- a/src/main/java/com/sk89q/worldedit/operation/RecursiveVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/visitor/RecursiveVisitor.java
@@ -17,11 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.visitor;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.operation.RegionFunction;
/**
* An implementation of an {@link BreadthFirstSearch} that uses a mask to
diff --git a/src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java b/src/main/java/com/sk89q/worldedit/visitor/RegionVisitor.java
similarity index 92%
rename from src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java
rename to src/main/java/com/sk89q/worldedit/visitor/RegionVisitor.java
index 51772d57b..e87bea61b 100644
--- a/src/main/java/com/sk89q/worldedit/operation/RegionVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/visitor/RegionVisitor.java
@@ -17,10 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.visitor;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.operation.Operation;
+import com.sk89q.worldedit.operation.RegionFunction;
import com.sk89q.worldedit.regions.Region;
/**
From 9cd164ae98428e0b07a1a6f3ac13a463ab2f01bf Mon Sep 17 00:00:00 2001
From: sk89q
Date: Thu, 27 Mar 2014 21:11:02 -0700
Subject: [PATCH 019/106] Removed mask support from BlockCount.
RegionMaskFilter handles it.
---
.../java/com/sk89q/worldedit/EditSession.java | 7 ++++---
.../sk89q/worldedit/operation/BlockCount.java | 21 ++-----------------
2 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index aa1c5b040..d041591ce 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -551,10 +551,11 @@ public class EditSession {
*/
public int countBlocks(Region region, Set searchBlocks) {
FuzzyBlockMask mask = new FuzzyBlockMask(searchBlocks);
- BlockCount counter = new BlockCount(this, mask);
- RegionVisitor visitor = new RegionVisitor(region, counter);
+ BlockCount count = new BlockCount();
+ RegionMaskFilter filter = new RegionMaskFilter(this, mask, count);
+ RegionVisitor visitor = new RegionVisitor(region, filter);
OperationHelper.completeBlindly(visitor); // We can't throw exceptions, nor do we expect any
- return counter.getCount();
+ return count.getCount();
}
/**
diff --git a/src/main/java/com/sk89q/worldedit/operation/BlockCount.java b/src/main/java/com/sk89q/worldedit/operation/BlockCount.java
index 3ac2533e6..9482d141c 100644
--- a/src/main/java/com/sk89q/worldedit/operation/BlockCount.java
+++ b/src/main/java/com/sk89q/worldedit/operation/BlockCount.java
@@ -19,30 +19,15 @@
package com.sk89q.worldedit.operation;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.masks.Mask;
/**
- * Counts the number of blocks that match a given mask.
+ * Counts the number of blocks.
*/
public class BlockCount implements RegionFunction {
- private final EditSession editSession;
- private Mask mask;
private int count;
-
- /**
- * Create a new block counter.
- *
- * @param editSession the edit session
- * @param mask the mask
- */
- public BlockCount(EditSession editSession, Mask mask) {
- this.editSession = editSession;
- this.mask = mask;
- }
/**
* Returns the number of blocks that have been counted.
@@ -55,9 +40,7 @@ import com.sk89q.worldedit.masks.Mask;
@Override
public boolean apply(Vector position) throws WorldEditException {
- if (mask.matches(editSession, position)) {
- count++;
- }
+ count++;
return false;
}
From 09ca5c31317f99dd59523c09a6041cd0626e61c6 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 00:16:24 -0700
Subject: [PATCH 020/106] Cleaned up Javadocs for CuboidRegion; added
preconditions.
---
.../sk89q/worldedit/regions/CuboidRegion.java | 167 ++++++++----------
1 file changed, 73 insertions(+), 94 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
index 37c944da4..736821988 100644
--- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
+++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
@@ -29,80 +29,114 @@ import java.util.Iterator;
import java.util.Set;
import java.util.HashSet;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
- *
- * @author sk89q
+ * An axis-aligned cuboid. It can be defined using two corners of the cuboid.
*/
public class CuboidRegion extends AbstractRegion implements FlatRegion {
- /**
- * Store the first point.
- */
+
private Vector pos1;
- /**
- * Store the second point.
- */
private Vector pos2;
/**
- * Construct a new instance of this cuboid region.
+ * Construct a new instance of this cuboid using two corners of the cuboid.
*
- * @param pos1
- * @param pos2
+ * @param pos1 the first position
+ * @param pos2 the second position
*/
public CuboidRegion(Vector pos1, Vector pos2) {
this(null, pos1, pos2);
}
/**
- * Construct a new instance of this cuboid region.
+ * Construct a new instance of this cuboid using two corners of the cuboid.
*
- * @param world
- * @param pos1
- * @param pos2
+ * @param world the world
+ * @param pos1 the first position
+ * @param pos2 the second position
*/
public CuboidRegion(LocalWorld world, Vector pos1, Vector pos2) {
super(world);
+ checkNotNull(pos1);
+ checkNotNull(pos2);
this.pos1 = pos1;
this.pos2 = pos2;
recalculate();
}
/**
- * Get the lower point of the cuboid.
+ * Get the first cuboid-defining corner.
*
- * @return min point
+ * @return a position
*/
+ public Vector getPos1() {
+ return pos1;
+ }
+
+ /**
+ * Set the first cuboid-defining corner.
+ *
+ * @param pos1 a position
+ */
+ public void setPos1(Vector pos1) {
+ this.pos1 = pos1;
+ }
+
+ /**
+ * Get the second cuboid-defining corner.
+ *
+ * @return a position
+ */
+ public Vector getPos2() {
+ return pos2;
+ }
+
+ /**
+ * Set the second cuboid-defining corner.
+ *
+ * @param pos2 a position
+ */
+ public void setPos2(Vector pos2) {
+ this.pos2 = pos2;
+ }
+
+ /**
+ * Clamps the cuboid according to boundaries of the world.
+ */
+ private void recalculate() {
+ pos1 = pos1.clampY(0, world == null ? 255 : world.getMaxY());
+ pos2 = pos2.clampY(0, world == null ? 255 : world.getMaxY());
+ }
+
+ @Override
public Vector getMinimumPoint() {
return new Vector(Math.min(pos1.getX(), pos2.getX()),
Math.min(pos1.getY(), pos2.getY()),
Math.min(pos1.getZ(), pos2.getZ()));
}
- /**
- * Get the upper point of the cuboid.
- *
- * @return max point
- */
+ @Override
public Vector getMaximumPoint() {
return new Vector(Math.max(pos1.getX(), pos2.getX()),
Math.max(pos1.getY(), pos2.getY()),
Math.max(pos1.getZ(), pos2.getZ()));
}
+ @Override
public int getMinimumY() {
return Math.min(pos1.getBlockY(), pos2.getBlockY());
}
+ @Override
public int getMaximumY() {
return Math.max(pos1.getBlockY(), pos2.getBlockY());
}
- /**
- * Expands the cuboid in a direction.
- *
- * @param change
- */
+ @Override
public void expand(Vector... changes) {
+ checkNotNull(changes);
+
for (Vector change : changes) {
if (change.getX() > 0) {
if (Math.max(pos1.getX(), pos2.getX()) == pos1.getX()) {
@@ -150,12 +184,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
recalculate();
}
- /**
- * Contracts the cuboid in a direction.
- *
- * @param change
- */
+ @Override
public void contract(Vector... changes) {
+ checkNotNull(changes);
+
for (Vector change : changes) {
if (change.getX() < 0) {
if (Math.max(pos1.getX(), pos2.getX()) == pos1.getX()) {
@@ -203,11 +235,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
recalculate();
}
- private void recalculate() {
- pos1 = pos1.clampY(0, world == null ? 255 : world.getMaxY());
- pos2 = pos2.clampY(0, world == null ? 255 : world.getMaxY());
- }
-
@Override
public void shift(Vector change) throws RegionOperationException {
pos1 = pos1.add(change);
@@ -216,47 +243,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
recalculate();
}
- /**
- * Get position 1.
- *
- * @return position 1
- */
- public Vector getPos1() {
- return pos1;
- }
-
- /**
- * Set position 1.
- *
- * @param pos1
- */
- public void setPos1(Vector pos1) {
- this.pos1 = pos1;
- }
-
- /**
- * Get position 2.
- *
- * @return position 2
- */
- public Vector getPos2() {
- return pos2;
- }
-
- /**
- * Set position 2.
- *
- * @param pos2
- */
- public void setPos2(Vector pos2) {
- this.pos2 = pos2;
- }
-
- /**
- * Get a list of chunks that this region is within.
- *
- * @return
- */
+ @Override
public Set getChunks() {
Set chunks = new HashSet();
@@ -273,6 +260,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return chunks;
}
+ @Override
public Set getChunkCubes() {
Set chunks = new HashSet();
@@ -291,11 +279,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return chunks;
}
- /**
- * Returns true based on whether the region contains the point,
- *
- * @param pt
- */
+ @Override
public boolean contains(Vector pt) {
double x = pt.getX();
double y = pt.getY();
@@ -309,11 +293,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
&& z >= min.getBlockZ() && z <= max.getBlockZ();
}
- /**
- * Get the iterator.
- *
- * @return iterator of points inside the region
- */
@Override
public Iterator iterator() {
return new Iterator() {
@@ -323,10 +302,12 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
private int nextY = min.getBlockY();
private int nextZ = min.getBlockZ();
+ @Override
public boolean hasNext() {
return (nextX != Integer.MIN_VALUE);
}
+ @Override
public BlockVector next() {
if (!hasNext()) throw new java.util.NoSuchElementException();
BlockVector answer = new BlockVector(nextX, nextY, nextZ);
@@ -342,6 +323,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
return answer;
}
+ @Override
public void remove() {
throw new UnsupportedOperationException();
}
@@ -359,10 +341,12 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
private int nextX = min.getBlockX();
private int nextZ = min.getBlockZ();
+ @Override
public boolean hasNext() {
return (nextX != Integer.MIN_VALUE);
}
+ @Override
public Vector2D next() {
if (!hasNext()) throw new java.util.NoSuchElementException();
Vector2D answer = new Vector2D(nextX, nextZ);
@@ -384,17 +368,12 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
};
}
- /**
- * Returns string representation in the format
- * "(minX, minY, minZ) - (maxX, maxY, maxZ)".
- *
- * @return string
- */
@Override
public String toString() {
return getMinimumPoint() + " - " + getMaximumPoint();
}
+ @Override
public CuboidRegion clone() {
return (CuboidRegion) super.clone();
}
From dd244bfe0492040772c295c72599647ca1cb5699 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 00:39:11 -0700
Subject: [PATCH 021/106] Add getFaces() and addWalls() to CuboidRegion.
---
.../worldedit/regions/RegionIntersection.java | 148 ++++++++++++++++++
1 file changed, 148 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java
diff --git a/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java b/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java
new file mode 100644
index 000000000..04cb256aa
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java
@@ -0,0 +1,148 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.google.common.collect.Iterators;
+import com.sk89q.worldedit.BlockVector;
+import com.sk89q.worldedit.LocalWorld;
+import com.sk89q.worldedit.Vector;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * An intersection of several other regions. Any location that is contained in one
+ * of the child regions is considered as contained by this region.
+ *
+ * {@link #iterator()} returns a special iterator that will iterate through
+ * the iterators of each region in an undefined sequence. Some positions may
+ * be repeated if the position is contained in more than one region, but this cannot
+ * be guaranteed to occur.
+ */
+public class RegionIntersection extends AbstractRegion {
+
+ private final List regions = new ArrayList();
+
+ /**
+ * Create a new instance with the included list of regions.
+ *
+ * @param regions a list of regions, which is copied
+ */
+ public RegionIntersection(List regions) {
+ this(null, regions);
+ }
+
+ /**
+ * Create a new instance with the included list of regions.
+ *
+ * @param regions a list of regions, which is copied
+ */
+ public RegionIntersection(Region... regions) {
+ this(null, regions);
+ }
+
+ /**
+ * Create a new instance with the included list of regions.
+ *
+ * @param world the world
+ * @param regions a list of regions, which is copied
+ */
+ public RegionIntersection(LocalWorld world, List regions) {
+ super(world);
+ checkNotNull(regions);
+ checkArgument(regions.size() > 0, "empty region list is not supported");
+ for (Region region : regions) {
+ this.regions.add(region);
+ }
+ }
+
+ /**
+ * Create a new instance with the included list of regions.
+ *
+ * @param world the world
+ * @param regions an array of regions, which is copied
+ */
+ public RegionIntersection(LocalWorld world, Region... regions) {
+ super(world);
+ checkNotNull(regions);
+ checkArgument(regions.length > 0, "empty region list is not supported");
+ for (Region region : regions) {
+ this.regions.add(region);
+ }
+ }
+
+ @Override
+ public Vector getMinimumPoint() {
+ Vector minimum = regions.get(0).getMinimumPoint();
+ for (int i = 1; i < regions.size(); i++) {
+ minimum = Vector.getMinimum(regions.get(i).getMinimumPoint(), minimum);
+ }
+ return minimum;
+ }
+
+ @Override
+ public Vector getMaximumPoint() {
+ Vector maximum = regions.get(0).getMaximumPoint();
+ for (int i = 1; i < regions.size(); i++) {
+ maximum = Vector.getMaximum(regions.get(i).getMaximumPoint(), maximum);
+ }
+ return maximum;
+ }
+
+ @Override
+ public void expand(Vector... changes) throws RegionOperationException {
+ checkNotNull(changes);
+ throw new RegionOperationException("Cannot expand a region intersection");
+ }
+
+ @Override
+ public void contract(Vector... changes) throws RegionOperationException {
+ checkNotNull(changes);
+ throw new RegionOperationException("Cannot contract a region intersection");
+ }
+
+ @Override
+ public boolean contains(Vector pt) {
+ checkNotNull(pt);
+
+ for (Region region : regions) {
+ if (region.contains(pt)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ @Override
+ public Iterator iterator() {
+ Iterator[] iterators = (Iterator[]) new Iterator[regions.size()];
+ for (int i = 0; i < regions.size(); i++) {
+ iterators[i] = regions.get(i).iterator();
+ }
+ return Iterators.concat(iterators);
+ }
+
+}
From 6c1ff02df55622e57b84b0b38896726b2ddcf79d Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 00:39:39 -0700
Subject: [PATCH 022/106] Add getFaces() and addWalls() to CuboidRegion.
---
.../sk89q/worldedit/regions/CuboidRegion.java | 64 +++++++++++++++----
1 file changed, 52 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
index 736821988..35df1e097 100644
--- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
+++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
@@ -19,15 +19,12 @@
package com.sk89q.worldedit.regions;
-import com.sk89q.worldedit.BlockVector;
-import com.sk89q.worldedit.BlockVector2D;
-import com.sk89q.worldedit.LocalWorld;
-import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.Vector2D;
+import com.sk89q.worldedit.*;
import com.sk89q.worldedit.data.ChunkStore;
+
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
-import java.util.HashSet;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -53,8 +50,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
* Construct a new instance of this cuboid using two corners of the cuboid.
*
* @param world the world
- * @param pos1 the first position
- * @param pos2 the second position
+ * @param pos1 the first position
+ * @param pos2 the second position
*/
public CuboidRegion(LocalWorld world, Vector pos1, Vector pos2) {
super(world);
@@ -109,18 +106,61 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
pos2 = pos2.clampY(0, world == null ? 255 : world.getMaxY());
}
+ /**
+ * Get a region that contains the faces of this cuboid.
+ *
+ * @return a new complex region
+ */
+ public Region getFaces() {
+ Vector min = getMinimumPoint();
+ Vector max = getMaximumPoint();
+
+ return new RegionIntersection(
+ // Project to Z-Y plane
+ new CuboidRegion(pos1.setX(min.getX()), pos2.setX(min.getX())),
+ new CuboidRegion(pos1.setX(max.getX()), pos2.setX(max.getX())),
+
+ // Project to X-Y plane
+ new CuboidRegion(pos1.setZ(min.getZ()), pos2.setZ(min.getZ())),
+ new CuboidRegion(pos1.setZ(max.getZ()), pos2.setZ(max.getZ())),
+
+ // Project to the X-Z plane
+ new CuboidRegion(pos1.setY(min.getY()), pos2.setY(min.getY())),
+ new CuboidRegion(pos1.setY(max.getY()), pos2.setY(max.getY())));
+ }
+
+ /**
+ * Get a region that contains the walls (all faces but the ones parallel to
+ * the X-Z plane) of this cuboid.
+ *
+ * @return a new complex region
+ */
+ public Region getWalls() {
+ Vector min = getMinimumPoint();
+ Vector max = getMaximumPoint();
+
+ return new RegionIntersection(
+ // Project to Z-Y plane
+ new CuboidRegion(pos1.setX(min.getX()), pos2.setX(min.getX())),
+ new CuboidRegion(pos1.setX(max.getX()), pos2.setX(max.getX())),
+
+ // Project to X-Y plane
+ new CuboidRegion(pos1.setZ(min.getZ()), pos2.setZ(min.getZ())),
+ new CuboidRegion(pos1.setZ(max.getZ()), pos2.setZ(max.getZ())));
+ }
+
@Override
public Vector getMinimumPoint() {
return new Vector(Math.min(pos1.getX(), pos2.getX()),
- Math.min(pos1.getY(), pos2.getY()),
- Math.min(pos1.getZ(), pos2.getZ()));
+ Math.min(pos1.getY(), pos2.getY()),
+ Math.min(pos1.getZ(), pos2.getZ()));
}
@Override
public Vector getMaximumPoint() {
return new Vector(Math.max(pos1.getX(), pos2.getX()),
- Math.max(pos1.getY(), pos2.getY()),
- Math.max(pos1.getZ(), pos2.getZ()));
+ Math.max(pos1.getY(), pos2.getY()),
+ Math.max(pos1.getZ(), pos2.getZ()));
}
@Override
From f509a3128e6baa08240c33c5a6e3a13784d62ac9 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 00:40:04 -0700
Subject: [PATCH 023/106] Switched //faces and //walls to use visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 290 +++++-------------
1 file changed, 72 insertions(+), 218 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index d041591ce..0cf981c5c 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -1006,265 +1006,119 @@ public class EditSession {
}
/**
- * Make faces of the region (as if it was a cuboid if it's not).
+ * Make the faces of the given region as if it was a {@link CuboidRegion}.
*
- * @param region
- * @param block
+ * @param region the region
+ * @param block the block to place
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
- public int makeCuboidFaces(Region region, BaseBlock block)
- throws MaxChangedBlocksException {
- int affected = 0;
-
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- if (setBlock(new Vector(x, y, minZ), block)) {
- ++affected;
- }
- if (setBlock(new Vector(x, y, maxZ), block)) {
- ++affected;
- }
- ++affected;
- }
- }
-
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- if (setBlock(new Vector(minX, y, z), block)) {
- ++affected;
- }
- if (setBlock(new Vector(maxX, y, z), block)) {
- ++affected;
- }
- }
- }
-
- for (int z = minZ; z <= maxZ; ++z) {
- for (int x = minX; x <= maxX; ++x) {
- if (setBlock(new Vector(x, minY, z), block)) {
- ++affected;
- }
- if (setBlock(new Vector(x, maxY, z), block)) {
- ++affected;
- }
- }
- }
-
- return affected;
+ public int makeCuboidFaces(Region region, BaseBlock block) throws MaxChangedBlocksException {
+ return makeCuboidFaces(region, new SingleBlockPattern(block));
}
/**
- * Make faces of the region (as if it was a cuboid if it's not).
+ * Make the faces of the given region as if it was a {@link CuboidRegion}.
*
- * @param region
- * @param pattern
+ * @param region the region
+ * @param pattern the pattern to place
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int makeCuboidFaces(Region region, Pattern pattern)
- throws MaxChangedBlocksException {
- int affected = 0;
+ public int makeCuboidFaces(Region region, Pattern pattern) throws MaxChangedBlocksException {
+ checkNotNull(region);
+ checkNotNull(pattern);
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- Vector minV = new Vector(x, y, minZ);
- if (setBlock(minV, pattern.next(minV))) {
- ++affected;
- }
- Vector maxV = new Vector(x, y, maxZ);
- if (setBlock(maxV, pattern.next(maxV))) {
- ++affected;
- }
- ++affected;
- }
- }
-
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector minV = new Vector(minX, y, z);
- if (setBlock(minV, pattern.next(minV))) {
- ++affected;
- }
- Vector maxV = new Vector(maxX, y, z);
- if (setBlock(maxV, pattern.next(maxV))) {
- ++affected;
- }
- }
- }
-
- for (int z = minZ; z <= maxZ; ++z) {
- for (int x = minX; x <= maxX; ++x) {
- Vector minV = new Vector(x, minY, z);
- if (setBlock(minV, pattern.next(minV))) {
- ++affected;
- }
- Vector maxV = new Vector(x, maxY, z);
- if (setBlock(maxV, pattern.next(maxV))) {
- ++affected;
- }
- }
- }
-
- return affected;
+ CuboidRegion cuboid = CuboidRegion.makeCuboid(region);
+ Region faces = cuboid.getFaces();
+ return setBlocks(faces, pattern);
}
/**
- * Make faces of the region
+ * Make the faces of the given region. The method by which the faces are found
+ * may be inefficient, because there may not be an efficient implementation supported
+ * for that specific shape.
*
- * @param region
- * @param pattern
+ * @param region the region
+ * @param pattern the pattern to place
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int makeFaces(final Region region, Pattern pattern) throws MaxChangedBlocksException {
- return new RegionShape(region).generate(this, pattern, true);
+ checkNotNull(region);
+ checkNotNull(pattern);
+
+ if (region instanceof CuboidRegion) {
+ return makeCuboidFaces(region, pattern);
+ } else {
+ return new RegionShape(region).generate(this, pattern, true);
+ }
}
/**
- * Make walls of the region (as if it was a cuboid if it's not).
+ * Make the walls (all faces but those parallel to the X-Z plane) of the given region
+ * as if it was a {@link CuboidRegion}.
*
- * @param region
- * @param block
+ * @param region the region
+ * @param block the block to place
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
- public int makeCuboidWalls(Region region, BaseBlock block)
- throws MaxChangedBlocksException {
- int affected = 0;
-
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- if (setBlock(new Vector(x, y, minZ), block)) {
- ++affected;
- }
- if (setBlock(new Vector(x, y, maxZ), block)) {
- ++affected;
- }
- ++affected;
- }
- }
-
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- if (setBlock(new Vector(minX, y, z), block)) {
- ++affected;
- }
- if (setBlock(new Vector(maxX, y, z), block)) {
- ++affected;
- }
- }
- }
-
- return affected;
+ public int makeCuboidWalls(Region region, BaseBlock block) throws MaxChangedBlocksException {
+ return makeCuboidWalls(region, new SingleBlockPattern(block));
}
/**
- * Make walls of the region (as if it was a cuboid if it's not).
+ * Make the walls (all faces but those parallel to the X-Z plane) of the given region
+ * as if it was a {@link CuboidRegion}.
*
- * @param region
- * @param pattern
+ * @param region the region
+ * @param pattern the pattern to place
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int makeCuboidWalls(Region region, Pattern pattern)
- throws MaxChangedBlocksException {
- int affected = 0;
+ public int makeCuboidWalls(Region region, Pattern pattern) throws MaxChangedBlocksException {
+ checkNotNull(region);
+ checkNotNull(pattern);
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int y = minY; y <= maxY; ++y) {
- Vector minV = new Vector(x, y, minZ);
- if (setBlock(minV, pattern.next(minV))) {
- ++affected;
- }
- Vector maxV = new Vector(x, y, maxZ);
- if (setBlock(maxV, pattern.next(maxV))) {
- ++affected;
- }
- ++affected;
- }
- }
-
- for (int y = minY; y <= maxY; ++y) {
- for (int z = minZ; z <= maxZ; ++z) {
- Vector minV = new Vector(minX, y, z);
- if (setBlock(minV, pattern.next(minV))) {
- ++affected;
- }
- Vector maxV = new Vector(maxX, y, z);
- if (setBlock(maxV, pattern.next(maxV))) {
- ++affected;
- }
- }
- }
-
- return affected;
+ CuboidRegion cuboid = CuboidRegion.makeCuboid(region);
+ Region faces = cuboid.getWalls();
+ return setBlocks(faces, pattern);
}
/**
- * Make walls of the region
+ * Make the walls of the given region. The method by which the walls are found
+ * may be inefficient, because there may not be an efficient implementation supported
+ * for that specific shape.
*
- * @param region
- * @param pattern
+ * @param region the region
+ * @param pattern the pattern to place
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int makeWalls(final Region region, Pattern pattern) throws MaxChangedBlocksException {
- final int minY = region.getMinimumPoint().getBlockY();
- final int maxY = region.getMaximumPoint().getBlockY();
- final ArbitraryShape shape = new RegionShape(region) {
- @Override
- protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) {
- if (y > maxY || y < minY) {
- // Put holes into the floor and ceiling by telling ArbitraryShape that the shape goes on outside the region
- return defaultMaterial;
- }
+ checkNotNull(region);
+ checkNotNull(pattern);
- return super.getMaterial(x, y, z, defaultMaterial);
- }
- };
- return shape.generate(this, pattern, true);
+ if (region instanceof CuboidRegion) {
+ return makeCuboidWalls(region, pattern);
+ } else {
+ final int minY = region.getMinimumPoint().getBlockY();
+ final int maxY = region.getMaximumPoint().getBlockY();
+ final ArbitraryShape shape = new RegionShape(region) {
+ @Override
+ protected BaseBlock getMaterial(int x, int y, int z, BaseBlock defaultMaterial) {
+ if (y > maxY || y < minY) {
+ // Put holes into the floor and ceiling by telling ArbitraryShape that the shape goes on outside the region
+ return defaultMaterial;
+ }
+
+ return super.getMaterial(x, y, z, defaultMaterial);
+ }
+ };
+ return shape.generate(this, pattern, true);
+ }
}
/**
From fd8ad9b988ffe452bc71e0a3629c9b7dec0e1308 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 00:41:00 -0700
Subject: [PATCH 024/106] Removed messages from EditSession not-null
preconditions.
---
.../java/com/sk89q/worldedit/EditSession.java | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 0cf981c5c..6c877da98 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -805,8 +805,8 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
- checkNotNull(origin, "origin must not be null");
- checkNotNull(pattern, "pattern must not be null");
+ checkNotNull(origin);
+ checkNotNull(pattern);
checkArgument(radius >= 0, "radius >= 0");
checkArgument(depth >= 1, "depth >= 1");
@@ -845,7 +845,7 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int removeAbove(Vector position, int apothem, int height) throws MaxChangedBlocksException {
- checkNotNull(position, "position must not be null");
+ checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
checkArgument(height >= 1, "height >= 1");
@@ -867,7 +867,7 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int removeBelow(Vector position, int apothem, int height) throws MaxChangedBlocksException {
- checkNotNull(position, "position must not be null");
+ checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
checkArgument(height >= 1, "height >= 1");
@@ -889,7 +889,7 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int removeNear(Vector position, int blockType, int apothem) throws MaxChangedBlocksException {
- checkNotNull(position, "position must not be null");
+ checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
Mask mask = new FuzzyBlockMask(new BaseBlock(blockType, -1));
@@ -923,8 +923,8 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
- checkNotNull(region, "region must not be null");
- checkNotNull(pattern, "pattern must not be null");
+ checkNotNull(region);
+ checkNotNull(pattern);
BlockReplace replace = new BlockReplace(this, pattern);
RegionVisitor visitor = new RegionVisitor(region, replace);
@@ -972,9 +972,9 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
- checkNotNull(region, "region must not be null");
- checkNotNull(mask, "mask must not be null");
- checkNotNull(pattern, "pattern must not be null");
+ checkNotNull(region);
+ checkNotNull(mask);
+ checkNotNull(pattern);
BlockReplace replace = new BlockReplace(this, pattern);
RegionMaskFilter filter = new RegionMaskFilter(this, mask, replace);
@@ -994,8 +994,8 @@ public class EditSession {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
- checkNotNull(region, "region must not be null");
- checkNotNull(pattern, "pattern must not be null");
+ checkNotNull(region);
+ checkNotNull(pattern);
Vector center = region.getCenter();
Region centerRegion = new CuboidRegion(
From e7d5cc8603677d16b6c973235d1eb51f7aa32639 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 16:12:39 -0700
Subject: [PATCH 025/106] Added Mask2D and AbstractMask2D.
---
.../sk89q/worldedit/masks/AbstractMask2D.java | 26 +++++++++++++
.../com/sk89q/worldedit/masks/Mask2D.java | 39 +++++++++++++++++++
2 files changed, 65 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java
create mode 100644 src/main/java/com/sk89q/worldedit/masks/Mask2D.java
diff --git a/src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java b/src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java
new file mode 100644
index 000000000..72df4af4d
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java
@@ -0,0 +1,26 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+/**
+ * An abstract implementaiton of {@link com.sk89q.worldedit.masks.Mask2D}.
+ */
+public abstract class AbstractMask2D implements Mask2D {
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/Mask2D.java b/src/main/java/com/sk89q/worldedit/masks/Mask2D.java
new file mode 100644
index 000000000..f70af34a0
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/Mask2D.java
@@ -0,0 +1,39 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector2D;
+
+/**
+ * A 2-dimensional mask, similar to {@link com.sk89q.worldedit.masks.Mask}.
+ */
+public interface Mask2D {
+
+ /**
+ * Return whether the given position is matched by this mask.
+ *
+ * @param editSession an edit session
+ * @param position a mask
+ * @return true if there is a match
+ */
+ boolean matches(EditSession editSession, Vector2D position);
+
+}
From e5e5d8901a533d64afbbabb04c019701c19403f8 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 16:13:12 -0700
Subject: [PATCH 026/106] Added NoiseFilter and NoiseFilter2D masks.
---
.../sk89q/worldedit/masks/NoiseFilter.java | 93 +++++++++++++++++++
.../sk89q/worldedit/masks/NoiseFilter2D.java | 93 +++++++++++++++++++
.../{ => util}/noise/NoiseGenerator.java | 2 +-
.../{ => util}/noise/RandomNoise.java | 2 +-
4 files changed, 188 insertions(+), 2 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
create mode 100644 src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
rename src/main/java/com/sk89q/worldedit/{ => util}/noise/NoiseGenerator.java (97%)
rename src/main/java/com/sk89q/worldedit/{ => util}/noise/RandomNoise.java (97%)
diff --git a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
new file mode 100644
index 000000000..4913704bd
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
@@ -0,0 +1,93 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.util.noise.NoiseGenerator;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A mask that uses a noise generator and returns true whenever the noise
+ * generator returns a value above the given density.
+ */
+public class NoiseFilter extends AbstractMask {
+
+ private NoiseGenerator noiseGenerator;
+ private double density;
+
+ /**
+ * Create a new noise filter.
+ *
+ * @param noiseGenerator the noise generator
+ * @param density the density
+ */
+ public NoiseFilter(NoiseGenerator noiseGenerator, double density) {
+ setNoiseGenerator(noiseGenerator);
+ setDensity(density);
+ }
+
+ /**
+ * Get the noise generator.
+ *
+ * @return the noise generator
+ */
+ public NoiseGenerator getNoiseGenerator() {
+ return noiseGenerator;
+ }
+
+ /**
+ * Set the noise generator.
+ *
+ * @param noiseGenerator a noise generator
+ */
+ public void setNoiseGenerator(NoiseGenerator noiseGenerator) {
+ checkNotNull(noiseGenerator);
+ this.noiseGenerator = noiseGenerator;
+ }
+
+ /**
+ * Get the probability of passing as a number between 0 and 1 (inclusive).
+ *
+ * @return the density
+ */
+ public double getDensity() {
+ return density;
+ }
+
+ /**
+ * Set the probability of passing as a number between 0 and 1 (inclusive).
+ *
+ * @return the density
+ */
+ public void setDensity(double density) {
+ checkArgument(density >= 0, "density must be >= 0");
+ checkArgument(density <= 1, "density must be >= 1");
+ this.density = density;
+ }
+
+ @Override
+ public boolean matches(EditSession editSession, Vector pos) {
+ return noiseGenerator.noise(pos) <= density;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
new file mode 100644
index 000000000..4f6290957
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
@@ -0,0 +1,93 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector2D;
+import com.sk89q.worldedit.util.noise.NoiseGenerator;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A mask that uses a noise generator and returns true whenever the noise
+ * generator returns a value above the given density.
+ */
+public class NoiseFilter2D extends AbstractMask2D {
+
+ private NoiseGenerator noiseGenerator;
+ private double density;
+
+ /**
+ * Create a new noise filter.
+ *
+ * @param noiseGenerator the noise generator
+ * @param density the density
+ */
+ public NoiseFilter2D(NoiseGenerator noiseGenerator, double density) {
+ setNoiseGenerator(noiseGenerator);
+ setDensity(density);
+ }
+
+ /**
+ * Get the noise generator.
+ *
+ * @return the noise generator
+ */
+ public NoiseGenerator getNoiseGenerator() {
+ return noiseGenerator;
+ }
+
+ /**
+ * Set the noise generator.
+ *
+ * @param noiseGenerator a noise generator
+ */
+ public void setNoiseGenerator(NoiseGenerator noiseGenerator) {
+ checkNotNull(noiseGenerator);
+ this.noiseGenerator = noiseGenerator;
+ }
+
+ /**
+ * Get the probability of passing as a number between 0 and 1 (inclusive).
+ *
+ * @return the density
+ */
+ public double getDensity() {
+ return density;
+ }
+
+ /**
+ * Set the probability of passing as a number between 0 and 1 (inclusive).
+ *
+ * @return the density
+ */
+ public void setDensity(double density) {
+ checkArgument(density >= 0, "density must be >= 0");
+ checkArgument(density <= 1, "density must be >= 1");
+ this.density = density;
+ }
+
+ @Override
+ public boolean matches(EditSession editSession, Vector2D pos) {
+ return noiseGenerator.noise(pos) <= density;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/noise/NoiseGenerator.java b/src/main/java/com/sk89q/worldedit/util/noise/NoiseGenerator.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/noise/NoiseGenerator.java
rename to src/main/java/com/sk89q/worldedit/util/noise/NoiseGenerator.java
index 7e95f5f4a..a16271056 100644
--- a/src/main/java/com/sk89q/worldedit/noise/NoiseGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/util/noise/NoiseGenerator.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.noise;
+package com.sk89q.worldedit.util.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
diff --git a/src/main/java/com/sk89q/worldedit/noise/RandomNoise.java b/src/main/java/com/sk89q/worldedit/util/noise/RandomNoise.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/noise/RandomNoise.java
rename to src/main/java/com/sk89q/worldedit/util/noise/RandomNoise.java
index f60480e15..87da1d03d 100644
--- a/src/main/java/com/sk89q/worldedit/noise/RandomNoise.java
+++ b/src/main/java/com/sk89q/worldedit/util/noise/RandomNoise.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.noise;
+package com.sk89q.worldedit.util.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
From 60b839ed09ffbeb0615c07eaac41b8a9ccf23c1e Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 16:13:27 -0700
Subject: [PATCH 027/106] Changed how ground finding operations were
implemented.
---
.../java/com/sk89q/worldedit/EditSession.java | 36 ++--
.../worldedit/commands/RegionCommands.java | 42 ++--
.../operation/FlatRegionMaskingFilter.java | 62 ++++++
.../operation/GroundFindingFunction.java | 188 ------------------
.../worldedit/operation/GroundFunction.java | 64 ++++++
.../operation/GroundScatterFunction.java | 128 ------------
...skFilter.java => RegionMaskingFilter.java} | 29 +--
.../regions/search/AbstractGroundSearch.java | 76 +++++++
.../regions/search/GroundSearch.java | 47 +++++
.../regions/search/MaskingGroundSearch.java | 68 +++++++
10 files changed, 382 insertions(+), 358 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java
delete mode 100644 src/main/java/com/sk89q/worldedit/operation/GroundFindingFunction.java
create mode 100644 src/main/java/com/sk89q/worldedit/operation/GroundFunction.java
delete mode 100644 src/main/java/com/sk89q/worldedit/operation/GroundScatterFunction.java
rename src/main/java/com/sk89q/worldedit/operation/{RegionMaskFilter.java => RegionMaskingFilter.java} (66%)
create mode 100644 src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java
create mode 100644 src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java
create mode 100644 src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 6c877da98..b1faffb4a 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -40,11 +40,14 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
+import com.sk89q.worldedit.regions.search.GroundSearch;
+import com.sk89q.worldedit.regions.search.MaskingGroundSearch;
import com.sk89q.worldedit.shape.ArbitraryBiomeShape;
import com.sk89q.worldedit.shape.ArbitraryShape;
import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator;
+import com.sk89q.worldedit.util.noise.RandomNoise;
import com.sk89q.worldedit.visitor.DownwardVisitor;
import com.sk89q.worldedit.visitor.FlatRegionVisitor;
import com.sk89q.worldedit.visitor.RecursiveVisitor;
@@ -552,7 +555,7 @@ public class EditSession {
public int countBlocks(Region region, Set searchBlocks) {
FuzzyBlockMask mask = new FuzzyBlockMask(searchBlocks);
BlockCount count = new BlockCount();
- RegionMaskFilter filter = new RegionMaskFilter(this, mask, count);
+ RegionMaskingFilter filter = new RegionMaskingFilter(this, mask, count);
RegionVisitor visitor = new RegionVisitor(region, filter);
OperationHelper.completeBlindly(visitor); // We can't throw exceptions, nor do we expect any
return count.getCount();
@@ -977,7 +980,7 @@ public class EditSession {
checkNotNull(pattern);
BlockReplace replace = new BlockReplace(this, pattern);
- RegionMaskFilter filter = new RegionMaskFilter(this, mask, replace);
+ RegionMaskingFilter filter = new RegionMaskingFilter(this, mask, replace);
RegionVisitor visitor = new RegionVisitor(region, filter);
OperationHelper.completeLegacy(visitor);
return visitor.getAffected();
@@ -2045,13 +2048,20 @@ public class EditSession {
position.add(-apothem, -5, -apothem),
position.add(apothem, 10, apothem));
- // And we want to scatter them
- GroundScatterFunction scatter = new GroundScatterFunction(this, generator);
- scatter.setDensity(0.02);
- scatter.setRange(region);
+ int lowerY = region.getMinimumPoint().getBlockY();
+ int upperY = region.getMaximumPoint().getBlockY();
+ double density = 0.02;
+
+ // We want to find the ground
+ GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
+ GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
+
+ // We don't want to place a patch in every column
+ Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
+ FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(this, mask, groundFunction);
// Generate those patches!
- FlatRegionVisitor operation = new FlatRegionVisitor(region, scatter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, filter);
OperationHelper.completeLegacy(operation);
return operation.getAffected();
@@ -2122,16 +2132,14 @@ public class EditSession {
throws WorldEditException {
ForestGenerator generator = new ForestGenerator(this, treeGenerator);
-
- // And we want to scatter them
- GroundScatterFunction scatter = new GroundScatterFunction(this, generator);
- scatter.setDensity(density);
- scatter.setRange(lowerY, upperY);
+ GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
+ GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
+ Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
+ FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(this, mask, groundFunction);
int affected = 0;
-
for (Vector2D pt : it) {
- if (scatter.apply(pt)) {
+ if (filter.apply(pt)) {
affected++;
}
}
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index b3d79cfb9..ae765a52f 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -31,8 +31,15 @@ import com.sk89q.worldedit.filtering.GaussianKernel;
import com.sk89q.worldedit.filtering.HeightMapFilter;
import com.sk89q.worldedit.generator.FloraGenerator;
import com.sk89q.worldedit.generator.ForestGenerator;
+import com.sk89q.worldedit.masks.ExistingBlockMask;
+import com.sk89q.worldedit.masks.Mask2D;
+import com.sk89q.worldedit.masks.NoiseFilter2D;
+import com.sk89q.worldedit.operation.FlatRegionMaskingFilter;
+import com.sk89q.worldedit.operation.GroundFunction;
+import com.sk89q.worldedit.regions.search.GroundSearch;
+import com.sk89q.worldedit.regions.search.MaskingGroundSearch;
+import com.sk89q.worldedit.util.noise.RandomNoise;
import com.sk89q.worldedit.visitor.FlatRegionVisitor;
-import com.sk89q.worldedit.operation.GroundScatterFunction;
import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.operation.OperationHelper;
import com.sk89q.worldedit.patterns.Pattern;
@@ -543,16 +550,18 @@ public class RegionCommands {
Region region = session.getSelection(player.getWorld());
- // We want to generate trees
ForestGenerator generator = new ForestGenerator(editSession, new TreeGenerator(type));
- // And we want to scatter them
- GroundScatterFunction scatter = new GroundScatterFunction(editSession, generator);
- scatter.setDensity(density);
- scatter.setRange(region);
+ int lowerY = region.getMinimumPoint().getBlockY();
+ int upperY = region.getMaximumPoint().getBlockY();
- // Generate that forest
- FlatRegionVisitor operation = new FlatRegionVisitor(region, scatter);
+ GroundSearch search = new MaskingGroundSearch(editSession, new ExistingBlockMask());
+ GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
+ Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
+ FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(editSession, mask, groundFunction);
+
+ // Execute
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, filter);
OperationHelper.complete(operation);
player.print(operation.getAffected() + " trees created.");
@@ -571,17 +580,18 @@ public class RegionCommands {
double density = args.argsLength() > 0 ? args.getDouble(0) / 100 : 0.1;
Region region = session.getSelection(player.getWorld());
-
- // We want to generate flora
FloraGenerator generator = new FloraGenerator(editSession);
- // And we want to scatter them
- GroundScatterFunction scatter = new GroundScatterFunction(editSession, generator);
- scatter.setDensity(density);
- scatter.setRange(region);
+ int lowerY = region.getMinimumPoint().getBlockY();
+ int upperY = region.getMaximumPoint().getBlockY();
- // Generate that flora
- FlatRegionVisitor operation = new FlatRegionVisitor(region, scatter);
+ GroundSearch search = new MaskingGroundSearch(editSession, new ExistingBlockMask());
+ GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
+ Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
+ FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(editSession, mask, groundFunction);
+
+ // Execute
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, filter);
OperationHelper.complete(operation);
player.print(operation.getAffected() + " flora created.");
diff --git a/src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java b/src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java
new file mode 100644
index 000000000..7a6abb656
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java
@@ -0,0 +1,62 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector2D;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.masks.Mask2D;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Passes calls to {@link #apply(com.sk89q.worldedit.Vector2D)} to the
+ * delegate {@link com.sk89q.worldedit.operation.FlatRegionFunction} if they
+ * match the given mask.
+ */
+public class FlatRegionMaskingFilter implements FlatRegionFunction {
+
+ private final EditSession editSession;
+ private final FlatRegionFunction function;
+ private Mask2D mask;
+
+ /**
+ * Create a new masking filter.
+ *
+ * @param editSession the edit session
+ * @param mask the mask
+ * @param function the delegate function to call
+ */
+ public FlatRegionMaskingFilter(EditSession editSession, Mask2D mask, FlatRegionFunction function) {
+ checkNotNull(function);
+ checkNotNull(editSession);
+ checkNotNull(mask);
+
+ this.editSession = editSession;
+ this.mask = mask;
+ this.function = function;
+ }
+
+ @Override
+ public boolean apply(Vector2D position) throws WorldEditException {
+ return mask.matches(editSession, position) && function.apply(position);
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/operation/GroundFindingFunction.java b/src/main/java/com/sk89q/worldedit/operation/GroundFindingFunction.java
deleted file mode 100644
index 63f0f7715..000000000
--- a/src/main/java/com/sk89q/worldedit/operation/GroundFindingFunction.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * 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 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.operation;
-
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.Vector2D;
-import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.blocks.BaseBlock;
-import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.regions.Region;
-
-/**
- * An abstract implementation of {@link com.sk89q.worldedit.operation.FlatRegionFunction}
- * that searches for the first "ground" block." A ground block is found when the
- * method {@link #shouldPassThrough(Vector, BaseBlock)} returns false, which, by default,
- * does so for all non-air blocks.
- *
- * This function starts from the provided upperY in each block column and traverses
- * down the column until it finds the first ground block, at which point
- * {@link #apply(Vector, BaseBlock)} is called with the position and the
- * {@link BaseBlock} for the found ground block. Implementations that want
- * to skip certain columns (and avoid the ground search) can override
- * {@link #shouldContinue(com.sk89q.worldedit.Vector2D)} and return true as necessary.
- */
-public abstract class GroundFindingFunction implements FlatRegionFunction {
-
- private final EditSession editSession;
- private int lowerY;
- private int upperY;
-
- /**
- * Create a new instance.
- *
- * @param editSession the edit session
- */
- protected GroundFindingFunction(EditSession editSession) {
- this.editSession = editSession;
- checkYBounds();
- }
-
- /**
- * Check whether upperY is >= lowerY.
- */
- private void checkYBounds() {
- if (upperY < lowerY) {
- throw new IllegalArgumentException("upperY must be greater than or equal to lowerY");
- }
- }
-
- /**
- * Get the upper Y coordinate to start the ground search from.
- *
- * @return the upper Y coordinate
- */
- public int getUpperY() {
- return upperY;
- }
-
- /**
- * Get the lower Y coordinate to end the ground search at.
- *
- * @return lowerY the lower Y coordinate
- */
- public int getLowerY() {
- return lowerY;
- }
-
- /**
- * Set the range of Y coordinates to perform a search for ground within.
- *
- * @param lowerY the lower Y coordinate
- * @param upperY the upper Y coordinate (upperY >= lowerY)
- */
- public void setRange(int lowerY, int upperY) {
- this.lowerY = lowerY;
- this.upperY = upperY;
- checkYBounds();
- }
-
- /**
- * Set the range of Y coordinates to perform a search for ground within from
- * the minimum and maximum Y of the given region.
- *
- * @param region the region
- */
- public void setRange(Region region) {
- setRange(region.getMinimumPoint().getBlockY(), region.getMaximumPoint().getBlockY());
- }
-
- /**
- * Increase the upper Y by the given amount.
- *
- * @param y the amount to increase the upper Y by
- */
- public void raiseCeiling(int y) {
- if (y <= 0) {
- throw new IllegalArgumentException("Can't raise by a negative");
- }
- upperY += y;
- }
-
- @Override
- public final boolean apply(Vector2D pt) throws WorldEditException {
- // Don't want to be in the ground
- if (!editSession.getBlock(pt.toVector(upperY + 1)).isAir()) {
- return false;
- }
-
- if (!shouldContinue(pt)) {
- return false;
- }
-
- for (int y = upperY + 1; y >= lowerY; --y) {
- Vector testPt = pt.toVector(y);
- BaseBlock block = editSession.getBlock(testPt);
-
- if (!shouldPassThrough(testPt, block)) {
- return apply(testPt, block);
- }
- }
-
- return false;
- }
-
- /**
- * Returns whether a search for the ground should be performed for the given
- * column. Return false if the column is to be skipped.
- *
- * @param pt the point
- * @return true if the search should begin
- */
- protected boolean shouldContinue(Vector2D pt) {
- return true;
- }
-
- /**
- * Returns whether the given block should be "passed through" when
- * conducting the ground search.
- *
- * Examples of blocks where this method could return true include snow, tall
- * grass, shrubs, and flowers. Note that this method will also receive
- * calls on each air block so that condition must be handled. Be aware
- * that blocks passed through are not automatically removed
- * from the world, so implementations may need to remove the block
- * immediately above the ground.
- *
- * The default implementation only returns true for air blocks.
- *
- * @param position the position
- * @param block the block
- * @return true if the block should be passed through during the ground search
- */
- protected boolean shouldPassThrough(Vector position, BaseBlock block) {
- return block.getType() == BlockID.AIR;
- }
-
- /**
- * Apply the function to the given ground block.
- *
- * Naive implementations may provide flowers, tall grass, and other
- * blocks not often considered to be the ground as the ground block.
- *
- * @param position the position
- * @param block the block
- * @return true if something was changed
- * @throws WorldEditException thrown on an error
- */
- protected abstract boolean apply(Vector position, BaseBlock block) throws WorldEditException;
-
-}
diff --git a/src/main/java/com/sk89q/worldedit/operation/GroundFunction.java b/src/main/java/com/sk89q/worldedit/operation/GroundFunction.java
new file mode 100644
index 000000000..78e90e209
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/operation/GroundFunction.java
@@ -0,0 +1,64 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.operation;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.Vector2D;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.regions.search.GroundSearch;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Accepts 2D coordinates to columns, finds the first ground block in each
+ * column, and applies the given {@link RegionFunction} onto the ground blocks.
+ */
+public class GroundFunction implements FlatRegionFunction {
+
+ private final RegionFunction function;
+ private GroundSearch groundSearch;
+ private int minY;
+ private int maxY;
+
+ /**
+ * Create a new instance.
+ *
+ * @param groundSearch the ground search implementation
+ * @param minY the minimum Y (inclusive)
+ * @param maxY the maximum Y (inclusive)
+ * @param function the function to apply on ground blocks
+ */
+ public GroundFunction(GroundSearch groundSearch, int minY, int maxY, RegionFunction function) {
+ checkNotNull(function);
+ checkNotNull(groundSearch);
+ checkArgument(minY <= maxY, "minY <= maxY required");
+ this.function = function;
+ this.groundSearch = groundSearch;
+ this.minY = minY;
+ this.maxY = maxY;
+ }
+
+ @Override
+ public boolean apply(Vector2D pt) throws WorldEditException {
+ Vector ground = groundSearch.findGround(pt.toVector(maxY), minY);
+ return ground != null && function.apply(ground);
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/operation/GroundScatterFunction.java b/src/main/java/com/sk89q/worldedit/operation/GroundScatterFunction.java
deleted file mode 100644
index 474d70214..000000000
--- a/src/main/java/com/sk89q/worldedit/operation/GroundScatterFunction.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * 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 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.operation;
-
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.Vector2D;
-import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.blocks.BaseBlock;
-import com.sk89q.worldedit.noise.NoiseGenerator;
-import com.sk89q.worldedit.noise.RandomNoise;
-
-/**
- * Randomly applies the given {@link RegionFunction} onto random ground blocks.
- *
- * This class can be used to generate a structure randomly over an area.
- */
-public class GroundScatterFunction extends GroundFindingFunction {
-
- private NoiseGenerator noiseGenerator;
- private RegionFunction function;
- private double density;
-
- /**
- * Create a new instance using a {@link RandomNoise} as the noise generator.
- *
- * @param editSession the edit session
- * @param function the function
- */
- public GroundScatterFunction(EditSession editSession, RegionFunction function) {
- this(editSession, function, new RandomNoise());
- }
-
- /**
- * Create a new instance.
- *
- * @param editSession the edit session
- * @param function the function
- */
- public GroundScatterFunction(EditSession editSession, RegionFunction function, NoiseGenerator noiseGenerator) {
- super(editSession);
- this.function = function;
- this.noiseGenerator = noiseGenerator;
- }
-
- /**
- * Get the density (0 <= density <= 1) which indicates the threshold that
- * must be met for the function to be applied to a column.
- *
- * @return the density
- */
- public double getDensity() {
- return density;
- }
-
- /**
- * Set the density (0 <= density <= 1) which indicates the threshold that
- * must be met for the function to be applied to a column.
- *
- * @param density the density
- */
- public void setDensity(double density) {
- this.density = density;
- }
-
- /**
- * Get the noise generator.
- *
- * @return the noise generator
- */
- public NoiseGenerator getNoiseGenerator() {
- return noiseGenerator;
- }
-
- /**
- * Set the noise generator.
- *
- * @param noiseGenerator the noise generator
- */
- public void setNoiseGenerator(NoiseGenerator noiseGenerator) {
- this.noiseGenerator = noiseGenerator;
- }
-
- /**
- * Get the function to apply.
- *
- * @return the region function
- */
- public RegionFunction getFunction() {
- return function;
- }
-
- /**
- * Set the function to apply.
- *
- * @param function the region function
- */
- public void setFunction(RegionFunction function) {
- this.function = function;
- }
-
- @Override
- protected boolean shouldContinue(Vector2D pt) {
- return noiseGenerator.noise(pt) <= density;
- }
-
- @Override
- protected boolean apply(Vector position, BaseBlock block) throws WorldEditException {
- return function.apply(position);
- }
-}
diff --git a/src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java b/src/main/java/com/sk89q/worldedit/operation/RegionMaskingFilter.java
similarity index 66%
rename from src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java
rename to src/main/java/com/sk89q/worldedit/operation/RegionMaskingFilter.java
index 6a8640401..072f46be7 100644
--- a/src/main/java/com/sk89q/worldedit/operation/RegionMaskFilter.java
+++ b/src/main/java/com/sk89q/worldedit/operation/RegionMaskingFilter.java
@@ -27,18 +27,27 @@ import com.sk89q.worldedit.masks.Mask;
import static com.google.common.base.Preconditions.checkNotNull;
/**
- * Passes positions that match the given mask onto the provided function.
+ * Passes calls to {@link #apply(com.sk89q.worldedit.Vector)} to the
+ * delegate {@link com.sk89q.worldedit.operation.RegionFunction} if they
+ * match the given mask.
*/
-public class RegionMaskFilter implements RegionFunction {
+public class RegionMaskingFilter implements RegionFunction {
private final EditSession editSession;
- private final Mask mask;
private final RegionFunction function;
+ private Mask mask;
- public RegionMaskFilter(EditSession editSession, Mask mask, RegionFunction function) {
- checkNotNull(function, "function must not be null");
- checkNotNull(editSession, "editSession must not be null");
- checkNotNull(mask, "mask must not be null");
+ /**
+ * Create a new masking filter.
+ *
+ * @param editSession the edit session
+ * @param mask the mask
+ * @param function the function
+ */
+ public RegionMaskingFilter(EditSession editSession, Mask mask, RegionFunction function) {
+ checkNotNull(function);
+ checkNotNull(editSession);
+ checkNotNull(mask);
this.editSession = editSession;
this.mask = mask;
@@ -47,11 +56,7 @@ public class RegionMaskFilter implements RegionFunction {
@Override
public boolean apply(Vector position) throws WorldEditException {
- if (mask.matches(editSession, position)) {
- return function.apply(position);
- } else {
- return false;
- }
+ return mask.matches(editSession, position) && function.apply(position);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java b/src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java
new file mode 100644
index 000000000..94ca881b9
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java
@@ -0,0 +1,76 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.search;
+
+import com.sk89q.worldedit.Vector;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static net.minecraft.util.com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Utility class for finding the first ground block starting from a certain
+ * position and traversing down.
+ */
+public abstract class AbstractGroundSearch implements GroundSearch {
+
+ /**
+ * Returns whether the given block should be "passed through" when
+ * conducting the ground search.
+ *
+ * @param position return whether the given block is the ground
+ * @return true if the search should stop
+ */
+ protected abstract boolean isGround(Vector position);
+
+ /**
+ * Find the ground block starting from the given position and traversing
+ * downward until reaching minY (inclusive).
+ *
+ * The highest ground block that may be returned is at the location of
+ * the origin location. The lowest ground block that may be returned is
+ * in the same column as the origin but with y = minY.
+ *
+ * It is possible for no ground block to be found if the given origin
+ * block is underground to begin with.
+ *
+ * @param origin the origin
+ * @param minY the minimum Y to end the search at
+ * @return the location of a ground block, or null if none was found
+ */
+ public Vector findGround(Vector origin, int minY) {
+ checkNotNull(origin);
+ checkArgument(minY <= origin.getBlockY(), "minY <= origin Y");
+
+ // Don't want to be in the ground
+ if (isGround(origin.add(0, 1, 0))) {
+ return null;
+ }
+
+ for (int y = origin.getBlockY() + 1; y >= minY; --y) {
+ Vector test = origin.setY(y);
+ if (isGround(test)) {
+ return test;
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java b/src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java
new file mode 100644
index 000000000..0f0aa3ada
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java
@@ -0,0 +1,47 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.search;
+
+import com.sk89q.worldedit.Vector;
+
+/**
+ * Given a column of blocks in the world, finds the first ground block
+ * starting from a given Y.
+ */
+public interface GroundSearch {
+
+ /**
+ * Find the ground block starting from the given position and traversing
+ * downward until reaching minY (inclusive).
+ *
+ * The highest ground block that may be returned is at the location of
+ * the origin location. The lowest ground block that may be returned is
+ * in the same column as the origin but with y = minY.
+ *
+ * It is possible for no ground block to be found if the given origin
+ * block is underground.
+ *
+ * @param origin the origin
+ * @param minY the minimum Y to end the search at
+ * @return the location of a ground block, or null if none was found
+ */
+ Vector findGround(Vector origin, int minY);
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java b/src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java
new file mode 100644
index 000000000..27c196c22
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java
@@ -0,0 +1,68 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.search;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.masks.Mask;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A ground finder that uses a {@link com.sk89q.worldedit.masks.Mask} to determine
+ * ground blocks.
+ */
+public class MaskingGroundSearch extends AbstractGroundSearch {
+
+ private final EditSession editSession;
+ private final Mask mask;
+
+ /**
+ * Create a new instance.
+ *
+ * If a mask that matches non-ground blocks is available, it can be inverted with
+ * {@link com.sk89q.worldedit.masks.InvertedMask}.
+ *
+ * @param editSession an edit session
+ * @param mask a mask that matches ground blocks
+ */
+ public MaskingGroundSearch(EditSession editSession, Mask mask) {
+ checkNotNull(editSession);
+ checkNotNull(mask);
+
+ this.editSession = editSession;
+ this.mask = mask;
+ }
+
+ /**
+ * Get the mask that matches ground blocks.
+ *
+ * @return the mask
+ */
+ public Mask getMask() {
+ return mask;
+ }
+
+ @Override
+ protected boolean isGround(Vector position) {
+ return mask.matches(editSession, position);
+ }
+
+}
From 53730bfa20b36635a4270e260945b89041c5089a Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 16:15:40 -0700
Subject: [PATCH 028/106] Moved packages to worldedit.function.*.
---
.../java/com/sk89q/worldedit/EditSession.java | 21 +++++++++++--------
.../worldedit/commands/RegionCommands.java | 12 +++++------
.../FlatRegionFunction.java | 2 +-
.../FlatRegionMaskingFilter.java | 4 ++--
.../GroundFunction.java | 2 +-
.../RegionFunction.java | 2 +-
.../RegionMaskingFilter.java | 4 ++--
.../block}/BlockCount.java | 3 ++-
.../block}/BlockReplace.java | 4 ++--
.../generator/FloraGenerator.java | 4 ++--
.../generator/ForestGenerator.java | 4 ++--
.../generator/GardenPatchGenerator.java | 4 ++--
.../{ => function}/operation/Operation.java | 2 +-
.../operation/OperationHelper.java | 2 +-
.../visitor/BreadthFirstSearch.java | 6 +++---
.../visitor/DownwardVisitor.java | 4 ++--
.../visitor/FlatRegionVisitor.java | 6 +++---
.../visitor/RecursiveVisitor.java | 4 ++--
.../{ => function}/visitor/RegionVisitor.java | 6 +++---
19 files changed, 50 insertions(+), 46 deletions(-)
rename src/main/java/com/sk89q/worldedit/{operation => function}/FlatRegionFunction.java (96%)
rename src/main/java/com/sk89q/worldedit/{operation => function}/FlatRegionMaskingFilter.java (94%)
rename src/main/java/com/sk89q/worldedit/{operation => function}/GroundFunction.java (98%)
rename src/main/java/com/sk89q/worldedit/{operation => function}/RegionFunction.java (96%)
rename src/main/java/com/sk89q/worldedit/{operation => function}/RegionMaskingFilter.java (94%)
rename src/main/java/com/sk89q/worldedit/{operation => function/block}/BlockCount.java (93%)
rename src/main/java/com/sk89q/worldedit/{operation => function/block}/BlockReplace.java (94%)
rename src/main/java/com/sk89q/worldedit/{ => function}/generator/FloraGenerator.java (97%)
rename src/main/java/com/sk89q/worldedit/{ => function}/generator/ForestGenerator.java (95%)
rename src/main/java/com/sk89q/worldedit/{ => function}/generator/GardenPatchGenerator.java (98%)
rename src/main/java/com/sk89q/worldedit/{ => function}/operation/Operation.java (97%)
rename src/main/java/com/sk89q/worldedit/{ => function}/operation/OperationHelper.java (98%)
rename src/main/java/com/sk89q/worldedit/{ => function}/visitor/BreadthFirstSearch.java (97%)
rename src/main/java/com/sk89q/worldedit/{ => function}/visitor/DownwardVisitor.java (95%)
rename src/main/java/com/sk89q/worldedit/{ => function}/visitor/FlatRegionVisitor.java (92%)
rename src/main/java/com/sk89q/worldedit/{ => function}/visitor/RecursiveVisitor.java (94%)
rename src/main/java/com/sk89q/worldedit/{ => function}/visitor/RegionVisitor.java (91%)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index b1faffb4a..7d29b1f06 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -27,13 +27,16 @@ import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.expression.Expression;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
-import com.sk89q.worldedit.generator.ForestGenerator;
-import com.sk89q.worldedit.generator.GardenPatchGenerator;
+import com.sk89q.worldedit.function.block.BlockCount;
+import com.sk89q.worldedit.function.operation.OperationHelper;
+import com.sk89q.worldedit.function.block.BlockReplace;
+import com.sk89q.worldedit.function.generator.ForestGenerator;
+import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
import com.sk89q.worldedit.masks.*;
-import com.sk89q.worldedit.operation.*;
+import com.sk89q.worldedit.function.*;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.CuboidRegion;
@@ -48,10 +51,10 @@ import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.noise.RandomNoise;
-import com.sk89q.worldedit.visitor.DownwardVisitor;
-import com.sk89q.worldedit.visitor.FlatRegionVisitor;
-import com.sk89q.worldedit.visitor.RecursiveVisitor;
-import com.sk89q.worldedit.visitor.RegionVisitor;
+import com.sk89q.worldedit.function.visitor.DownwardVisitor;
+import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
+import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
+import com.sk89q.worldedit.function.visitor.RegionVisitor;
import java.util.*;
@@ -2123,8 +2126,8 @@ public class EditSession {
* @param treeGenerator the tree generator
* @return number of trees created
* @throws MaxChangedBlocksException
- * @deprecated Use {@link com.sk89q.worldedit.generator.ForestGenerator} with a
- * {@link com.sk89q.worldedit.visitor.FlatRegionVisitor}
+ * @deprecated Use {@link com.sk89q.worldedit.function.generator.ForestGenerator} with a
+ * {@link com.sk89q.worldedit.function.visitor.FlatRegionVisitor}
*/
@Deprecated
public int makeForest(Iterable it, int upperY, int lowerY,
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index ae765a52f..15572c813 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -29,19 +29,19 @@ import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.filtering.GaussianKernel;
import com.sk89q.worldedit.filtering.HeightMapFilter;
-import com.sk89q.worldedit.generator.FloraGenerator;
-import com.sk89q.worldedit.generator.ForestGenerator;
+import com.sk89q.worldedit.function.generator.FloraGenerator;
+import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.masks.ExistingBlockMask;
import com.sk89q.worldedit.masks.Mask2D;
import com.sk89q.worldedit.masks.NoiseFilter2D;
-import com.sk89q.worldedit.operation.FlatRegionMaskingFilter;
-import com.sk89q.worldedit.operation.GroundFunction;
+import com.sk89q.worldedit.function.FlatRegionMaskingFilter;
+import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.regions.search.GroundSearch;
import com.sk89q.worldedit.regions.search.MaskingGroundSearch;
import com.sk89q.worldedit.util.noise.RandomNoise;
-import com.sk89q.worldedit.visitor.FlatRegionVisitor;
+import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.operation.OperationHelper;
+import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.*;
diff --git a/src/main/java/com/sk89q/worldedit/operation/FlatRegionFunction.java b/src/main/java/com/sk89q/worldedit/function/FlatRegionFunction.java
similarity index 96%
rename from src/main/java/com/sk89q/worldedit/operation/FlatRegionFunction.java
rename to src/main/java/com/sk89q/worldedit/function/FlatRegionFunction.java
index 88f1039fa..b62508d1d 100644
--- a/src/main/java/com/sk89q/worldedit/operation/FlatRegionFunction.java
+++ b/src/main/java/com/sk89q/worldedit/function/FlatRegionFunction.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
diff --git a/src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java b/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java
rename to src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
index 7a6abb656..e6bf41fba 100644
--- a/src/main/java/com/sk89q/worldedit/operation/FlatRegionMaskingFilter.java
+++ b/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector2D;
@@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* Passes calls to {@link #apply(com.sk89q.worldedit.Vector2D)} to the
- * delegate {@link com.sk89q.worldedit.operation.FlatRegionFunction} if they
+ * delegate {@link com.sk89q.worldedit.function.FlatRegionFunction} if they
* match the given mask.
*/
public class FlatRegionMaskingFilter implements FlatRegionFunction {
diff --git a/src/main/java/com/sk89q/worldedit/operation/GroundFunction.java b/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
similarity index 98%
rename from src/main/java/com/sk89q/worldedit/operation/GroundFunction.java
rename to src/main/java/com/sk89q/worldedit/function/GroundFunction.java
index 78e90e209..ced5546ff 100644
--- a/src/main/java/com/sk89q/worldedit/operation/GroundFunction.java
+++ b/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
diff --git a/src/main/java/com/sk89q/worldedit/operation/RegionFunction.java b/src/main/java/com/sk89q/worldedit/function/RegionFunction.java
similarity index 96%
rename from src/main/java/com/sk89q/worldedit/operation/RegionFunction.java
rename to src/main/java/com/sk89q/worldedit/function/RegionFunction.java
index 8707d7c4f..1f13a2cad 100644
--- a/src/main/java/com/sk89q/worldedit/operation/RegionFunction.java
+++ b/src/main/java/com/sk89q/worldedit/function/RegionFunction.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
diff --git a/src/main/java/com/sk89q/worldedit/operation/RegionMaskingFilter.java b/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/operation/RegionMaskingFilter.java
rename to src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
index 072f46be7..461846c5d 100644
--- a/src/main/java/com/sk89q/worldedit/operation/RegionMaskingFilter.java
+++ b/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
@@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* Passes calls to {@link #apply(com.sk89q.worldedit.Vector)} to the
- * delegate {@link com.sk89q.worldedit.operation.RegionFunction} if they
+ * delegate {@link com.sk89q.worldedit.function.RegionFunction} if they
* match the given mask.
*/
public class RegionMaskingFilter implements RegionFunction {
diff --git a/src/main/java/com/sk89q/worldedit/operation/BlockCount.java b/src/main/java/com/sk89q/worldedit/function/block/BlockCount.java
similarity index 93%
rename from src/main/java/com/sk89q/worldedit/operation/BlockCount.java
rename to src/main/java/com/sk89q/worldedit/function/block/BlockCount.java
index 9482d141c..9a5d9fdaf 100644
--- a/src/main/java/com/sk89q/worldedit/operation/BlockCount.java
+++ b/src/main/java/com/sk89q/worldedit/function/block/BlockCount.java
@@ -17,10 +17,11 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function.block;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.function.RegionFunction;
/**
* Counts the number of blocks.
diff --git a/src/main/java/com/sk89q/worldedit/operation/BlockReplace.java b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/operation/BlockReplace.java
rename to src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
index 8153584ff..5298dcf66 100644
--- a/src/main/java/com/sk89q/worldedit/operation/BlockReplace.java
+++ b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
@@ -17,12 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function.block;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.patterns.Pattern;
/**
diff --git a/src/main/java/com/sk89q/worldedit/generator/FloraGenerator.java b/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/generator/FloraGenerator.java
rename to src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
index 7ddb06678..56085eee6 100644
--- a/src/main/java/com/sk89q/worldedit/generator/FloraGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
@@ -17,14 +17,14 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.generator;
+package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.patterns.BlockChance;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.RandomFillPattern;
diff --git a/src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java b/src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java
similarity index 95%
rename from src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java
rename to src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java
index 74b41d581..42598244d 100644
--- a/src/main/java/com/sk89q/worldedit/generator/ForestGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/function/generator/ForestGenerator.java
@@ -17,14 +17,14 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.generator;
+package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.util.TreeGenerator;
/**
diff --git a/src/main/java/com/sk89q/worldedit/generator/GardenPatchGenerator.java b/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
similarity index 98%
rename from src/main/java/com/sk89q/worldedit/generator/GardenPatchGenerator.java
rename to src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
index 873495ceb..2a145410b 100644
--- a/src/main/java/com/sk89q/worldedit/generator/GardenPatchGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.generator;
+package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
@@ -25,7 +25,7 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.patterns.BlockChance;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.RandomFillPattern;
diff --git a/src/main/java/com/sk89q/worldedit/operation/Operation.java b/src/main/java/com/sk89q/worldedit/function/operation/Operation.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/operation/Operation.java
rename to src/main/java/com/sk89q/worldedit/function/operation/Operation.java
index 0e6fc5f11..494ccc802 100644
--- a/src/main/java/com/sk89q/worldedit/operation/Operation.java
+++ b/src/main/java/com/sk89q/worldedit/function/operation/Operation.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.WorldEditException;
diff --git a/src/main/java/com/sk89q/worldedit/operation/OperationHelper.java b/src/main/java/com/sk89q/worldedit/function/operation/OperationHelper.java
similarity index 98%
rename from src/main/java/com/sk89q/worldedit/operation/OperationHelper.java
rename to src/main/java/com/sk89q/worldedit/function/operation/OperationHelper.java
index a3585646f..579045a0f 100644
--- a/src/main/java/com/sk89q/worldedit/operation/OperationHelper.java
+++ b/src/main/java/com/sk89q/worldedit/function/operation/OperationHelper.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.operation;
+package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
diff --git a/src/main/java/com/sk89q/worldedit/visitor/BreadthFirstSearch.java b/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/visitor/BreadthFirstSearch.java
rename to src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
index 3b9979467..153882333 100644
--- a/src/main/java/com/sk89q/worldedit/visitor/BreadthFirstSearch.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
@@ -17,13 +17,13 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.visitor;
+package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.operation.Operation;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.function.RegionFunction;
import java.util.*;
diff --git a/src/main/java/com/sk89q/worldedit/visitor/DownwardVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
similarity index 95%
rename from src/main/java/com/sk89q/worldedit/visitor/DownwardVisitor.java
rename to src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
index 78614ebe1..a2764476f 100644
--- a/src/main/java/com/sk89q/worldedit/visitor/DownwardVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
@@ -17,12 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.visitor;
+package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.RegionFunction;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/visitor/FlatRegionVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
similarity index 92%
rename from src/main/java/com/sk89q/worldedit/visitor/FlatRegionVisitor.java
rename to src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
index 816219205..33a7dbb81 100644
--- a/src/main/java/com/sk89q/worldedit/visitor/FlatRegionVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
@@ -17,12 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.visitor;
+package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.operation.FlatRegionFunction;
-import com.sk89q.worldedit.operation.Operation;
+import com.sk89q.worldedit.function.FlatRegionFunction;
+import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.Region;
diff --git a/src/main/java/com/sk89q/worldedit/visitor/RecursiveVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/visitor/RecursiveVisitor.java
rename to src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
index aa9ef421a..5e86da7c5 100644
--- a/src/main/java/com/sk89q/worldedit/visitor/RecursiveVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
@@ -17,12 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.visitor;
+package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.RegionFunction;
/**
* An implementation of an {@link BreadthFirstSearch} that uses a mask to
diff --git a/src/main/java/com/sk89q/worldedit/visitor/RegionVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java
similarity index 91%
rename from src/main/java/com/sk89q/worldedit/visitor/RegionVisitor.java
rename to src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java
index e87bea61b..99cf2d273 100644
--- a/src/main/java/com/sk89q/worldedit/visitor/RegionVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java
@@ -17,12 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.visitor;
+package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.operation.Operation;
-import com.sk89q.worldedit.operation.RegionFunction;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.regions.Region;
/**
From 77071211f258b2e99dda2a83ffb803f52f0082f9 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 16:48:53 -0700
Subject: [PATCH 029/106] Added RegionOffset and FlatRegionOffset.
---
.../function/util/FlatRegionOffset.java | 71 ++++++++++++++++++
.../worldedit/function/util/RegionOffset.java | 72 +++++++++++++++++++
2 files changed, 143 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java
diff --git a/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java b/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java
new file mode 100644
index 000000000..a51b2800d
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/util/FlatRegionOffset.java
@@ -0,0 +1,71 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.util;
+
+import com.sk89q.worldedit.Vector2D;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.function.FlatRegionFunction;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Offsets the position parameter by adding a given offset vector.
+ */
+public class FlatRegionOffset implements FlatRegionFunction {
+
+ private Vector2D offset;
+ private final FlatRegionFunction function;
+
+ /**
+ * Create a new instance.
+ *
+ * @param offset the offset
+ * @param function the function that is called with the offset position
+ */
+ public FlatRegionOffset(Vector2D offset, FlatRegionFunction function) {
+ checkNotNull(function);
+ setOffset(offset);
+ this.function = function;
+ }
+
+ /**
+ * Get the offset that is added to the position.
+ *
+ * @return the offset
+ */
+ public Vector2D getOffset() {
+ return offset;
+ }
+
+ /**
+ * Set the offset that is added to the position.
+ *
+ * @param offset the offset
+ */
+ public void setOffset(Vector2D offset) {
+ checkNotNull(offset);
+ this.offset = offset;
+ }
+
+ @Override
+ public boolean apply(Vector2D position) throws WorldEditException {
+ return function.apply(position.add(offset));
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java b/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java
new file mode 100644
index 000000000..b9d063d62
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/util/RegionOffset.java
@@ -0,0 +1,72 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.util;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.function.RegionFunction;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Offsets the position parameter by adding a given offset vector.
+ */
+public class RegionOffset implements RegionFunction {
+
+ private Vector offset;
+ private final RegionFunction function;
+
+ /**
+ * Create a new instance.
+ *
+ * @param offset the offset
+ * @param function the function that is called with the offset position
+ */
+ public RegionOffset(Vector offset, RegionFunction function) {
+ checkNotNull(function);
+ setOffset(offset);
+ this.function = function;
+ }
+
+ /**
+ * Get the offset that is added to the position.
+ *
+ * @return the offset
+ */
+ public Vector getOffset() {
+ return offset;
+ }
+
+ /**
+ * Set the offset that is added to the position.
+ *
+ * @param offset the offset
+ */
+ public void setOffset(Vector offset) {
+ checkNotNull(offset);
+ this.offset = offset;
+ }
+
+ @Override
+ public boolean apply(Vector position) throws WorldEditException {
+ return function.apply(position.add(offset));
+ }
+
+}
From 1b6d32ba3af352a141f1f6913c791df7086cd287 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Fri, 28 Mar 2014 16:49:01 -0700
Subject: [PATCH 030/106] Converted //overlay to visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 108 ++++++------------
1 file changed, 34 insertions(+), 74 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 7d29b1f06..04c44defc 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -27,16 +27,23 @@ import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.expression.Expression;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
+import com.sk89q.worldedit.function.FlatRegionMaskingFilter;
+import com.sk89q.worldedit.function.GroundFunction;
+import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockCount;
-import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
+import com.sk89q.worldedit.function.operation.OperationHelper;
+import com.sk89q.worldedit.function.util.RegionOffset;
+import com.sk89q.worldedit.function.visitor.DownwardVisitor;
+import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
+import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
+import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
import com.sk89q.worldedit.masks.*;
-import com.sk89q.worldedit.function.*;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.CuboidRegion;
@@ -51,10 +58,6 @@ import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.noise.RandomNoise;
-import com.sk89q.worldedit.function.visitor.DownwardVisitor;
-import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
-import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
-import com.sk89q.worldedit.function.visitor.RegionVisitor;
import java.util.*;
@@ -1128,87 +1131,44 @@ public class EditSession {
}
/**
- * Overlays a layer of blocks over a cuboid area.
+ * Places a layer of blocks on top of ground blocks in the given region
+ * (as if it were a cuboid).
*
- * @param region
- * @param block
+ * @param region the region
+ * @param block the placed block
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int overlayCuboidBlocks(Region region, BaseBlock block)
- throws MaxChangedBlocksException {
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
+ public int overlayCuboidBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
+ checkNotNull(block);
- int upperY = Math.min(world.getMaxY(), max.getBlockY() + 1);
- int lowerY = Math.max(0, min.getBlockY() - 1);
-
- int affected = 0;
-
- int minX = min.getBlockX();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int z = minZ; z <= maxZ; ++z) {
- for (int y = upperY; y >= lowerY; --y) {
- Vector above = new Vector(x, y + 1, z);
-
- if (y + 1 <= world.getMaxY() && !getBlock(new Vector(x, y, z)).isAir()
- && getBlock(above).isAir()) {
- if (setBlock(above, block)) {
- ++affected;
- }
- break;
- }
- }
- }
- }
-
- return affected;
+ return overlayCuboidBlocks(region, new SingleBlockPattern(block));
}
/**
- * Overlays a layer of blocks over a cuboid area.
+ * Places a layer of blocks on top of ground blocks in the given region
+ * (as if it were a cuboid).
*
- * @param region
- * @param pattern
+ * @param region the region
+ * @param pattern the placed block pattern
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int overlayCuboidBlocks(Region region, Pattern pattern)
- throws MaxChangedBlocksException {
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
+ public int overlayCuboidBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
+ checkNotNull(region);
+ checkNotNull(pattern);
- int upperY = Math.min(world.getMaxY(), max.getBlockY() + 1);
- int lowerY = Math.max(0, min.getBlockY() - 1);
+ int lowerY = region.getMinimumPoint().getBlockY();
+ int upperY = region.getMaximumPoint().getBlockY();
- int affected = 0;
+ BlockReplace replace = new BlockReplace(this, pattern);
+ RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
+ GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
+ GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, offset);
+ FlatRegionVisitor operation = new FlatRegionVisitor(region, groundFunction);
+ OperationHelper.completeLegacy(operation);
- int minX = min.getBlockX();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxZ = max.getBlockZ();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int z = minZ; z <= maxZ; ++z) {
- for (int y = upperY; y >= lowerY; --y) {
- Vector above = new Vector(x, y + 1, z);
-
- if (y + 1 <= world.getMaxY() && !getBlock(new Vector(x, y, z)).isAir()
- && getBlock(above).isAir()) {
- if (setBlock(above, pattern.next(above))) {
- ++affected;
- }
- break;
- }
- }
- }
- }
-
- return affected;
+ return operation.getAffected();
}
/**
From 11068cb69f9423301ec9a1fc2d4d02f0abc8fbf0 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:30:57 -0700
Subject: [PATCH 031/106] Added Regions class with utility methods.
---
.../com/sk89q/worldedit/regions/Regions.java | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/regions/Regions.java
diff --git a/src/main/java/com/sk89q/worldedit/regions/Regions.java b/src/main/java/com/sk89q/worldedit/regions/Regions.java
new file mode 100644
index 000000000..08bb58789
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/regions/Regions.java
@@ -0,0 +1,92 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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;
+
+/**
+ * Utility methods relating to {@link Region}s.
+ */
+public final class Regions {
+
+ private Regions() {
+ }
+
+ /**
+ * Get the minimum Y coordinate of the given region using the region's
+ * {@link Region#getMinimumPoint()} method.
+ *
+ * @param region the region
+ * @return the Y coordinate
+ */
+ public static double minimumY(Region region) {
+ return region.getMinimumPoint().getY();
+ }
+
+ /**
+ * Get the maximum Y coordinate of the given region using the region's
+ * {@link Region#getMaximumPoint()} method.
+ *
+ * @param region the region
+ * @return the Y coordinate
+ */
+ public static double maximumY(Region region) {
+ return region.getMaximumPoint().getY();
+ }
+
+ /**
+ * Get the minimum Y coordinate of the given region using the region's
+ * {@link Region#getMinimumPoint()} method.
+ *
+ * @param region the region
+ * @return the Y coordinate
+ */
+ public static int minimumBlockY(Region region) {
+ return region.getMinimumPoint().getBlockY();
+ }
+
+ /**
+ * Get the maximum Y coordinate of the given region using the region's
+ * {@link Region#getMaximumPoint()} method.
+ *
+ * @param region the region
+ * @return the Y coordinate
+ */
+ public static int maximumBlockY(Region region) {
+ return region.getMaximumPoint().getBlockY();
+ }
+
+ /**
+ * Attempt to get a {@link FlatRegion} from the given region.
+ *
+ * If the given region is already a {@link FlatRegion}, then the region
+ * will be cast and returned. Otherwise, a new {@link CuboidRegion} will
+ * be created covers the provided region's minimum and maximum extents.
+ *
+ * @param region the region
+ * @return a flat region
+ */
+ public static FlatRegion asFlatRegion(Region region) {
+ if (region instanceof FlatRegion) {
+ return (FlatRegion) region;
+ } else {
+ return CuboidRegion.makeCuboid(region);
+ }
+ }
+
+}
From 8b9cf95079bdde54a5bd23e25d4ccb02554c7d9a Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:31:07 -0700
Subject: [PATCH 032/106] Added DummyMask and DummyMask2D.
---
.../com/sk89q/worldedit/masks/DummyMask.java | 35 +++++++++++++++++++
.../sk89q/worldedit/masks/DummyMask2D.java | 35 +++++++++++++++++++
2 files changed, 70 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/masks/DummyMask.java
create mode 100644 src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java
diff --git a/src/main/java/com/sk89q/worldedit/masks/DummyMask.java b/src/main/java/com/sk89q/worldedit/masks/DummyMask.java
new file mode 100644
index 000000000..0b6ef5c8a
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/DummyMask.java
@@ -0,0 +1,35 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+
+/**
+ * A mask that only returns true
.
+ */
+public class DummyMask extends AbstractMask {
+
+ @Override
+ public boolean matches(EditSession editSession, Vector pos) {
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java b/src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java
new file mode 100644
index 000000000..cb1e3b19c
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java
@@ -0,0 +1,35 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector2D;
+
+/**
+ * A mask that only returns true
.
+ */
+public class DummyMask2D extends AbstractMask2D {
+
+ @Override
+ public boolean matches(EditSession editSession, Vector2D position) {
+ return true;
+ }
+
+}
From e13d5198be70b1e97625084fed6e386630e511d0 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:31:34 -0700
Subject: [PATCH 033/106] Added a BlockMask(BaseBlock... block) constructor.
---
.../com/sk89q/worldedit/masks/BlockMask.java | 21 +++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/masks/BlockMask.java b/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
index e852a9990..ee52d511a 100644
--- a/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
@@ -1,14 +1,15 @@
package com.sk89q.worldedit.masks;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
public class BlockMask extends AbstractMask {
+
private final Set blocks;
public BlockMask() {
@@ -19,6 +20,13 @@ public class BlockMask extends AbstractMask {
this.blocks = types;
}
+ public BlockMask(BaseBlock... block) {
+ blocks = new HashSet();
+ for (BaseBlock b : block) {
+ add(b);
+ }
+ }
+
public BlockMask(BaseBlock block) {
this();
add(block);
@@ -35,7 +43,8 @@ public class BlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
BaseBlock block = editSession.getBlock(pos);
- return blocks.contains(block)
+ return blocks.contains(block)
|| blocks.contains(new BaseBlock(block.getType(), -1));
- }
+ }
+
}
From af61efc4fb7b0b7eb4636f4dc6cb7c95ef3e8c08 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:31:53 -0700
Subject: [PATCH 034/106] Added LayerVisitor and LayerFunction.
---
.../worldedit/function/LayerFunction.java | 48 +++++++
.../function/visitor/LayerVisitor.java | 123 ++++++++++++++++++
2 files changed, 171 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/function/LayerFunction.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
diff --git a/src/main/java/com/sk89q/worldedit/function/LayerFunction.java b/src/main/java/com/sk89q/worldedit/function/LayerFunction.java
new file mode 100644
index 000000000..57f8fbab2
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/LayerFunction.java
@@ -0,0 +1,48 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+
+/**
+ * A function that accepts layers of blocks.
+ */
+public interface LayerFunction {
+
+ /**
+ * Returns whether the given block should be "passed through" when
+ * conducting the ground search.
+ *
+ * @param position return whether the given block is the ground
+ * @return true if the search should stop
+ */
+ boolean isGround(Vector position);
+
+ /**
+ * Apply the function to the given position.
+ *
+ * @param position the position
+ * @param depth the depth as a number starting from 0
+ * @return true whether this method should be called for further layers
+ * @throws com.sk89q.worldedit.WorldEditException thrown on an error
+ */
+ boolean apply(Vector position, int depth) throws WorldEditException;
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
new file mode 100644
index 000000000..759f12360
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
@@ -0,0 +1,123 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.visitor;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.Vector2D;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.function.LayerFunction;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.masks.DummyMask2D;
+import com.sk89q.worldedit.masks.Mask2D;
+import com.sk89q.worldedit.regions.FlatRegion;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Visits the layers within a region.
+ *
+ * This class works by iterating over all the columns in a {@link FlatRegion},
+ * finding the first ground block in each column (searching from a given
+ * maximum Y down to a minimum Y), and then applies a {@link LayerFunction} to
+ * each layer.
+ */
+public class LayerVisitor implements Operation {
+
+ private final FlatRegion flatRegion;
+ private final LayerFunction function;
+ private Mask2D mask = new DummyMask2D();
+ private int minY;
+ private int maxY;
+
+ /**
+ * Create a new visitor.
+ *
+ * @param flatRegion the flat region to visit
+ * @param minY the minimum Y to stop the search at
+ * @param maxY the maximum Y to begin the search at
+ * @param function the layer function to apply t blocks
+ */
+ public LayerVisitor(FlatRegion flatRegion, int minY, int maxY, LayerFunction function) {
+ checkNotNull(flatRegion);
+ checkArgument(minY <= maxY, "minY <= maxY required");
+ checkNotNull(function);
+
+ this.flatRegion = flatRegion;
+ this.minY = minY;
+ this.maxY = maxY;
+ this.function = function;
+ }
+
+ /**
+ * Get the mask that determines which columns within the flat region
+ * will be visited.
+ *
+ * @return a 2D mask
+ */
+ public Mask2D getMask() {
+ return mask;
+ }
+
+ /**
+ * Set the mask that determines which columns within the flat region
+ * will be visited.
+ *
+ * @param mask a 2D mask
+ */
+ public void setMask(Mask2D mask) {
+ checkNotNull(mask);
+ this.mask = mask;
+ }
+
+ @Override
+ public Operation resume() throws WorldEditException {
+ for (Vector2D column : flatRegion.asFlatRegion()) {
+ // Abort if we are underground
+ if (function.isGround(column.toVector(maxY + 1))) {
+ return null;
+ }
+
+ boolean found = false;
+ int groundY = 0;
+ for (int y = maxY; y >= minY; --y) {
+ Vector test = column.toVector(y);
+ if (!found) {
+ if (function.isGround(test)) {
+ found = true;
+ groundY = y;
+ }
+ }
+
+ if (found) {
+ if (!function.apply(test, groundY - y)) {
+ break;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void cancel() {
+ }
+}
From 69f3862c1115f6db4aa27e29f92a74ebb7d29a76 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:32:10 -0700
Subject: [PATCH 035/106] Converted //naturalize to visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 92 ++++---------------
.../worldedit/function/block/Naturalizer.java | 91 ++++++++++++++++++
2 files changed, 108 insertions(+), 75 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 04c44defc..cd7778c4f 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -32,24 +32,19 @@ import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockCount;
import com.sk89q.worldedit.function.block.BlockReplace;
+import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.util.RegionOffset;
-import com.sk89q.worldedit.function.visitor.DownwardVisitor;
-import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
-import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
-import com.sk89q.worldedit.function.visitor.RegionVisitor;
+import com.sk89q.worldedit.function.visitor.*;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
import com.sk89q.worldedit.masks.*;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
-import com.sk89q.worldedit.regions.CuboidRegion;
-import com.sk89q.worldedit.regions.EllipsoidRegion;
-import com.sk89q.worldedit.regions.Region;
-import com.sk89q.worldedit.regions.RegionOperationException;
+import com.sk89q.worldedit.regions.*;
import com.sk89q.worldedit.regions.search.GroundSearch;
import com.sk89q.worldedit.regions.search.MaskingGroundSearch;
import com.sk89q.worldedit.shape.ArbitraryBiomeShape;
@@ -63,6 +58,8 @@ import java.util.*;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
+import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
/**
* This class can wrap all block editing operations into one "edit session" that
@@ -236,9 +233,9 @@ public class EditSession {
}
}
}
-
+
boolean result;
-
+
if (type == 0) {
if (fastMode) {
result = world.setBlockTypeFast(pt, 0);
@@ -248,7 +245,7 @@ public class EditSession {
} else {
result = world.setBlock(pt, block, !fastMode);
}
-
+
return result;
}
@@ -1175,73 +1172,18 @@ public class EditSession {
* Turns the first 3 layers into dirt/grass and the bottom layers
* into rock, like a natural Minecraft mountain.
*
- * @param region
+ * @param region the region to affect
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int naturalizeCuboidBlocks(Region region)
- throws MaxChangedBlocksException {
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
+ public int naturalizeCuboidBlocks(Region region) throws MaxChangedBlocksException {
+ checkNotNull(region);
- int upperY = Math.min(world.getMaxY(), max.getBlockY() + 1);
- int lowerY = Math.max(0, min.getBlockY() - 1);
-
- int affected = 0;
-
- int minX = min.getBlockX();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxZ = max.getBlockZ();
-
- BaseBlock grass = new BaseBlock(BlockID.GRASS);
- BaseBlock dirt = new BaseBlock(BlockID.DIRT);
- BaseBlock stone = new BaseBlock(BlockID.STONE);
-
- for (int x = minX; x <= maxX; ++x) {
- for (int z = minZ; z <= maxZ; ++z) {
- int level = -1;
-
- for (int y = upperY; y >= lowerY; --y) {
- Vector pt = new Vector(x, y, z);
- //Vector above = new Vector(x, y + 1, z);
- int blockType = getBlockType(pt);
-
- boolean isTransformable =
- blockType == BlockID.GRASS
- || blockType == BlockID.DIRT
- || blockType == BlockID.STONE;
-
- // Still searching for the top block
- if (level == -1) {
- if (!isTransformable) {
- continue; // Not transforming this column yet
- }
-
- level = 0;
- }
-
- if (level >= 0) {
- if (isTransformable) {
- if (level == 0) {
- setBlock(pt, grass);
- affected++;
- } else if (level <= 2) {
- setBlock(pt, dirt);
- affected++;
- } else {
- setBlock(pt, stone);
- affected++;
- }
- }
-
- level++;
- }
- }
- }
- }
-
- return affected;
+ Naturalizer naturalizer = new Naturalizer(this);
+ FlatRegion flatRegion = Regions.asFlatRegion(region);
+ LayerVisitor visitor = new LayerVisitor(flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer);
+ OperationHelper.completeLegacy(visitor);
+ return naturalizer.getAffected();
}
/**
diff --git a/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java b/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java
new file mode 100644
index 000000000..b2143319b
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/block/Naturalizer.java
@@ -0,0 +1,91 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.block;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.blocks.BlockID;
+import com.sk89q.worldedit.function.LayerFunction;
+import com.sk89q.worldedit.masks.BlockMask;
+import com.sk89q.worldedit.masks.Mask;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Makes a layer of grass on top, three layers of dirt below, and smooth stone
+ * only below that for all layers that originally consist of grass, dirt,
+ * or smooth stone.
+ */
+public class Naturalizer implements LayerFunction {
+
+ private final EditSession editSession;
+ private final BaseBlock grass = new BaseBlock(BlockID.GRASS);
+ private final BaseBlock dirt = new BaseBlock(BlockID.DIRT);
+ private final BaseBlock stone = new BaseBlock(BlockID.STONE);
+ private final Mask mask = new BlockMask(grass, dirt, stone);
+ private int affected = 0;
+
+ /**
+ * Make a new naturalizer.
+ *
+ * @param editSession an edit session
+ */
+ public Naturalizer(EditSession editSession) {
+ checkNotNull(editSession);
+ this.editSession = editSession;
+ }
+
+ /**
+ * Get the number of affected objects.
+ *
+ * @return the number of affected
+ */
+ public int getAffected() {
+ return affected;
+ }
+
+ @Override
+ public boolean isGround(Vector position) {
+ return mask.matches(editSession, position);
+ }
+
+ @Override
+ public boolean apply(Vector position, int depth) throws WorldEditException {
+ if (mask.matches(editSession, position)) {
+ affected++;
+ switch (depth) {
+ case 0:
+ editSession.setBlock(position, grass);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ editSession.setBlock(position, dirt);
+ break;
+ default:
+ editSession.setBlock(position, stone);
+ }
+ }
+
+ return true;
+ }
+}
From c804aeb03efbda42193953f9df7d2624d571c313 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:34:34 -0700
Subject: [PATCH 036/106] Make FlatRegionVisitor take FlatRegions only.
---
.../java/com/sk89q/worldedit/EditSession.java | 4 ++--
.../worldedit/commands/RegionCommands.java | 4 ++--
.../function/visitor/FlatRegionVisitor.java | 24 +++++++++++--------
3 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index cd7778c4f..1f49bd86a 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -1162,7 +1162,7 @@ public class EditSession {
RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, offset);
- FlatRegionVisitor operation = new FlatRegionVisitor(region, groundFunction);
+ FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), groundFunction);
OperationHelper.completeLegacy(operation);
return operation.getAffected();
@@ -1966,7 +1966,7 @@ public class EditSession {
FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(this, mask, groundFunction);
// Generate those patches!
- FlatRegionVisitor operation = new FlatRegionVisitor(region, filter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), filter);
OperationHelper.completeLegacy(operation);
return operation.getAffected();
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index 15572c813..01a6ad7b1 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -561,7 +561,7 @@ public class RegionCommands {
FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(editSession, mask, groundFunction);
// Execute
- FlatRegionVisitor operation = new FlatRegionVisitor(region, filter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), filter);
OperationHelper.complete(operation);
player.print(operation.getAffected() + " trees created.");
@@ -591,7 +591,7 @@ public class RegionCommands {
FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(editSession, mask, groundFunction);
// Execute
- FlatRegionVisitor operation = new FlatRegionVisitor(region, filter);
+ FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), filter);
OperationHelper.complete(operation);
player.print(operation.getAffected() + " flora created.");
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
index 33a7dbb81..546dc0f2b 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/FlatRegionVisitor.java
@@ -23,12 +23,12 @@ import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.FlatRegionFunction;
import com.sk89q.worldedit.function.operation.Operation;
-import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.FlatRegion;
-import com.sk89q.worldedit.regions.Region;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
- * Utility class to apply region functions to {@link com.sk89q.worldedit.regions.Region}.
+ * Applies region functions to columns in a {@link FlatRegion}.
*/
public class FlatRegionVisitor implements Operation {
@@ -36,14 +36,18 @@ public class FlatRegionVisitor implements Operation {
private final FlatRegionFunction function;
private int affected = 0;
- public FlatRegionVisitor(Region region, FlatRegionFunction function) {
- this.function = function;
+ /**
+ * Create a new visitor.
+ *
+ * @param flatRegion a flat region
+ * @param function a function to apply to columns
+ */
+ public FlatRegionVisitor(FlatRegion flatRegion, FlatRegionFunction function) {
+ checkNotNull(flatRegion);
+ checkNotNull(function);
- if (region instanceof FlatRegion) {
- flatRegion = (FlatRegion) region;
- } else {
- flatRegion = CuboidRegion.makeCuboid(region);
- }
+ this.flatRegion = flatRegion;
+ this.function = function;
}
/**
From 3c5c257a4151dbf0c1d474ed17c5c9833e866fc3 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:51:33 -0700
Subject: [PATCH 037/106] Changed ground seeking operations to LayerVisitor.
---
.../java/com/sk89q/worldedit/EditSession.java | 78 ++++--------------
.../worldedit/commands/RegionCommands.java | 59 ++++++--------
.../worldedit/function/GroundFunction.java | 79 +++++++++++++------
.../function/visitor/LayerVisitor.java | 10 ++-
.../regions/search/AbstractGroundSearch.java | 76 ------------------
.../regions/search/GroundSearch.java | 47 -----------
.../regions/search/MaskingGroundSearch.java | 68 ----------------
7 files changed, 102 insertions(+), 315 deletions(-)
delete mode 100644 src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java
delete mode 100644 src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java
delete mode 100644 src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 1f49bd86a..3d9ecdd2e 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -45,8 +45,6 @@ import com.sk89q.worldedit.masks.*;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.*;
-import com.sk89q.worldedit.regions.search.GroundSearch;
-import com.sk89q.worldedit.regions.search.MaskingGroundSearch;
import com.sk89q.worldedit.shape.ArbitraryBiomeShape;
import com.sk89q.worldedit.shape.ArbitraryShape;
import com.sk89q.worldedit.shape.RegionShape;
@@ -58,6 +56,7 @@ import java.util.*;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
@@ -1155,17 +1154,13 @@ public class EditSession {
checkNotNull(region);
checkNotNull(pattern);
- int lowerY = region.getMinimumPoint().getBlockY();
- int upperY = region.getMaximumPoint().getBlockY();
-
BlockReplace replace = new BlockReplace(this, pattern);
RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
- GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
- GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, offset);
- FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), groundFunction);
- OperationHelper.completeLegacy(operation);
-
- return operation.getAffected();
+ GroundFunction ground = new GroundFunction(this, offset);
+ LayerVisitor visitor = new LayerVisitor(
+ this, asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ OperationHelper.completeLegacy(visitor);
+ return ground.getAffected();
}
/**
@@ -1181,7 +1176,8 @@ public class EditSession {
Naturalizer naturalizer = new Naturalizer(this);
FlatRegion flatRegion = Regions.asFlatRegion(region);
- LayerVisitor visitor = new LayerVisitor(flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer);
+ LayerVisitor visitor = new LayerVisitor(
+ this, flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer);
OperationHelper.completeLegacy(visitor);
return naturalizer.getAffected();
}
@@ -1948,28 +1944,18 @@ public class EditSession {
generator.setPlant(GardenPatchGenerator.getPumpkinPattern());
// In a region of the given radius
- Region region = new CuboidRegion(
+ FlatRegion region = new CuboidRegion(
getWorld(), // Causes clamping of Y range
position.add(-apothem, -5, -apothem),
position.add(apothem, 10, apothem));
-
- int lowerY = region.getMinimumPoint().getBlockY();
- int upperY = region.getMaximumPoint().getBlockY();
double density = 0.02;
- // We want to find the ground
- GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
- GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
-
- // We don't want to place a patch in every column
- Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
- FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(this, mask, groundFunction);
-
- // Generate those patches!
- FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), filter);
- OperationHelper.completeLegacy(operation);
-
- return operation.getAffected();
+ GroundFunction ground = new GroundFunction(this, generator);
+ LayerVisitor visitor = new LayerVisitor(
+ this, region, minimumBlockY(region), maximumBlockY(region), ground);
+ visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
+ OperationHelper.completeLegacy(visitor);
+ return ground.getAffected();
}
/**
@@ -2018,40 +2004,6 @@ public class EditSession {
return affected;
}
- /**
- * Makes a forest.
- *
- * @param it an iterator over the points within the region
- * @param upperY the Y to start from (upperY >= lowerY), inclusive
- * @param lowerY the Y to end at (upperY >= lowerY), inclusive
- * @param density density of the forest
- * @param treeGenerator the tree generator
- * @return number of trees created
- * @throws MaxChangedBlocksException
- * @deprecated Use {@link com.sk89q.worldedit.function.generator.ForestGenerator} with a
- * {@link com.sk89q.worldedit.function.visitor.FlatRegionVisitor}
- */
- @Deprecated
- public int makeForest(Iterable it, int upperY, int lowerY,
- double density, TreeGenerator treeGenerator)
- throws WorldEditException {
-
- ForestGenerator generator = new ForestGenerator(this, treeGenerator);
- GroundSearch search = new MaskingGroundSearch(this, new ExistingBlockMask());
- GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
- Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
- FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(this, mask, groundFunction);
-
- int affected = 0;
- for (Vector2D pt : it) {
- if (filter.apply(pt)) {
- affected++;
- }
- }
-
- return affected;
- }
-
/**
* Get the block distribution inside a region.
*
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index 01a6ad7b1..9ace6d32b 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -29,29 +29,28 @@ import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.filtering.GaussianKernel;
import com.sk89q.worldedit.filtering.HeightMapFilter;
+import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.generator.FloraGenerator;
import com.sk89q.worldedit.function.generator.ForestGenerator;
-import com.sk89q.worldedit.masks.ExistingBlockMask;
-import com.sk89q.worldedit.masks.Mask2D;
-import com.sk89q.worldedit.masks.NoiseFilter2D;
-import com.sk89q.worldedit.function.FlatRegionMaskingFilter;
-import com.sk89q.worldedit.function.GroundFunction;
-import com.sk89q.worldedit.regions.search.GroundSearch;
-import com.sk89q.worldedit.regions.search.MaskingGroundSearch;
-import com.sk89q.worldedit.util.noise.RandomNoise;
-import com.sk89q.worldedit.function.visitor.FlatRegionVisitor;
-import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.function.operation.OperationHelper;
+import com.sk89q.worldedit.function.visitor.LayerVisitor;
+import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.masks.NoiseFilter2D;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
-import com.sk89q.worldedit.regions.*;
+import com.sk89q.worldedit.regions.ConvexPolyhedralRegion;
+import com.sk89q.worldedit.regions.CuboidRegion;
+import com.sk89q.worldedit.regions.Region;
+import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.util.TreeGenerator;
+import com.sk89q.worldedit.util.noise.RandomNoise;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.sk89q.minecraft.util.commands.Logging.LogMode.*;
+import static com.sk89q.worldedit.regions.Regions.*;
/**
* Region related commands.
@@ -551,20 +550,13 @@ public class RegionCommands {
Region region = session.getSelection(player.getWorld());
ForestGenerator generator = new ForestGenerator(editSession, new TreeGenerator(type));
+ GroundFunction ground = new GroundFunction(editSession, generator);
+ LayerVisitor visitor = new LayerVisitor(
+ editSession, asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
+ OperationHelper.completeLegacy(visitor);
- int lowerY = region.getMinimumPoint().getBlockY();
- int upperY = region.getMaximumPoint().getBlockY();
-
- GroundSearch search = new MaskingGroundSearch(editSession, new ExistingBlockMask());
- GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
- Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
- FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(editSession, mask, groundFunction);
-
- // Execute
- FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), filter);
- OperationHelper.complete(operation);
-
- player.print(operation.getAffected() + " trees created.");
+ player.print(ground.getAffected() + " trees created.");
}
@Command(
@@ -581,20 +573,13 @@ public class RegionCommands {
Region region = session.getSelection(player.getWorld());
FloraGenerator generator = new FloraGenerator(editSession);
+ GroundFunction ground = new GroundFunction(editSession, generator);
+ LayerVisitor visitor = new LayerVisitor(
+ editSession, asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
+ OperationHelper.completeLegacy(visitor);
- int lowerY = region.getMinimumPoint().getBlockY();
- int upperY = region.getMaximumPoint().getBlockY();
-
- GroundSearch search = new MaskingGroundSearch(editSession, new ExistingBlockMask());
- GroundFunction groundFunction = new GroundFunction(search, lowerY, upperY, generator);
- Mask2D mask = new NoiseFilter2D(new RandomNoise(), density);
- FlatRegionMaskingFilter filter = new FlatRegionMaskingFilter(editSession, mask, groundFunction);
-
- // Execute
- FlatRegionVisitor operation = new FlatRegionVisitor(Regions.asFlatRegion(region), filter);
- OperationHelper.complete(operation);
-
- player.print(operation.getAffected() + " flora created.");
+ player.print(ground.getAffected() + " flora created.");
}
}
diff --git a/src/main/java/com/sk89q/worldedit/function/GroundFunction.java b/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
index ced5546ff..ee7af86ba 100644
--- a/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
+++ b/src/main/java/com/sk89q/worldedit/function/GroundFunction.java
@@ -19,46 +19,79 @@
package com.sk89q.worldedit.function;
+import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.regions.search.GroundSearch;
+import com.sk89q.worldedit.masks.ExistingBlockMask;
+import com.sk89q.worldedit.masks.Mask;
-import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
- * Accepts 2D coordinates to columns, finds the first ground block in each
- * column, and applies the given {@link RegionFunction} onto the ground blocks.
+ * Applies a {@link RegionFunction} to the first ground block.
*/
-public class GroundFunction implements FlatRegionFunction {
+public class GroundFunction implements LayerFunction {
+ private final EditSession editSession;
private final RegionFunction function;
- private GroundSearch groundSearch;
- private int minY;
- private int maxY;
+ private Mask mask = new ExistingBlockMask();
+ private int affected;
/**
- * Create a new instance.
+ * Create a new ground function.
*
- * @param groundSearch the ground search implementation
- * @param minY the minimum Y (inclusive)
- * @param maxY the maximum Y (inclusive)
- * @param function the function to apply on ground blocks
+ * @param editSession an edit session
+ * @param function the function to apply
*/
- public GroundFunction(GroundSearch groundSearch, int minY, int maxY, RegionFunction function) {
+ public GroundFunction(EditSession editSession, RegionFunction function) {
+ checkNotNull(editSession);
checkNotNull(function);
- checkNotNull(groundSearch);
- checkArgument(minY <= maxY, "minY <= maxY required");
+ this.editSession = editSession;
this.function = function;
- this.groundSearch = groundSearch;
- this.minY = minY;
- this.maxY = maxY;
+ }
+
+ /**
+ * Get the mask that determines what the ground consists of.
+ *
+ * @return a mask
+ */
+ public Mask getMask() {
+ return mask;
+ }
+
+ /**
+ * Set the mask that determines what the ground consists of.
+ *
+ * @param mask a mask
+ */
+ public void setMask(Mask mask) {
+ checkNotNull(mask);
+ this.mask = mask;
+ }
+
+ /**
+ * Get the number of affected objects.
+ *
+ * @return the number of affected
+ */
+ public int getAffected() {
+ return affected;
}
@Override
- public boolean apply(Vector2D pt) throws WorldEditException {
- Vector ground = groundSearch.findGround(pt.toVector(maxY), minY);
- return ground != null && function.apply(ground);
+ public boolean isGround(Vector position) {
+ return mask.matches(editSession, position);
}
+
+ @Override
+ public boolean apply(Vector position, int depth) throws WorldEditException {
+ if (depth == 0) {
+ if (function.apply(position)) {
+ affected++;
+ }
+ }
+
+ return false;
+ }
+
}
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
index 759f12360..3872f4f4a 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
@@ -19,6 +19,7 @@
package com.sk89q.worldedit.function.visitor;
+import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
@@ -41,6 +42,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class LayerVisitor implements Operation {
+ private final EditSession editSession;
private final FlatRegion flatRegion;
private final LayerFunction function;
private Mask2D mask = new DummyMask2D();
@@ -55,11 +57,13 @@ public class LayerVisitor implements Operation {
* @param maxY the maximum Y to begin the search at
* @param function the layer function to apply t blocks
*/
- public LayerVisitor(FlatRegion flatRegion, int minY, int maxY, LayerFunction function) {
+ public LayerVisitor(EditSession editSession, FlatRegion flatRegion, int minY, int maxY, LayerFunction function) {
+ checkNotNull(editSession);
checkNotNull(flatRegion);
checkArgument(minY <= maxY, "minY <= maxY required");
checkNotNull(function);
+ this.editSession = editSession;
this.flatRegion = flatRegion;
this.minY = minY;
this.maxY = maxY;
@@ -90,6 +94,10 @@ public class LayerVisitor implements Operation {
@Override
public Operation resume() throws WorldEditException {
for (Vector2D column : flatRegion.asFlatRegion()) {
+ if (!mask.matches(editSession, column)) {
+ continue;
+ }
+
// Abort if we are underground
if (function.isGround(column.toVector(maxY + 1))) {
return null;
diff --git a/src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java b/src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java
deleted file mode 100644
index 94ca881b9..000000000
--- a/src/main/java/com/sk89q/worldedit/regions/search/AbstractGroundSearch.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * 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 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.search;
-
-import com.sk89q.worldedit.Vector;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static net.minecraft.util.com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Utility class for finding the first ground block starting from a certain
- * position and traversing down.
- */
-public abstract class AbstractGroundSearch implements GroundSearch {
-
- /**
- * Returns whether the given block should be "passed through" when
- * conducting the ground search.
- *
- * @param position return whether the given block is the ground
- * @return true if the search should stop
- */
- protected abstract boolean isGround(Vector position);
-
- /**
- * Find the ground block starting from the given position and traversing
- * downward until reaching minY (inclusive).
- *
- * The highest ground block that may be returned is at the location of
- * the origin location. The lowest ground block that may be returned is
- * in the same column as the origin but with y = minY.
- *
- * It is possible for no ground block to be found if the given origin
- * block is underground to begin with.
- *
- * @param origin the origin
- * @param minY the minimum Y to end the search at
- * @return the location of a ground block, or null if none was found
- */
- public Vector findGround(Vector origin, int minY) {
- checkNotNull(origin);
- checkArgument(minY <= origin.getBlockY(), "minY <= origin Y");
-
- // Don't want to be in the ground
- if (isGround(origin.add(0, 1, 0))) {
- return null;
- }
-
- for (int y = origin.getBlockY() + 1; y >= minY; --y) {
- Vector test = origin.setY(y);
- if (isGround(test)) {
- return test;
- }
- }
-
- return null;
- }
-
-}
diff --git a/src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java b/src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java
deleted file mode 100644
index 0f0aa3ada..000000000
--- a/src/main/java/com/sk89q/worldedit/regions/search/GroundSearch.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * 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 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.search;
-
-import com.sk89q.worldedit.Vector;
-
-/**
- * Given a column of blocks in the world, finds the first ground block
- * starting from a given Y.
- */
-public interface GroundSearch {
-
- /**
- * Find the ground block starting from the given position and traversing
- * downward until reaching minY (inclusive).
- *
- * The highest ground block that may be returned is at the location of
- * the origin location. The lowest ground block that may be returned is
- * in the same column as the origin but with y = minY.
- *
- * It is possible for no ground block to be found if the given origin
- * block is underground.
- *
- * @param origin the origin
- * @param minY the minimum Y to end the search at
- * @return the location of a ground block, or null if none was found
- */
- Vector findGround(Vector origin, int minY);
-
-}
diff --git a/src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java b/src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java
deleted file mode 100644
index 27c196c22..000000000
--- a/src/main/java/com/sk89q/worldedit/regions/search/MaskingGroundSearch.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * 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 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.search;
-
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.masks.Mask;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * A ground finder that uses a {@link com.sk89q.worldedit.masks.Mask} to determine
- * ground blocks.
- */
-public class MaskingGroundSearch extends AbstractGroundSearch {
-
- private final EditSession editSession;
- private final Mask mask;
-
- /**
- * Create a new instance.
- *
- * If a mask that matches non-ground blocks is available, it can be inverted with
- * {@link com.sk89q.worldedit.masks.InvertedMask}.
- *
- * @param editSession an edit session
- * @param mask a mask that matches ground blocks
- */
- public MaskingGroundSearch(EditSession editSession, Mask mask) {
- checkNotNull(editSession);
- checkNotNull(mask);
-
- this.editSession = editSession;
- this.mask = mask;
- }
-
- /**
- * Get the mask that matches ground blocks.
- *
- * @return the mask
- */
- public Mask getMask() {
- return mask;
- }
-
- @Override
- protected boolean isGround(Vector position) {
- return mask.matches(editSession, position);
- }
-
-}
From 70f409975e37e964aeb0eb2107a0eeaeda55bee4 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 21:05:09 -0700
Subject: [PATCH 038/106] Added support for Extent interface.
---
.../java/com/sk89q/worldedit/EditSession.java | 18 +++--
src/main/java/com/sk89q/worldedit/Extent.java | 77 +++++++++++++++++++
.../java/com/sk89q/worldedit/LocalWorld.java | 25 +++---
3 files changed, 98 insertions(+), 22 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/Extent.java
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 3d9ecdd2e..7ee9fbc94 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -27,17 +27,18 @@ import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.expression.Expression;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
-import com.sk89q.worldedit.function.FlatRegionMaskingFilter;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockCount;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer;
-import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.util.RegionOffset;
-import com.sk89q.worldedit.function.visitor.*;
+import com.sk89q.worldedit.function.visitor.DownwardVisitor;
+import com.sk89q.worldedit.function.visitor.LayerVisitor;
+import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
+import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
@@ -56,9 +57,7 @@ import java.util.*;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.sk89q.worldedit.regions.Regions.asFlatRegion;
-import static com.sk89q.worldedit.regions.Regions.maximumBlockY;
-import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
+import static com.sk89q.worldedit.regions.Regions.*;
/**
* This class can wrap all block editing operations into one "edit session" that
@@ -70,7 +69,7 @@ import static com.sk89q.worldedit.regions.Regions.minimumBlockY;
*
* @author sk89q
*/
-public class EditSession {
+public class EditSession implements Extent {
/**
* Random number generator.
@@ -248,6 +247,11 @@ public class EditSession {
return result;
}
+ @Override
+ public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) {
+ return setBlock(location, block, true);
+ }
+
/**
* Sets the block at position x, y, z with a block type. If queue mode is
* enabled, blocks may not be actually set in world until flushQueue() is
diff --git a/src/main/java/com/sk89q/worldedit/Extent.java b/src/main/java/com/sk89q/worldedit/Extent.java
new file mode 100644
index 000000000..4959e9e91
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/Extent.java
@@ -0,0 +1,77 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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;
+
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * A world, portion of a world, clipboard, or other object that can have blocks set or
+ * entities placed.
+ */
+public interface Extent {
+
+ /**
+ * Get a copy of the block at the given location. May return null if the location
+ * given is out of bounds. The returned block must not be tied to any real block
+ * in the world, so changes to the returned {@link BaseBlock} have no effect until
+ * {@link #setBlock(Vector, BaseBlock)} is called.
+ *
+ * @param location location of the block
+ * @return the block, or null if the block does not exist
+ */
+ BaseBlock getBlock(Vector location);
+
+ /**
+ * Get the block ID at the given location.
+ *
+ * @param location location of the block
+ * @return the block ID
+ */
+ int getBlockType(Vector location);
+
+ /**
+ * Get the data value of the block at the given location.
+ *
+ * @param location the location of the block
+ * @return the block data value
+ */
+ int getBlockData(Vector location);
+
+ /**
+ * Change the block at the given location to the given block. The operation may
+ * not tie the given {@link BaseBlock} to the world, so future changes to the
+ * {@link BaseBlock} do not affect the world until this method is called again.
+ *
+ * The return value of this method indicates whether the change "went through," as
+ * in the block was changed in the world in any way. If the new block is no different
+ * than the block already at the position in the world, 'false' would be returned.
+ * If the position is invalid (out of bounds, for example), then nothing should
+ * occur and 'false' should be returned. If possible, the return value should be
+ * accurate as possible, but implementations may choose to not provide an accurate
+ * value if it is not possible to know.
+ *
+ * @param location location of the block
+ * @param block block to set
+ * @param notifyAdjacent true to notify adjacent blocks of changes
+ * @return true if the block was successfully set (return value may not be accurate)
+ */
+ boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent);
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/LocalWorld.java b/src/main/java/com/sk89q/worldedit/LocalWorld.java
index 449faa681..6b77884e1 100644
--- a/src/main/java/com/sk89q/worldedit/LocalWorld.java
+++ b/src/main/java/com/sk89q/worldedit/LocalWorld.java
@@ -19,31 +19,21 @@
package com.sk89q.worldedit;
-import java.util.PriorityQueue;
-import java.util.Random;
-
-import com.sk89q.worldedit.blocks.BaseBlock;
-import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.blocks.BlockType;
-import com.sk89q.worldedit.blocks.ChestBlock;
-import com.sk89q.worldedit.blocks.DispenserBlock;
-import com.sk89q.worldedit.blocks.FurnaceBlock;
-import com.sk89q.worldedit.blocks.MobSpawnerBlock;
-import com.sk89q.worldedit.blocks.NoteBlock;
-import com.sk89q.worldedit.blocks.SignBlock;
-import com.sk89q.worldedit.blocks.SkullBlock;
+import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.foundation.Block;
import com.sk89q.worldedit.foundation.World;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
+import java.util.PriorityQueue;
+import java.util.Random;
+
/**
* Represents a world.
*
* @author sk89q
*/
-public abstract class LocalWorld implements World {
+public abstract class LocalWorld implements World, Extent {
/**
* Named flags to use as parameters to {@link LocalWorld#killMobs(Vector, double, int)}
*/
@@ -528,6 +518,11 @@ public abstract class LocalWorld implements World {
public int killEntities(LocalEntity... entities) {
return 0;
}
+
+ @Override
+ public boolean setBlock(Vector pt, BaseBlock block, boolean notifyAdjacent) {
+ return setBlock(pt, (Block) block, notifyAdjacent);
+ }
@Override
public boolean setBlock(Vector pt, Block block, boolean notifyAdjacent) {
From e7bbd1ac53d35384ac227e2f28ef17cfae33d8f9 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 21:07:02 -0700
Subject: [PATCH 039/106] Made some masks use Extents rather than EditSessions.
---
.../com/sk89q/worldedit/masks/BlockMask.java | 6 +-
.../worldedit/masks/ExistingBlockMask.java | 4 +-
.../worldedit/masks/ExtentAwareMask.java | 71 +++++++++++++++++++
.../sk89q/worldedit/masks/FuzzyBlockMask.java | 6 +-
.../java/com/sk89q/worldedit/masks/Mask.java | 4 +-
.../sk89q/worldedit/masks/SolidBlockMask.java | 6 +-
.../worldedit/masks/UnderOverlayMask.java | 10 ++-
7 files changed, 91 insertions(+), 16 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java
diff --git a/src/main/java/com/sk89q/worldedit/masks/BlockMask.java b/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
index ee52d511a..692501ad7 100644
--- a/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
@@ -1,6 +1,7 @@
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
@@ -8,7 +9,7 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
-public class BlockMask extends AbstractMask {
+public class BlockMask extends ExtentAwareMask {
private final Set blocks;
@@ -42,7 +43,8 @@ public class BlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- BaseBlock block = editSession.getBlock(pos);
+ Extent extent = getExtent(editSession);
+ BaseBlock block = extent.getBlock(pos);
return blocks.contains(block)
|| blocks.contains(new BaseBlock(block.getType(), -1));
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java
index ea9e8f448..8a536195f 100644
--- a/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java
@@ -23,9 +23,9 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
-public class ExistingBlockMask extends AbstractMask {
+public class ExistingBlockMask extends ExtentAwareMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- return editSession.getBlockType(pos) != BlockID.AIR;
+ return getExtent(editSession).getBlockType(pos) != BlockID.AIR;
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java b/src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java
new file mode 100644
index 000000000..4b86f9d25
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java
@@ -0,0 +1,71 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.masks;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Extent;
+
+/**
+ * Extended by masks to make them potentially use an {@link Extent} rather than
+ * the {@link EditSession}.
+ *
+ * At the moment, masks are coupled to {@link EditSession} when they should
+ * not be. However, because a change to {@link Mask} would cause massive breakage in
+ * the API, that change is deferred until further notice and this class exists as
+ * an opt-in mixin for adding support for {@link Extent}s.
+ */
+public abstract class ExtentAwareMask extends AbstractMask {
+
+ private Extent extent;
+
+ /**
+ * Get the extent that will be used for lookups.
+ *
+ * @return the extent, or null if the {@link EditSession} is to be used
+ */
+ public Extent getExtent() {
+ return extent;
+ }
+
+ /**
+ * Set the extent that will be used for lookups.
+ *
+ * @param extent the extent, or null if the {@link EditSession} is to be used
+ */
+ public void setExtent(Extent extent) {
+ this.extent = extent;
+ }
+
+ /**
+ * Get the extent to use for operations. Subclasses should call this method
+ * rather than access the passed {@link EditSession} directly.
+ *
+ * @param editSession the passed in {@link EditSession}
+ * @return an extent
+ */
+ protected Extent getExtent(EditSession editSession) {
+ if (extent != null) {
+ return extent;
+ } else {
+ return editSession;
+ }
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
index 4b34aab89..fe35ec30f 100644
--- a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
@@ -20,6 +20,7 @@
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
@@ -30,7 +31,7 @@ import java.util.Set;
* Uses {@link BaseBlock#containsFuzzy(java.util.Collection, BaseBlock)} to
* match blocks.
*/
-public class FuzzyBlockMask extends AbstractMask {
+public class FuzzyBlockMask extends ExtentAwareMask {
private final Set filter;
@@ -58,7 +59,8 @@ public class FuzzyBlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- BaseBlock compare = new BaseBlock(editSession.getBlockType(pos), editSession.getBlockData(pos));
+ Extent extent = getExtent(editSession);
+ BaseBlock compare = new BaseBlock(extent.getBlockType(pos), extent.getBlockData(pos));
return BaseBlock.containsFuzzy(filter, compare);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/Mask.java b/src/main/java/com/sk89q/worldedit/masks/Mask.java
index d5a448736..ce18cbece 100644
--- a/src/main/java/com/sk89q/worldedit/masks/Mask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/Mask.java
@@ -48,8 +48,8 @@ public interface Mask {
* that position matches the filter. Block information is not provided
* as getting a BaseBlock has unneeded overhead in most block querying
* situations (enumerating a chest's contents is a waste, for example).
- *
- * @param editSession
+ *
+ * @param editSession
* @param pos
* @return
*/
diff --git a/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java
index f78170efc..9414cfaf8 100644
--- a/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java
@@ -1,15 +1,17 @@
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType;
/**
* Works like {@link ExistingBlockMask}, except also dealing with non-solid non-air blocks the same way as with air.
*/
-public class SolidBlockMask extends AbstractMask {
+public class SolidBlockMask extends ExtentAwareMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- return !BlockType.canPassThrough(editSession.getBlockType(pos), editSession.getBlockData(pos));
+ Extent extent = getExtent(editSession);
+ return !BlockType.canPassThrough(extent.getBlockType(pos), extent.getBlockData(pos));
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java b/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java
index 7c77a75da..d7cf29da9 100644
--- a/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java
@@ -21,17 +21,14 @@ package com.sk89q.worldedit.masks;
import java.util.Set;
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.LocalPlayer;
-import com.sk89q.worldedit.LocalSession;
-import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
*
* @author 1337
*/
-public class UnderOverlayMask extends AbstractMask {
+public class UnderOverlayMask extends ExtentAwareMask {
private final int yMod;
private Mask mask;
@@ -68,6 +65,7 @@ public class UnderOverlayMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- return !mask.matches(editSession, pos) && mask.matches(editSession, pos.add(0, yMod, 0));
+ Extent extent = getExtent(editSession);
+ return !mask.matches(extent, pos) && mask.matches(extent, pos.add(0, yMod, 0));
}
}
From e657fd5be98ee0d6429c00cb900e2f3e5e36f2e0 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 21:08:03 -0700
Subject: [PATCH 040/106] Moved noise classes to worldedit.math.* package.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 2 +-
src/main/java/com/sk89q/worldedit/commands/RegionCommands.java | 2 +-
src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java | 2 +-
src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java | 2 +-
.../sk89q/worldedit/{util => math}/noise/NoiseGenerator.java | 2 +-
.../com/sk89q/worldedit/{util => math}/noise/RandomNoise.java | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
rename src/main/java/com/sk89q/worldedit/{util => math}/noise/NoiseGenerator.java (97%)
rename src/main/java/com/sk89q/worldedit/{util => math}/noise/RandomNoise.java (97%)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 7ee9fbc94..4963ae0db 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -51,7 +51,7 @@ import com.sk89q.worldedit.shape.ArbitraryShape;
import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator;
-import com.sk89q.worldedit.util.noise.RandomNoise;
+import com.sk89q.worldedit.math.noise.RandomNoise;
import java.util.*;
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index 9ace6d32b..141c39744 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -43,7 +43,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.util.TreeGenerator;
-import com.sk89q.worldedit.util.noise.RandomNoise;
+import com.sk89q.worldedit.math.noise.RandomNoise;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
index 4913704bd..6c5e586a2 100644
--- a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
+++ b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
@@ -21,7 +21,7 @@ package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.util.noise.NoiseGenerator;
+import com.sk89q.worldedit.math.noise.NoiseGenerator;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
index 4f6290957..2071ce000 100644
--- a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
+++ b/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
@@ -21,7 +21,7 @@ package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector2D;
-import com.sk89q.worldedit.util.noise.NoiseGenerator;
+import com.sk89q.worldedit.math.noise.NoiseGenerator;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/src/main/java/com/sk89q/worldedit/util/noise/NoiseGenerator.java b/src/main/java/com/sk89q/worldedit/math/noise/NoiseGenerator.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/util/noise/NoiseGenerator.java
rename to src/main/java/com/sk89q/worldedit/math/noise/NoiseGenerator.java
index a16271056..bd331fd0c 100644
--- a/src/main/java/com/sk89q/worldedit/util/noise/NoiseGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/math/noise/NoiseGenerator.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.util.noise;
+package com.sk89q.worldedit.math.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
diff --git a/src/main/java/com/sk89q/worldedit/util/noise/RandomNoise.java b/src/main/java/com/sk89q/worldedit/math/noise/RandomNoise.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/util/noise/RandomNoise.java
rename to src/main/java/com/sk89q/worldedit/math/noise/RandomNoise.java
index 87da1d03d..936323c16 100644
--- a/src/main/java/com/sk89q/worldedit/util/noise/RandomNoise.java
+++ b/src/main/java/com/sk89q/worldedit/math/noise/RandomNoise.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.util.noise;
+package com.sk89q.worldedit.math.noise;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
From 9ab1d0f1509e60446f0db98523ac58200ab65d41 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 21:30:48 -0700
Subject: [PATCH 041/106] Fixed UnderOverlayMask not really supporting Extent.
---
.../sk89q/worldedit/masks/UnderOverlayMask.java | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java b/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java
index d7cf29da9..e2e0216ae 100644
--- a/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/UnderOverlayMask.java
@@ -19,16 +19,19 @@
package com.sk89q.worldedit.masks;
-import java.util.Set;
-
-import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.LocalPlayer;
+import com.sk89q.worldedit.LocalSession;
+import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
+import java.util.Set;
+
/**
*
* @author 1337
*/
-public class UnderOverlayMask extends ExtentAwareMask {
+public class UnderOverlayMask extends AbstractMask {
private final int yMod;
private Mask mask;
@@ -65,7 +68,6 @@ public class UnderOverlayMask extends ExtentAwareMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- Extent extent = getExtent(editSession);
- return !mask.matches(extent, pos) && mask.matches(extent, pos.add(0, yMod, 0));
+ return !mask.matches(editSession, pos) && mask.matches(editSession, pos.add(0, yMod, 0));
}
}
From 9113cd4bd3d836bedf525d18fa324c8c902d00eb Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 01:36:02 -0700
Subject: [PATCH 042/106] Added new Mask interface and deprecated old one.
---
.../java/com/sk89q/worldedit/EditSession.java | 21 ++--
.../worldedit/commands/RegionCommands.java | 2 +-
.../function/FlatRegionMaskingFilter.java | 11 +-
.../function/RegionMaskingFilter.java | 12 +-
.../function/mask/AbstractExtentMask.java | 61 ++++++++++
.../mask/AbstractMask.java} | 19 +--
.../mask}/AbstractMask2D.java | 4 +-
.../worldedit/function/mask/BlockMask.java | 99 +++++++++++++++
.../mask/BoundedHeightMask.java} | 27 +++--
.../function/mask/ExistingBlockMask.java | 46 +++++++
.../function/mask/FuzzyBlockMask.java | 45 +++++++
.../mask/Mask.java} | 18 +--
.../mask/Mask2D.java} | 18 +--
.../function/mask/MaskIntersection.java | 102 ++++++++++++++++
.../worldedit/function/mask/MaskUnion.java | 64 ++++++++++
.../sk89q/worldedit/function/mask/Masks.java | 113 ++++++++++++++++++
.../{masks => function/mask}/NoiseFilter.java | 7 +-
.../mask}/NoiseFilter2D.java | 5 +-
.../worldedit/function/mask/RegionMask.java | 67 +++++++++++
.../function/mask/SolidBlockMask.java | 38 ++++++
.../function/visitor/DownwardVisitor.java | 2 +-
.../function/visitor/LayerVisitor.java | 8 +-
.../function/visitor/RecursiveVisitor.java | 4 +-
.../sk89q/worldedit/masks/AbstractMask.java | 5 +
.../com/sk89q/worldedit/masks/BlockMask.java | 10 +-
.../sk89q/worldedit/masks/CombinedMask.java | 5 +
.../worldedit/masks/DynamicRegionMask.java | 2 +-
.../worldedit/masks/ExistingBlockMask.java | 8 +-
.../worldedit/masks/ExtentAwareMask.java | 71 -----------
.../sk89q/worldedit/masks/FuzzyBlockMask.java | 10 +-
.../sk89q/worldedit/masks/InvertedMask.java | 5 +
.../java/com/sk89q/worldedit/masks/Mask.java | 8 +-
.../com/sk89q/worldedit/masks/RandomMask.java | 5 +
.../com/sk89q/worldedit/masks/RegionMask.java | 4 +
.../sk89q/worldedit/masks/SolidBlockMask.java | 9 +-
35 files changed, 753 insertions(+), 182 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java
rename src/main/java/com/sk89q/worldedit/{masks/Mask2D.java => function/mask/AbstractMask.java} (62%)
rename src/main/java/com/sk89q/worldedit/{masks => function/mask}/AbstractMask2D.java (88%)
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
rename src/main/java/com/sk89q/worldedit/{masks/BoundedYMask.java => function/mask/BoundedHeightMask.java} (59%)
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java
rename src/main/java/com/sk89q/worldedit/{masks/DummyMask.java => function/mask/Mask.java} (73%)
rename src/main/java/com/sk89q/worldedit/{masks/DummyMask2D.java => function/mask/Mask2D.java} (73%)
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/Masks.java
rename src/main/java/com/sk89q/worldedit/{masks => function/mask}/NoiseFilter.java (92%)
rename src/main/java/com/sk89q/worldedit/{masks => function/mask}/NoiseFilter2D.java (94%)
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
delete mode 100644 src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 4963ae0db..342ed68f8 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -33,6 +33,7 @@ import com.sk89q.worldedit.function.block.BlockCount;
import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
+import com.sk89q.worldedit.function.mask.*;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
@@ -42,7 +43,8 @@ import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.interpolation.Interpolation;
import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
-import com.sk89q.worldedit.masks.*;
+import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.*;
@@ -51,7 +53,6 @@ import com.sk89q.worldedit.shape.ArbitraryShape;
import com.sk89q.worldedit.shape.RegionShape;
import com.sk89q.worldedit.shape.WorldEditExpressionEnvironment;
import com.sk89q.worldedit.util.TreeGenerator;
-import com.sk89q.worldedit.math.noise.RandomNoise;
import java.util.*;
@@ -559,9 +560,9 @@ public class EditSession implements Extent {
* @return the number of blocks that matched the pattern
*/
public int countBlocks(Region region, Set searchBlocks) {
- FuzzyBlockMask mask = new FuzzyBlockMask(searchBlocks);
+ FuzzyBlockMask mask = new FuzzyBlockMask(this, searchBlocks);
BlockCount count = new BlockCount();
- RegionMaskingFilter filter = new RegionMaskingFilter(this, mask, count);
+ RegionMaskingFilter filter = new RegionMaskingFilter(mask, count);
RegionVisitor visitor = new RegionVisitor(region, filter);
OperationHelper.completeBlindly(visitor); // We can't throw exceptions, nor do we expect any
return count.getCount();
@@ -819,10 +820,10 @@ public class EditSession implements Extent {
checkArgument(radius >= 0, "radius >= 0");
checkArgument(depth >= 1, "depth >= 1");
- CombinedMask mask = new CombinedMask(
+ MaskIntersection mask = new MaskIntersection(
new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))),
- new BoundedYMask(origin.getBlockY() - depth + 1, origin.getBlockY()),
- new InvertedMask(new ExistingBlockMask()));
+ new BoundedHeightMask(origin.getBlockY() - depth + 1, origin.getBlockY()),
+ Masks.negate(new ExistingBlockMask(this)));
// Want to replace blocks
BlockReplace replace = new BlockReplace(this, pattern);
@@ -901,7 +902,7 @@ public class EditSession implements Extent {
checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
- Mask mask = new FuzzyBlockMask(new BaseBlock(blockType, -1));
+ Mask mask = new com.sk89q.worldedit.masks.FuzzyBlockMask(new BaseBlock(blockType, -1));
Vector adjustment = new Vector(1, 1, 1).multiply(apothem - 1);
Region region = new CuboidRegion(
getWorld(), // Causes clamping of Y range
@@ -966,7 +967,7 @@ public class EditSession implements Extent {
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException {
- Mask mask = filter == null ? new ExistingBlockMask() : new FuzzyBlockMask(filter);
+ Mask mask = filter == null ? new com.sk89q.worldedit.masks.ExistingBlockMask() : new com.sk89q.worldedit.masks.FuzzyBlockMask(filter);
return replaceBlocks(region, mask, pattern);
}
@@ -986,7 +987,7 @@ public class EditSession implements Extent {
checkNotNull(pattern);
BlockReplace replace = new BlockReplace(this, pattern);
- RegionMaskingFilter filter = new RegionMaskingFilter(this, mask, replace);
+ RegionMaskingFilter filter = new RegionMaskingFilter(Masks.wrap(this, mask), replace);
RegionVisitor visitor = new RegionVisitor(region, filter);
OperationHelper.completeLegacy(visitor);
return visitor.getAffected();
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index 141c39744..bc72cdb3d 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -35,7 +35,7 @@ import com.sk89q.worldedit.function.generator.ForestGenerator;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.masks.Mask;
-import com.sk89q.worldedit.masks.NoiseFilter2D;
+import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.ConvexPolyhedralRegion;
diff --git a/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java b/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
index e6bf41fba..df28989a5 100644
--- a/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
+++ b/src/main/java/com/sk89q/worldedit/function/FlatRegionMaskingFilter.java
@@ -19,10 +19,9 @@
package com.sk89q.worldedit.function;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.masks.Mask2D;
+import com.sk89q.worldedit.function.mask.Mask2D;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -33,30 +32,26 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class FlatRegionMaskingFilter implements FlatRegionFunction {
- private final EditSession editSession;
private final FlatRegionFunction function;
private Mask2D mask;
/**
* Create a new masking filter.
*
- * @param editSession the edit session
* @param mask the mask
* @param function the delegate function to call
*/
- public FlatRegionMaskingFilter(EditSession editSession, Mask2D mask, FlatRegionFunction function) {
+ public FlatRegionMaskingFilter(Mask2D mask, FlatRegionFunction function) {
checkNotNull(function);
- checkNotNull(editSession);
checkNotNull(mask);
- this.editSession = editSession;
this.mask = mask;
this.function = function;
}
@Override
public boolean apply(Vector2D position) throws WorldEditException {
- return mask.matches(editSession, position) && function.apply(position);
+ return mask.test(position) && function.apply(position);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java b/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
index 461846c5d..cd0ac45b7 100644
--- a/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
+++ b/src/main/java/com/sk89q/worldedit/function/RegionMaskingFilter.java
@@ -19,10 +19,9 @@
package com.sk89q.worldedit.function;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.function.mask.Mask;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -33,30 +32,25 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class RegionMaskingFilter implements RegionFunction {
- private final EditSession editSession;
private final RegionFunction function;
private Mask mask;
/**
* Create a new masking filter.
*
- * @param editSession the edit session
* @param mask the mask
* @param function the function
*/
- public RegionMaskingFilter(EditSession editSession, Mask mask, RegionFunction function) {
+ public RegionMaskingFilter(Mask mask, RegionFunction function) {
checkNotNull(function);
- checkNotNull(editSession);
checkNotNull(mask);
-
- this.editSession = editSession;
this.mask = mask;
this.function = function;
}
@Override
public boolean apply(Vector position) throws WorldEditException {
- return mask.matches(editSession, position) && function.apply(position);
+ return mask.test(position) && function.apply(position);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java b/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java
new file mode 100644
index 000000000..4d90b4e43
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java
@@ -0,0 +1,61 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Extent;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * An abstract implementation of {@link Mask} that takes uses an {@link Extent}.
+ */
+public abstract class AbstractExtentMask extends AbstractMask {
+
+ private Extent extent;
+
+ /**
+ * Construct a new mask.
+ *
+ * @param extent the extent
+ */
+ protected AbstractExtentMask(Extent extent) {
+ setExtent(extent);
+ }
+
+ /**
+ * Get the extent.
+ *
+ * @return the extent
+ */
+ public Extent getExtent() {
+ return extent;
+ }
+
+ /**
+ * Set the extent.
+ *
+ * @param extent the extent
+ */
+ public void setExtent(Extent extent) {
+ checkNotNull(extent);
+ this.extent = extent;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/Mask2D.java b/src/main/java/com/sk89q/worldedit/function/mask/AbstractMask.java
similarity index 62%
rename from src/main/java/com/sk89q/worldedit/masks/Mask2D.java
rename to src/main/java/com/sk89q/worldedit/function/mask/AbstractMask.java
index f70af34a0..21c5900df 100644
--- a/src/main/java/com/sk89q/worldedit/masks/Mask2D.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/AbstractMask.java
@@ -17,23 +17,10 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
-
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Vector2D;
+package com.sk89q.worldedit.function.mask;
/**
- * A 2-dimensional mask, similar to {@link com.sk89q.worldedit.masks.Mask}.
+ * A base class of {@link Mask} that all masks should inherit from.
*/
-public interface Mask2D {
-
- /**
- * Return whether the given position is matched by this mask.
- *
- * @param editSession an edit session
- * @param position a mask
- * @return true if there is a match
- */
- boolean matches(EditSession editSession, Vector2D position);
-
+public abstract class AbstractMask implements Mask {
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java b/src/main/java/com/sk89q/worldedit/function/mask/AbstractMask2D.java
similarity index 88%
rename from src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java
rename to src/main/java/com/sk89q/worldedit/function/mask/AbstractMask2D.java
index 72df4af4d..1cffb2d2a 100644
--- a/src/main/java/com/sk89q/worldedit/masks/AbstractMask2D.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/AbstractMask2D.java
@@ -17,10 +17,10 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
+package com.sk89q.worldedit.function.mask;
/**
- * An abstract implementaiton of {@link com.sk89q.worldedit.masks.Mask2D}.
+ * A base class of {@link Mask2D} that all masks should inherit from.
*/
public abstract class AbstractMask2D implements Mask2D {
}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
new file mode 100644
index 000000000..1ea91cd46
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
@@ -0,0 +1,99 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A mask that checks whether blocks at the given positions are listed
+ * in a list of block types.
+ *
+ * This mask checks for both an exact block ID and data value match, as well
+ * for a block with the same ID but a data value of -1.
+ */
+public class BlockMask extends AbstractExtentMask {
+
+ private final Set blocks = new HashSet();
+
+ /**
+ * Create a new block mask.
+ *
+ * @param extent the extent
+ * @param blocks a list of blocks to match
+ */
+ public BlockMask(Extent extent, Collection blocks) {
+ super(extent);
+ checkNotNull(blocks);
+ blocks.addAll(blocks);
+ }
+
+ /**
+ * Create a new block mask.
+ *
+ * @param extent the extent
+ * @param block an array of blocks to match
+ */
+ public BlockMask(Extent extent, BaseBlock... block) {
+ this(extent, Arrays.asList(checkNotNull(block)));
+ }
+
+ /**
+ * Add the given blocks to the list of criteria.
+ *
+ * @param blocks a list of blocks
+ */
+ public void add(Collection blocks) {
+ checkNotNull(blocks);
+ blocks.addAll(blocks);
+ }
+
+ /**
+ * Add the given blocks to the list of criteria.
+ *
+ * @param block an array of blocks
+ */
+ public void add(BaseBlock... block) {
+ add(Arrays.asList(checkNotNull(block)));
+ }
+
+ /**
+ * Get the list of blocks that are tested with.
+ *
+ * @return a list of blocks
+ */
+ public Collection getBlocks() {
+ return blocks;
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ BaseBlock block = getExtent().getBlock(vector);
+ return blocks.contains(block) || blocks.contains(new BaseBlock(block.getType(), -1));
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java b/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java
similarity index 59%
rename from src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java
rename to src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java
index 21980312d..e955de42a 100644
--- a/src/main/java/com/sk89q/worldedit/masks/BoundedYMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java
@@ -17,31 +17,36 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
+package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
+import static com.google.common.base.Preconditions.checkArgument;
+
/**
- * Fails all tests against locations outside a range of Y values.
+ * Has the criteria where the Y value of passed positions must be within
+ * a certain range of Y values (inclusive).
*/
-public class BoundedYMask extends AbstractMask {
+public class BoundedHeightMask extends AbstractMask {
private final int minY;
private final int maxY;
- public BoundedYMask(int minY, int maxY) {
- if (minY > maxY) {
- throw new IllegalArgumentException("minY must be less than or equal to maxY");
- }
+ /**
+ * Create a new bounded height mask.
+ *
+ * @param minY the minimum Y
+ * @param maxY the maximum Y (must be equal to or greater than minY)
+ */
+ public BoundedHeightMask(int minY, int maxY) {
+ checkArgument(minY <= maxY, "minY <= maxY required");
this.minY = minY;
this.maxY = maxY;
}
@Override
- public boolean matches(EditSession editSession, Vector pos) {
- int y = pos.getBlockY();
- return y >= minY && y <= maxY;
+ public boolean test(Vector vector) {
+ return vector.getY() >= minY && vector.getY() <= maxY;
}
}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
new file mode 100644
index 000000000..b2fe813df
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
@@ -0,0 +1,46 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BlockID;
+
+/**
+ * A mask that returns true whenever the block at the location is not
+ * an air block (it contains some other block).
+ */
+public class ExistingBlockMask extends AbstractExtentMask {
+
+ /**
+ * Create a new existing block map.
+ *
+ * @param extent the extent to check
+ */
+ public ExistingBlockMask(Extent extent) {
+ super(extent);
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ return getExtent().getBlockType(vector) != BlockID.AIR;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java
new file mode 100644
index 000000000..10251e172
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java
@@ -0,0 +1,45 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+import java.util.Collection;
+
+public class FuzzyBlockMask extends BlockMask {
+
+ public FuzzyBlockMask(Extent extent, Collection blocks) {
+ super(extent, blocks);
+ }
+
+ public FuzzyBlockMask(Extent extent, BaseBlock... block) {
+ super(extent, block);
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ Extent extent = getExtent();
+ Collection blocks = getBlocks();
+ BaseBlock compare = new BaseBlock(extent.getBlockType(vector), extent.getBlockData(vector));
+ return BaseBlock.containsFuzzy(blocks, compare);
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/DummyMask.java b/src/main/java/com/sk89q/worldedit/function/mask/Mask.java
similarity index 73%
rename from src/main/java/com/sk89q/worldedit/masks/DummyMask.java
rename to src/main/java/com/sk89q/worldedit/function/mask/Mask.java
index 0b6ef5c8a..12d9931b5 100644
--- a/src/main/java/com/sk89q/worldedit/masks/DummyMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/Mask.java
@@ -17,19 +17,21 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
+package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
/**
- * A mask that only returns true
.
+ * Tests whether a given vector meets a criteria.
*/
-public class DummyMask extends AbstractMask {
+public interface Mask {
- @Override
- public boolean matches(EditSession editSession, Vector pos) {
- return true;
- }
+ /**
+ * Returns true if the criteria is met.
+ *
+ * @param vector the vector to test
+ * @return true if the criteria is met
+ */
+ boolean test(Vector vector);
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java b/src/main/java/com/sk89q/worldedit/function/mask/Mask2D.java
similarity index 73%
rename from src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java
rename to src/main/java/com/sk89q/worldedit/function/mask/Mask2D.java
index cb1e3b19c..e1b12a84f 100644
--- a/src/main/java/com/sk89q/worldedit/masks/DummyMask2D.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/Mask2D.java
@@ -17,19 +17,21 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
+package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector2D;
/**
- * A mask that only returns true
.
+ * Tests whether a given vector meets a criteria.
*/
-public class DummyMask2D extends AbstractMask2D {
+public interface Mask2D {
- @Override
- public boolean matches(EditSession editSession, Vector2D position) {
- return true;
- }
+ /**
+ * Returns true if the criteria is met.
+ *
+ * @param vector the vector to test
+ * @return true if the criteria is met
+ */
+ boolean test(Vector2D vector);
}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
new file mode 100644
index 000000000..6c5be470d
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
@@ -0,0 +1,102 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Vector;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Combines several masks and requires that all masks return true
+ * when a certain position is tested. It serves as a logical AND operation
+ * on a list of masks.
+ */
+public class MaskIntersection extends AbstractMask {
+
+ private final Set masks = new HashSet();
+
+ /**
+ * Create a new intersection.
+ *
+ * @param masks a list of masks
+ */
+ public MaskIntersection(Collection masks) {
+ checkNotNull(masks);
+ masks.addAll(masks);
+ }
+
+ /**
+ * Create a new intersection.
+ *
+ * @param mask a list of masks
+ */
+ public MaskIntersection(Mask... mask) {
+ this(Arrays.asList(checkNotNull(mask)));
+ }
+
+ /**
+ * Add some masks to the list.
+ *
+ * @param masks the masks
+ */
+ public void add(Collection masks) {
+ checkNotNull(masks);
+ masks.addAll(masks);
+ }
+
+ /**
+ * Add some masks to the list.
+ *
+ * @param mask the masks
+ */
+ public void add(Mask... mask) {
+ add(Arrays.asList(checkNotNull(mask)));
+ }
+
+ /**
+ * Get the masks that are tested with.
+ *
+ * @return the masks
+ */
+ public Collection getMasks() {
+ return masks;
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ if (masks.size() == 0) {
+ return false;
+ }
+
+ for (Mask mask : masks) {
+ if (!mask.test(vector)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java
new file mode 100644
index 000000000..3ab29c600
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java
@@ -0,0 +1,64 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Vector;
+
+import java.util.Collection;
+
+/**
+ * Combines several masks and requires that one or more masks return true
+ * when a certain position is tested. It serves as a logical OR operation
+ * on a list of masks.
+ */
+public class MaskUnion extends MaskIntersection {
+
+ /**
+ * Create a new union.
+ *
+ * @param masks a list of masks
+ */
+ public MaskUnion(Collection masks) {
+ super(masks);
+ }
+
+ /**
+ * Create a new union.
+ *
+ * @param mask a list of masks
+ */
+ public MaskUnion(Mask... mask) {
+ super(mask);
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ Collection masks = getMasks();
+
+ for (Mask mask : masks) {
+ if (mask.test(vector)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/Masks.java b/src/main/java/com/sk89q/worldedit/function/mask/Masks.java
new file mode 100644
index 000000000..7f8275aeb
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/Masks.java
@@ -0,0 +1,113 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.Vector2D;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Various utility functions related to {@link Mask} and {@link Mask2D}.
+ */
+public final class Masks {
+
+ private Masks() {
+ }
+
+ /**
+ * Return a 3D mask that always returns true;
+ *
+ * @return a mask
+ */
+ public static Mask alwaysTrue() {
+ return new AbstractMask() {
+ @Override
+ public boolean test(Vector vector) {
+ return true;
+ }
+ };
+ }
+
+ /**
+ * Return a 2D mask that always returns true;
+ *
+ * @return a mask
+ */
+ public static Mask2D alwaysTrue2D() {
+ return new AbstractMask2D() {
+ @Override
+ public boolean test(Vector2D vector) {
+ return true;
+ }
+ };
+ }
+
+ /**
+ * Negate the given mask.
+ *
+ * @param mask the mask
+ * @return a new mask
+ */
+ public static Mask negate(final Mask mask) {
+ checkNotNull(mask);
+ return new AbstractMask() {
+ @Override
+ public boolean test(Vector vector) {
+ return !mask.test(vector);
+ }
+ };
+ }
+
+ /**
+ * Negate the given mask.
+ *
+ * @param mask the mask
+ * @return a new mask
+ */
+ public static Mask2D negate(final Mask2D mask) {
+ checkNotNull(mask);
+ return new AbstractMask2D() {
+ @Override
+ public boolean test(Vector2D vector) {
+ return !mask.test(vector);
+ }
+ };
+ }
+
+ /**
+ * Wrap an old-style mask and convert it to a new mask.
+ *
+ * @param editSession the edit session to bind to
+ * @param mask the old-style mask
+ * @return a new-style mask
+ */
+ public static Mask wrap(final EditSession editSession, final com.sk89q.worldedit.masks.Mask mask) {
+ checkNotNull(mask);
+ return new AbstractMask() {
+ @Override
+ public boolean test(Vector vector) {
+ return mask.matches(editSession, vector);
+ }
+ };
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java b/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java
similarity index 92%
rename from src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
rename to src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java
index 6c5e586a2..3cb815771 100644
--- a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java
@@ -17,9 +17,8 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
+package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.noise.NoiseGenerator;
@@ -86,8 +85,8 @@ public class NoiseFilter extends AbstractMask {
}
@Override
- public boolean matches(EditSession editSession, Vector pos) {
- return noiseGenerator.noise(pos) <= density;
+ public boolean test(Vector vector) {
+ return noiseGenerator.noise(vector) <= density;
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java b/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter2D.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
rename to src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter2D.java
index 2071ce000..8c74b6cb9 100644
--- a/src/main/java/com/sk89q/worldedit/masks/NoiseFilter2D.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter2D.java
@@ -17,9 +17,8 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.masks;
+package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.math.noise.NoiseGenerator;
@@ -86,7 +85,7 @@ public class NoiseFilter2D extends AbstractMask2D {
}
@Override
- public boolean matches(EditSession editSession, Vector2D pos) {
+ public boolean test(Vector2D pos) {
return noiseGenerator.noise(pos) <= density;
}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java b/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java
new file mode 100644
index 000000000..42a1d5ff0
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/RegionMask.java
@@ -0,0 +1,67 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.regions.Region;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A mask that tests whether given positions are contained within a region.
+ */
+public class RegionMask extends AbstractMask {
+
+ private Region region;
+
+ /**
+ * Create a new region mask.
+ *
+ * @param region the region
+ */
+ public RegionMask(Region region) {
+ setRegion(region);
+ }
+
+ /**
+ * Get the region.
+ *
+ * @return the region
+ */
+ public Region getRegion() {
+ return region;
+ }
+
+ /**
+ * Set the region that positions must be contained within.
+ *
+ * @param region the region
+ */
+ public void setRegion(Region region) {
+ checkNotNull(region);
+ this.region = region;
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ return region.contains(vector);
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
new file mode 100644
index 000000000..fb0607637
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
@@ -0,0 +1,38 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.mask;
+
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BlockType;
+
+public class SolidBlockMask extends AbstractExtentMask {
+
+ public SolidBlockMask(Extent extent) {
+ super(extent);
+ }
+
+ @Override
+ public boolean test(Vector vector) {
+ Extent extent = getExtent();
+ return !BlockType.canPassThrough(extent.getBlockType(vector), extent.getBlockData(vector));
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
index a2764476f..0af12c68e 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
@@ -21,8 +21,8 @@ package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.function.RegionFunction;
+import com.sk89q.worldedit.function.mask.Mask;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
index 3872f4f4a..a7500ce74 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
@@ -24,9 +24,9 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.LayerFunction;
+import com.sk89q.worldedit.function.mask.Mask2D;
+import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.operation.Operation;
-import com.sk89q.worldedit.masks.DummyMask2D;
-import com.sk89q.worldedit.masks.Mask2D;
import com.sk89q.worldedit.regions.FlatRegion;
import static com.google.common.base.Preconditions.checkArgument;
@@ -45,7 +45,7 @@ public class LayerVisitor implements Operation {
private final EditSession editSession;
private final FlatRegion flatRegion;
private final LayerFunction function;
- private Mask2D mask = new DummyMask2D();
+ private Mask2D mask = Masks.alwaysTrue2D();
private int minY;
private int maxY;
@@ -94,7 +94,7 @@ public class LayerVisitor implements Operation {
@Override
public Operation resume() throws WorldEditException {
for (Vector2D column : flatRegion.asFlatRegion()) {
- if (!mask.matches(editSession, column)) {
+ if (!mask.test(column)) {
continue;
}
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
index 5e86da7c5..4446c566a 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
@@ -21,7 +21,7 @@ package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.masks.Mask;
+import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.RegionFunction;
/**
@@ -45,6 +45,6 @@ public class RecursiveVisitor extends BreadthFirstSearch {
if (y < 0 || y > editSession.getWorld().getMaxY()) {
return false;
}
- return mask.matches(editSession, to);
+ return mask.test(to);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/AbstractMask.java b/src/main/java/com/sk89q/worldedit/masks/AbstractMask.java
index 0be57ccab..05525fe9b 100644
--- a/src/main/java/com/sk89q/worldedit/masks/AbstractMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/AbstractMask.java
@@ -4,8 +4,13 @@ import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
+/**
+ * @deprecated Switch to {@link com.sk89q.worldedit.function.mask.AbstractMask}
+ */
+@Deprecated
public abstract class AbstractMask implements Mask {
@Override
public void prepare(LocalSession session, LocalPlayer player, Vector target) {
}
+
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/BlockMask.java b/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
index 692501ad7..c6d9a922e 100644
--- a/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/BlockMask.java
@@ -1,7 +1,6 @@
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
@@ -9,7 +8,11 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
-public class BlockMask extends ExtentAwareMask {
+/**
+ * @deprecated Use {@link com.sk89q.worldedit.function.mask.BlockMask}
+ */
+@Deprecated
+public class BlockMask extends AbstractMask {
private final Set blocks;
@@ -43,8 +46,7 @@ public class BlockMask extends ExtentAwareMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- Extent extent = getExtent(editSession);
- BaseBlock block = extent.getBlock(pos);
+ BaseBlock block = editSession.getBlock(pos);
return blocks.contains(block)
|| blocks.contains(new BaseBlock(block.getType(), -1));
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java b/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java
index 79eca640b..2a8b0ecd8 100644
--- a/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/CombinedMask.java
@@ -23,10 +23,15 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.function.mask.MaskIntersection;
import java.util.ArrayList;
import java.util.List;
+/**
+ * @deprecated See {@link MaskIntersection}
+ */
+@Deprecated
public class CombinedMask extends AbstractMask {
private final List masks = new ArrayList();
diff --git a/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java b/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java
index bb4536df1..d55d6cee2 100644
--- a/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/DynamicRegionMask.java
@@ -7,7 +7,7 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.Region;
-public class DynamicRegionMask implements Mask {
+public class DynamicRegionMask extends AbstractMask {
private Region region;
@Override
diff --git a/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java
index 8a536195f..09c4231d0 100644
--- a/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/ExistingBlockMask.java
@@ -23,9 +23,13 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
-public class ExistingBlockMask extends ExtentAwareMask {
+/**
+ * @deprecated See {@link com.sk89q.worldedit.function.mask.ExistingBlockMask}
+ */
+@Deprecated
+public class ExistingBlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- return getExtent(editSession).getBlockType(pos) != BlockID.AIR;
+ return editSession.getBlockType(pos) != BlockID.AIR;
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java b/src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java
deleted file mode 100644
index 4b86f9d25..000000000
--- a/src/main/java/com/sk89q/worldedit/masks/ExtentAwareMask.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * 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 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.masks;
-
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Extent;
-
-/**
- * Extended by masks to make them potentially use an {@link Extent} rather than
- * the {@link EditSession}.
- *
- * At the moment, masks are coupled to {@link EditSession} when they should
- * not be. However, because a change to {@link Mask} would cause massive breakage in
- * the API, that change is deferred until further notice and this class exists as
- * an opt-in mixin for adding support for {@link Extent}s.
- */
-public abstract class ExtentAwareMask extends AbstractMask {
-
- private Extent extent;
-
- /**
- * Get the extent that will be used for lookups.
- *
- * @return the extent, or null if the {@link EditSession} is to be used
- */
- public Extent getExtent() {
- return extent;
- }
-
- /**
- * Set the extent that will be used for lookups.
- *
- * @param extent the extent, or null if the {@link EditSession} is to be used
- */
- public void setExtent(Extent extent) {
- this.extent = extent;
- }
-
- /**
- * Get the extent to use for operations. Subclasses should call this method
- * rather than access the passed {@link EditSession} directly.
- *
- * @param editSession the passed in {@link EditSession}
- * @return an extent
- */
- protected Extent getExtent(EditSession editSession) {
- if (extent != null) {
- return extent;
- } else {
- return editSession;
- }
- }
-
-}
diff --git a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
index fe35ec30f..e350802f8 100644
--- a/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/FuzzyBlockMask.java
@@ -20,7 +20,6 @@
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
@@ -28,10 +27,10 @@ import java.util.HashSet;
import java.util.Set;
/**
- * Uses {@link BaseBlock#containsFuzzy(java.util.Collection, BaseBlock)} to
- * match blocks.
+ * @deprecated See {@link com.sk89q.worldedit.function.mask.FuzzyBlockMask}
*/
-public class FuzzyBlockMask extends ExtentAwareMask {
+@Deprecated
+public class FuzzyBlockMask extends AbstractMask {
private final Set filter;
@@ -59,8 +58,7 @@ public class FuzzyBlockMask extends ExtentAwareMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- Extent extent = getExtent(editSession);
- BaseBlock compare = new BaseBlock(extent.getBlockType(pos), extent.getBlockData(pos));
+ BaseBlock compare = new BaseBlock(editSession.getBlockType(pos), editSession.getBlockData(pos));
return BaseBlock.containsFuzzy(filter, compare);
}
}
diff --git a/src/main/java/com/sk89q/worldedit/masks/InvertedMask.java b/src/main/java/com/sk89q/worldedit/masks/InvertedMask.java
index 9ffc5213e..b84113790 100644
--- a/src/main/java/com/sk89q/worldedit/masks/InvertedMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/InvertedMask.java
@@ -4,7 +4,12 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.function.mask.Masks;
+/**
+ * @deprecated See {@link Masks#negate(com.sk89q.worldedit.function.mask.Mask)}
+ */
+@Deprecated
public class InvertedMask extends AbstractMask {
private final Mask mask;
diff --git a/src/main/java/com/sk89q/worldedit/masks/Mask.java b/src/main/java/com/sk89q/worldedit/masks/Mask.java
index ce18cbece..aab2b8b36 100644
--- a/src/main/java/com/sk89q/worldedit/masks/Mask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/Mask.java
@@ -25,13 +25,9 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector;
/**
- * Base matcher for the block filtering framework. Implementing classes
- * can be used to filter blocks to set or replace.
- *
- * Do NOT implement this interface. Extend {@link AbstractMask} instead.
- *
- * @author sk89q
+ * @deprecated Use {@link com.sk89q.worldedit.function.mask.Mask}
*/
+@Deprecated
public interface Mask {
/**
diff --git a/src/main/java/com/sk89q/worldedit/masks/RandomMask.java b/src/main/java/com/sk89q/worldedit/masks/RandomMask.java
index 65c71af47..4b8374388 100644
--- a/src/main/java/com/sk89q/worldedit/masks/RandomMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/RandomMask.java
@@ -2,7 +2,12 @@ package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.function.mask.NoiseFilter;
+/**
+ * @deprecated See {@link NoiseFilter}
+ */
+@Deprecated
public class RandomMask extends AbstractMask {
private final double ratio;
diff --git a/src/main/java/com/sk89q/worldedit/masks/RegionMask.java b/src/main/java/com/sk89q/worldedit/masks/RegionMask.java
index b734e7ae3..a8e1e65fc 100644
--- a/src/main/java/com/sk89q/worldedit/masks/RegionMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/RegionMask.java
@@ -23,6 +23,10 @@ import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.Region;
+/**
+ * @deprecated See {@link com.sk89q.worldedit.function.mask.RegionMask}
+ */
+@Deprecated
public class RegionMask extends AbstractMask {
private final Region region;
diff --git a/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java b/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java
index 9414cfaf8..fda252825 100644
--- a/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/masks/SolidBlockMask.java
@@ -1,17 +1,16 @@
package com.sk89q.worldedit.masks;
import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType;
/**
- * Works like {@link ExistingBlockMask}, except also dealing with non-solid non-air blocks the same way as with air.
+ * @deprecated See {@link com.sk89q.worldedit.function.mask.SolidBlockMask}
*/
-public class SolidBlockMask extends ExtentAwareMask {
+@Deprecated
+public class SolidBlockMask extends AbstractMask {
@Override
public boolean matches(EditSession editSession, Vector pos) {
- Extent extent = getExtent(editSession);
- return !BlockType.canPassThrough(extent.getBlockType(pos), extent.getBlockData(pos));
+ return !BlockType.canPassThrough(editSession.getBlockType(pos), editSession.getBlockData(pos));
}
}
From 250be31fe2c3699f70c6c38437b20d84feb8699c Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 03:06:07 -0700
Subject: [PATCH 043/106] Added Transforms for Vectors in worldedit.math.*
---
.../math/transform/AffineTransform.java | 298 ++++++++++++++++++
.../math/transform/CombinedTransform.java | 77 +++++
.../worldedit/math/transform/Identity.java | 42 +++
.../worldedit/math/transform/Transform.java | 38 +++
4 files changed, 455 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java
create mode 100644 src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java
create mode 100644 src/main/java/com/sk89q/worldedit/math/transform/Identity.java
create mode 100644 src/main/java/com/sk89q/worldedit/math/transform/Transform.java
diff --git a/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java b/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java
new file mode 100644
index 000000000..4fef9b606
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java
@@ -0,0 +1,298 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.math.transform;
+
+import com.sk89q.worldedit.Vector;
+
+/**
+ * An affine transform.
+ *
+ * This class is from the that, then this affine transform.
+ *
+ * @param that the transform to apply first
+ * @return the composition this * that
+ */
+ public AffineTransform concatenate(AffineTransform that) {
+ double n00 = m00 * that.m00 + m01 * that.m10 + m02 * that.m20;
+ double n01 = m00 * that.m01 + m01 * that.m11 + m02 * that.m21;
+ double n02 = m00 * that.m02 + m01 * that.m12 + m02 * that.m22;
+ double n03 = m00 * that.m03 + m01 * that.m13 + m02 * that.m23 + m03;
+ double n10 = m10 * that.m00 + m11 * that.m10 + m12 * that.m20;
+ double n11 = m10 * that.m01 + m11 * that.m11 + m12 * that.m21;
+ double n12 = m10 * that.m02 + m11 * that.m12 + m12 * that.m22;
+ double n13 = m10 * that.m03 + m11 * that.m13 + m12 * that.m23 + m13;
+ double n20 = m20 * that.m00 + m21 * that.m10 + m22 * that.m20;
+ double n21 = m20 * that.m01 + m21 * that.m11 + m22 * that.m21;
+ double n22 = m20 * that.m02 + m21 * that.m12 + m22 * that.m22;
+ double n23 = m20 * that.m03 + m21 * that.m13 + m22 * that.m23 + m23;
+ return new AffineTransform(
+ n00, n01, n02, n03,
+ n10, n11, n12, n13,
+ n20, n21, n22, n23);
+ }
+
+ /**
+ * Return the affine transform created by applying first this affine
+ * transform, then the affine transform given by that
.
+ *
+ * @param that the transform to apply in a second step
+ * @return the composition that * this
+ */
+ public AffineTransform preConcatenate(AffineTransform that) {
+ double n00 = that.m00 * m00 + that.m01 * m10 + that.m02 * m20;
+ double n01 = that.m00 * m01 + that.m01 * m11 + that.m02 * m21;
+ double n02 = that.m00 * m02 + that.m01 * m12 + that.m02 * m22;
+ double n03 = that.m00 * m03 + that.m01 * m13 + that.m02 * m23 + that.m03;
+ double n10 = that.m10 * m00 + that.m11 * m10 + that.m12 * m20;
+ double n11 = that.m10 * m01 + that.m11 * m11 + that.m12 * m21;
+ double n12 = that.m10 * m02 + that.m11 * m12 + that.m12 * m22;
+ double n13 = that.m10 * m03 + that.m11 * m13 + that.m12 * m23 + that.m13;
+ double n20 = that.m20 * m00 + that.m21 * m10 + that.m22 * m20;
+ double n21 = that.m20 * m01 + that.m21 * m11 + that.m22 * m21;
+ double n22 = that.m20 * m02 + that.m21 * m12 + that.m22 * m22;
+ double n23 = that.m20 * m03 + that.m21 * m13 + that.m22 * m23 + that.m23;
+ return new AffineTransform(
+ n00, n01, n02, n03,
+ n10, n11, n12, n13,
+ n20, n21, n22, n23);
+ }
+
+ public AffineTransform translate(Vector vec) {
+ return translate(vec.getX(), vec.getY(), vec.getZ());
+ }
+
+ public AffineTransform translate(double x, double y, double z) {
+ return concatenate(new AffineTransform(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z));
+ }
+
+ public AffineTransform rotateX(double theta) {
+ double cot = Math.cos(theta);
+ double sit = Math.sin(theta);
+ return concatenate(
+ new AffineTransform(
+ 1, 0, 0, 0,
+ 0, cot, -sit, 0,
+ 0, sit, cot, 0));
+ }
+
+ public AffineTransform rotateY(double theta) {
+ double cot = Math.cos(theta);
+ double sit = Math.sin(theta);
+ return concatenate(
+ new AffineTransform(
+ cot, 0, sit, 0,
+ 0, 1, 0, 0,
+ -sit, 0, cot, 0));
+ }
+
+ public AffineTransform rotateZ(double theta) {
+ double cot = Math.cos(theta);
+ double sit = Math.sin(theta);
+ return concatenate(
+ new AffineTransform(
+ cot, -sit, 0, 0,
+ sit, cot, 0, 0,
+ 0, 0, 1, 0));
+ }
+
+ public AffineTransform scale(double s) {
+ return scale(s, s, s);
+ }
+
+ public AffineTransform scale(double sx, double sy, double sz) {
+ return concatenate(new AffineTransform(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0));
+ }
+
+ @Override
+ public Vector apply(Vector vector) {
+ return new Vector(
+ vector.getX() * m00 + vector.getY() * m01 + vector.getZ() * m02 + m03,
+ vector.getX() * m10 + vector.getY() * m11 + vector.getZ() * m12 + m13,
+ vector.getX() * m20 + vector.getY() * m21 + vector.getZ() * m22 + m23);
+ }
+
+ @Override
+ public Transform combine(Transform other) {
+ if (other instanceof AffineTransform) {
+ return concatenate((AffineTransform) other);
+ } else {
+ return new CombinedTransform(this, other);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java b/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java
new file mode 100644
index 000000000..893e3c384
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/math/transform/CombinedTransform.java
@@ -0,0 +1,77 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.math.transform;
+
+import com.sk89q.worldedit.Vector;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Combines several transforms in order.
+ */
+public class CombinedTransform implements Transform {
+
+ private final Transform[] transforms;
+
+ /**
+ * Create a new combined transformation.
+ *
+ * @param transforms a list of transformations
+ */
+ public CombinedTransform(Transform... transforms) {
+ checkNotNull(transforms);
+ this.transforms = Arrays.copyOf(transforms, transforms.length);
+ }
+
+ /**
+ * Create a new combined transformation.
+ *
+ * @param transforms a list of transformations
+ */
+ public CombinedTransform(Collection transforms) {
+ this(transforms.toArray(new Transform[checkNotNull(transforms).size()]));
+ }
+
+ @Override
+ public Vector apply(Vector vector) {
+ for (Transform transform : transforms) {
+ vector = transform.apply(vector);
+ }
+ return vector;
+ }
+
+ @Override
+ public Transform combine(Transform other) {
+ checkNotNull(other);
+ if (other instanceof CombinedTransform) {
+ CombinedTransform combinedOther = (CombinedTransform) other;
+ Transform[] newTransforms = new Transform[transforms.length + combinedOther.transforms.length];
+ System.arraycopy(transforms, 0, newTransforms, 0, transforms.length);
+ System.arraycopy(combinedOther.transforms, 0, newTransforms, transforms.length, combinedOther.transforms.length);
+ return new CombinedTransform(newTransforms);
+ } else {
+ return new CombinedTransform(this, other);
+ }
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/math/transform/Identity.java b/src/main/java/com/sk89q/worldedit/math/transform/Identity.java
new file mode 100644
index 000000000..e13547de1
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/math/transform/Identity.java
@@ -0,0 +1,42 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.math.transform;
+
+import com.sk89q.worldedit.Vector;
+
+/**
+ * Makes no transformation to given vectors.
+ */
+public class Identity implements Transform {
+
+ @Override
+ public Vector apply(Vector vector) {
+ return vector;
+ }
+
+ @Override
+ public Transform combine(Transform other) {
+ if (other instanceof Identity) {
+ return this;
+ } else {
+ return new CombinedTransform(this, other);
+ }
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/math/transform/Transform.java b/src/main/java/com/sk89q/worldedit/math/transform/Transform.java
new file mode 100644
index 000000000..38aba52e9
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/math/transform/Transform.java
@@ -0,0 +1,38 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.math.transform;
+
+import com.google.common.base.Function;
+import com.sk89q.worldedit.Vector;
+
+/**
+ * Makes a transformation of {@link Vector}s.
+ */
+public interface Transform extends Function {
+
+ /**
+ * Create a new {@link Transform} that combines this transform with another.
+ *
+ * @param other the other transform to occur second
+ * @return a new transform
+ */
+ Transform combine(Transform other);
+
+}
From 1408487fffcab38547080aecfa8d176d36638df2 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 03:06:20 -0700
Subject: [PATCH 044/106] Fixed Javadocs in Extent.
---
src/main/java/com/sk89q/worldedit/Extent.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/Extent.java b/src/main/java/com/sk89q/worldedit/Extent.java
index 4959e9e91..284a35603 100644
--- a/src/main/java/com/sk89q/worldedit/Extent.java
+++ b/src/main/java/com/sk89q/worldedit/Extent.java
@@ -31,7 +31,7 @@ public interface Extent {
* Get a copy of the block at the given location. May return null if the location
* given is out of bounds. The returned block must not be tied to any real block
* in the world, so changes to the returned {@link BaseBlock} have no effect until
- * {@link #setBlock(Vector, BaseBlock)} is called.
+ * {@link #setBlock(Vector, BaseBlock, boolean)} is called.
*
* @param location location of the block
* @return the block, or null if the block does not exist
@@ -72,6 +72,6 @@ public interface Extent {
* @param notifyAdjacent true to notify adjacent blocks of changes
* @return true if the block was successfully set (return value may not be accurate)
*/
- boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent);
+ boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException;
}
From 9aa3ae15d04e83bd7d32aef9f332f1e0ed87ab49 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 03:06:34 -0700
Subject: [PATCH 045/106] Added DelegateOperation to proxy Operations.
---
.../function/operation/DelegateOperation.java | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/function/operation/DelegateOperation.java
diff --git a/src/main/java/com/sk89q/worldedit/function/operation/DelegateOperation.java b/src/main/java/com/sk89q/worldedit/function/operation/DelegateOperation.java
new file mode 100644
index 000000000..f8600b171
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/operation/DelegateOperation.java
@@ -0,0 +1,60 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.operation;
+
+import com.sk89q.worldedit.WorldEditException;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Executes a delegete operation, but returns to another operation upon
+ * completing the delegate.
+ */
+public class DelegateOperation implements Operation {
+
+ private final Operation original;
+ private Operation delegate;
+
+ /**
+ * Create a new operation delegate.
+ *
+ * @param original the operation to return to
+ * @param delegate the delegate operation to complete before returning
+ */
+ public DelegateOperation(Operation original, Operation delegate) {
+ checkNotNull(original);
+ checkNotNull(delegate);
+ this.original = original;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public Operation resume() throws WorldEditException {
+ delegate = delegate.resume();
+ return delegate != null ? this : original;
+ }
+
+ @Override
+ public void cancel() {
+ delegate.cancel();
+ original.cancel();
+ }
+
+}
From e3a42db309d3597cd5e03a73e5798d2853a69aa8 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 03:08:06 -0700
Subject: [PATCH 046/106] Added ForwardExtentCopy and ExtentBlockCopy.
---
.../function/block/ExtentBlockCopy.java | 70 +++++++
.../function/operation/ForwardExtentCopy.java | 177 ++++++++++++++++++
2 files changed, 247 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
diff --git a/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java b/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
new file mode 100644
index 000000000..c0ba48fae
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
@@ -0,0 +1,70 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.block;
+
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.function.RegionFunction;
+import com.sk89q.worldedit.math.transform.Transform;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Copies blocks from one extent to another.
+ */
+public class ExtentBlockCopy implements RegionFunction {
+
+ private final Extent source;
+ private final Extent destination;
+ private final Vector from;
+ private final Vector to;
+ private final Transform transform;
+
+ /**
+ * Make a new copy.
+ *
+ * @param source the source extent
+ * @param from the source offset
+ * @param destination the destination extent
+ * @param to the destination offset
+ * @param transform a transform to apply to positions (after source offset, before destination offset)
+ */
+ public ExtentBlockCopy(Extent source, Vector from, Extent destination, Vector to, Transform transform) {
+ checkNotNull(source);
+ checkNotNull(from);
+ checkNotNull(destination);
+ checkNotNull(to);
+ checkNotNull(transform);
+ this.source = source;
+ this.from = from;
+ this.destination = destination;
+ this.to = to;
+ this.transform = transform;
+ }
+
+ @Override
+ public boolean apply(Vector position) throws WorldEditException {
+ BaseBlock block = source.getBlock(position);
+ return destination.setBlock(transform.apply(position.subtract(from)).add(to), block, true);
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
new file mode 100644
index 000000000..286b081ad
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
@@ -0,0 +1,177 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.operation;
+
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.function.RegionMaskingFilter;
+import com.sk89q.worldedit.function.block.ExtentBlockCopy;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.mask.Masks;
+import com.sk89q.worldedit.function.visitor.RegionVisitor;
+import com.sk89q.worldedit.math.transform.Identity;
+import com.sk89q.worldedit.math.transform.Transform;
+import com.sk89q.worldedit.regions.Region;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Makes a copy of a portion of one extent to another extent or another point.
+ *
+ * This is a forward extent copy, meaning that it iterates over the blocks in the
+ * source extent, and will copy as many blocks as there are in the source.
+ * Therefore, interpolation will not occur to fill in the gaps.
+ */
+public class ForwardExtentCopy implements Operation {
+
+ private final Extent source;
+ private final Extent destination;
+ private final Region region;
+ private final Vector to;
+ private int repetitions = 1;
+ private Mask sourceMask = Masks.alwaysTrue();
+ private Transform transform = new Identity();
+ private Transform currentTransform = null;
+ private RegionVisitor lastVisitor;
+ private int affected;
+
+ /**
+ * Create a new copy.
+ *
+ * @param source the source extent
+ * @param region the region to copy
+ * @param destination the destination extent
+ * @param to the destination position, starting from the the lowest X, Y, Z
+ */
+ public ForwardExtentCopy(Extent source, Region region, Extent destination, Vector to) {
+ checkNotNull(source);
+ checkNotNull(region);
+ checkNotNull(destination);
+ checkNotNull(to);
+ this.source = source;
+ this.destination = destination;
+ this.region = region;
+ this.to = to;
+ }
+
+ /**
+ * Get the transformation that will occur on every point.
+ *
+ * The transformation will stack with each repetition.
+ *
+ * @return a transformation
+ */
+ public Transform getTransform() {
+ return transform;
+ }
+
+ /**
+ * Set the transformation that will occur on every point.
+ *
+ * @param transform a transformation
+ * @see #getTransform()
+ */
+ public void setTransform(Transform transform) {
+ checkNotNull(transform);
+ this.transform = transform;
+ }
+
+ /**
+ * Get the mask that gets applied to the source extent.
+ *
+ * This mask can be used to filter what will be copied from the source.
+ *
+ * @return a source mask
+ */
+ public Mask getSourceMask() {
+ return sourceMask;
+ }
+
+ /**
+ * Set a mask that gets applied to the source extent.
+ *
+ * @param sourceMask a source mask
+ * @see #getSourceMask()
+ */
+ public void setSourceMask(Mask sourceMask) {
+ checkNotNull(sourceMask);
+ this.sourceMask = sourceMask;
+ }
+
+ /**
+ * Get the number of repetitions left.
+ *
+ * @return the number of repetitions
+ */
+ public int getRepetitions() {
+ return repetitions;
+ }
+
+ /**
+ * Set the number of repetitions left.
+ *
+ * @param repetitions the number of repetitions
+ */
+ public void setRepetitions(int repetitions) {
+ checkArgument(repetitions >= 0, "number of repetitions must be non-negative");
+ this.repetitions = repetitions;
+ }
+
+ /**
+ * Get the number of affected objects.
+ *
+ * @return the number of affected
+ */
+ public int getAffected() {
+ return affected;
+ }
+
+ @Override
+ public Operation resume() throws WorldEditException {
+ if (lastVisitor != null) {
+ affected += lastVisitor.getAffected();
+ lastVisitor = null;
+ }
+
+ if (repetitions > 0) {
+ repetitions--;
+
+ if (currentTransform == null) {
+ currentTransform = transform;
+ }
+
+ ExtentBlockCopy copy = new ExtentBlockCopy(source, region.getMinimumPoint(), destination, to, currentTransform);
+ RegionMaskingFilter filter = new RegionMaskingFilter(sourceMask, copy);
+ RegionVisitor visitor = new RegionVisitor(region, filter);
+ lastVisitor = visitor;
+ currentTransform = currentTransform.combine(transform);
+ return new DelegateOperation(this, visitor);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void cancel() {
+ }
+
+}
From 37c388baefb9c5fc8b2fbc9c67dc61bb5de93f85 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 03:08:56 -0700
Subject: [PATCH 047/106] Converted //stack to visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 68 +++++++------------
1 file changed, 23 insertions(+), 45 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 342ed68f8..46c149a8a 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -34,6 +34,7 @@ import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.block.Naturalizer;
import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.mask.*;
+import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
@@ -45,6 +46,7 @@ import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.interpolation.Node;
import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.math.noise.RandomNoise;
+import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.patterns.SingleBlockPattern;
import com.sk89q.worldedit.regions.*;
@@ -249,8 +251,8 @@ public class EditSession implements Extent {
}
@Override
- public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) {
- return setBlock(location, block, true);
+ public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws MaxChangedBlocksException {
+ return setBlock(location, block);
}
/**
@@ -1190,52 +1192,28 @@ public class EditSession implements Extent {
/**
* Stack a cuboid region.
*
- * @param region
- * @param dir
- * @param count
- * @param copyAir
+ * @param region the region to stack
+ * @param dir the direction to stack
+ * @param count the number of times to stack
+ * @param copyAir true to also copy air blocks
* @return number of blocks affected
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int stackCuboidRegion(Region region, Vector dir, int count,
- boolean copyAir) throws MaxChangedBlocksException {
- int affected = 0;
-
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- int xs = region.getWidth();
- int ys = region.getHeight();
- int zs = region.getLength();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int z = minZ; z <= maxZ; ++z) {
- for (int y = minY; y <= maxY; ++y) {
- BaseBlock block = getBlock(new Vector(x, y, z));
-
- if (!block.isAir() || copyAir) {
- for (int i = 1; i <= count; ++i) {
- Vector pos = new Vector(x + xs * dir.getBlockX()
- * i, y + ys * dir.getBlockY() * i, z + zs
- * dir.getBlockZ() * i);
-
- if (setBlock(pos, block)) {
- ++affected;
- }
- }
- }
- }
- }
+ public int stackCuboidRegion(Region region, Vector dir, int count, boolean copyAir) throws MaxChangedBlocksException {
+ checkNotNull(region);
+ checkNotNull(dir);
+ checkArgument(count >= 1, "count >= 1 required");
+
+ Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
+ Vector to = region.getMinimumPoint();
+ ForwardExtentCopy copy = new ForwardExtentCopy(this, region, this, to);
+ copy.setRepetitions(count);
+ copy.setTransform(new AffineTransform().translate(dir.multiply(size)));
+ if (!copyAir) {
+ copy.setSourceMask(new ExistingBlockMask(this));
}
-
- return affected;
+ OperationHelper.completeLegacy(copy);
+ return copy.getAffected();
}
/**
From fb16897b5cbafc1a71d10160db63aef5c59390df Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:26:10 -0700
Subject: [PATCH 048/106] Fixed BlockMask, MaskIntersection not using this.
---
.../java/com/sk89q/worldedit/function/mask/BlockMask.java | 4 ++--
.../com/sk89q/worldedit/function/mask/MaskIntersection.java | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
index 1ea91cd46..4228b0deb 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
@@ -50,7 +50,7 @@ public class BlockMask extends AbstractExtentMask {
public BlockMask(Extent extent, Collection blocks) {
super(extent);
checkNotNull(blocks);
- blocks.addAll(blocks);
+ this.blocks.addAll(blocks);
}
/**
@@ -70,7 +70,7 @@ public class BlockMask extends AbstractExtentMask {
*/
public void add(Collection blocks) {
checkNotNull(blocks);
- blocks.addAll(blocks);
+ this.blocks.addAll(blocks);
}
/**
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
index 6c5be470d..3185b42c8 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java
@@ -44,7 +44,7 @@ public class MaskIntersection extends AbstractMask {
*/
public MaskIntersection(Collection masks) {
checkNotNull(masks);
- masks.addAll(masks);
+ this.masks.addAll(masks);
}
/**
@@ -63,7 +63,7 @@ public class MaskIntersection extends AbstractMask {
*/
public void add(Collection masks) {
checkNotNull(masks);
- masks.addAll(masks);
+ this.masks.addAll(masks);
}
/**
From ecde631e5fe52d93fdd99d7612c1da8b53e7c9d3 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:26:25 -0700
Subject: [PATCH 049/106] Changed BlockReplace to take an Extent.
---
.../worldedit/function/block/BlockReplace.java | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
index 5298dcf66..a3d80e6eb 100644
--- a/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
+++ b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
@@ -19,34 +19,38 @@
package com.sk89q.worldedit.function.block;
-import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.patterns.Pattern;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Replaces blocks with the given pattern.
*/
public class BlockReplace implements RegionFunction {
- private final EditSession editSession;
+ private final Extent extent;
private Pattern pattern;
/**
* Create a new instance.
*
- * @param editSession the edit session
+ * @param extent an extent
* @param pattern a pattern
*/
- public BlockReplace(EditSession editSession, Pattern pattern) {
- this.editSession = editSession;
+ public BlockReplace(Extent extent, Pattern pattern) {
+ checkNotNull(extent);
+ checkNotNull(pattern);
+ this.extent = extent;
this.pattern = pattern;
}
@Override
public boolean apply(Vector position) throws WorldEditException {
- return editSession.setBlock(position, pattern.next(position));
+ return extent.setBlock(position, pattern.next(position), true);
}
}
\ No newline at end of file
From 7a6df178d64049e2444af97af41d0544f07cc6c9 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:26:37 -0700
Subject: [PATCH 050/106] Added CombinedRegionFunction.
---
.../function/CombinedRegionFunction.java | 91 +++++++++++++++++++
1 file changed, 91 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java
diff --git a/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java b/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java
new file mode 100644
index 000000000..20e819454
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java
@@ -0,0 +1,91 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+
+import java.util.*;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Executes several region functions in order.
+ */
+public class CombinedRegionFunction implements RegionFunction {
+
+ private final List functions = new ArrayList();
+
+ /**
+ * Create a combined region function.
+ */
+ public CombinedRegionFunction() {
+ }
+
+ /**
+ * Create a combined region function.
+ *
+ * @param functions a list of functions to match
+ */
+ public CombinedRegionFunction(Collection functions) {
+ checkNotNull(functions);
+ this.functions.addAll(functions);
+ }
+
+ /**
+ * Create a combined region function.
+ *
+ * @param function an array of functions to match
+ */
+ public CombinedRegionFunction(RegionFunction... function) {
+ this(Arrays.asList(checkNotNull(function)));
+ }
+
+ /**
+ * Add the given functions to the list of functions to call.
+ *
+ * @param functions a list of functions
+ */
+ public void add(Collection functions) {
+ checkNotNull(functions);
+ this.functions.addAll(functions);
+ }
+
+ /**
+ * Add the given functions to the list of functions to call.
+ *
+ * @param function an array of functions
+ */
+ public void add(RegionFunction... function) {
+ add(Arrays.asList(checkNotNull(function)));
+ }
+
+ @Override
+ public boolean apply(Vector position) throws WorldEditException {
+ boolean ret = false;
+ for (RegionFunction function : functions) {
+ if (function.apply(position)) {
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+}
From 59aa51e037b38d5d0557ef3ef091185c8c669760 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:26:51 -0700
Subject: [PATCH 051/106] Added OperationQueue to execute multiple operations
sequentially.
---
.../function/operation/OperationQueue.java | 103 ++++++++++++++++++
1 file changed, 103 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/function/operation/OperationQueue.java
diff --git a/src/main/java/com/sk89q/worldedit/function/operation/OperationQueue.java b/src/main/java/com/sk89q/worldedit/function/operation/OperationQueue.java
new file mode 100644
index 000000000..0792394db
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/operation/OperationQueue.java
@@ -0,0 +1,103 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.operation;
+
+import com.sk89q.worldedit.WorldEditException;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Executes multiple queues in order.
+ */
+public class OperationQueue implements Operation {
+
+ private final Deque queue = new ArrayDeque();
+ private Operation current;
+
+ /**
+ * Create a new queue containing no operations.
+ */
+ public OperationQueue() {
+ }
+
+ /**
+ * Create a new queue with operations from the given collection.
+ *
+ * @param operations a collection of operations
+ */
+ public OperationQueue(Collection operations) {
+ checkNotNull(operations);
+ for (Operation operation : operations) {
+ offer(operation);
+ }
+ }
+
+ /**
+ * Create a new queue with operations from the given array.
+ *
+ * @param operation an array of operations
+ */
+ public OperationQueue(Operation... operation) {
+ checkNotNull(operation);
+ for (Operation o : operation) {
+ offer(o);
+ }
+ }
+
+ /**
+ * Add a new operation to the queue.
+ *
+ * @param operation the operation
+ */
+ public void offer(Operation operation) {
+ checkNotNull(operation);
+ queue.offer(operation);
+ }
+
+ @Override
+ public Operation resume() throws WorldEditException {
+ if (current == null && queue.size() > 0) {
+ current = queue.poll();
+ }
+
+ if (current != null) {
+ current = current.resume();
+
+ if (current == null) {
+ current = queue.poll();
+ }
+ }
+
+ return current != null ? this : null;
+ }
+
+ @Override
+ public void cancel() {
+ for (Operation operation : queue) {
+ operation.cancel();
+ }
+ queue.clear();
+ }
+
+}
From 36c5ceaf90ed03d07bca7bdd461f4f642be38802 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:27:02 -0700
Subject: [PATCH 052/106] Added ExtentBuffer to buffer changes to Extents.
---
.../sk89q/worldedit/extent/ExtentBuffer.java | 171 ++++++++++++++++++
1 file changed, 171 insertions(+)
create mode 100644 src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
diff --git a/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java b/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
new file mode 100644
index 000000000..741bac613
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
@@ -0,0 +1,171 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.extent;
+
+import com.sk89q.worldedit.BlockVector;
+import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.blocks.BlockID;
+import com.sk89q.worldedit.function.mask.Mask;
+import com.sk89q.worldedit.function.mask.Masks;
+import com.sk89q.worldedit.patterns.Pattern;
+import com.sk89q.worldedit.regions.AbstractRegion;
+import com.sk89q.worldedit.regions.Region;
+import com.sk89q.worldedit.regions.RegionOperationException;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Buffers changes to an {@link Extent} and allows later retrieval of buffered
+ * changes for actual setting.
+ */
+public class ExtentBuffer implements Extent, Pattern {
+
+ private static final BaseBlock AIR = new BaseBlock(BlockID.AIR);
+
+ private final Extent delegate;
+ private final Map buffer = new LinkedHashMap();
+ private final Mask mask;
+ private Vector min = null;
+ private Vector max = null;
+
+ /**
+ * Create a new extent buffer that will buffer every change.
+ *
+ * @param delegate the delegate extent for {@link Extent#getBlock(Vector)}, etc. calls
+ */
+ public ExtentBuffer(Extent delegate) {
+ this(delegate, Masks.alwaysTrue());
+ }
+
+ /**
+ * Create a new extent buffer that will buffer changes that meet the criteria
+ * of the given mask.
+ *
+ * @param delegate the delegate extent for {@link Extent#getBlock(Vector)}, etc. calls
+ * @param mask the mask
+ */
+ public ExtentBuffer(Extent delegate, Mask mask) {
+ checkNotNull(delegate);
+ checkNotNull(mask);
+ this.delegate = delegate;
+ this.mask = mask;
+ }
+
+ @Override
+ public BaseBlock getBlock(Vector location) {
+ return delegate.getBlock(location);
+ }
+
+ @Override
+ public int getBlockType(Vector location) {
+ return delegate.getBlockType(location);
+ }
+
+ @Override
+ public int getBlockData(Vector location) {
+ return delegate.getBlockData(location);
+ }
+
+ @Override
+ public boolean setBlock(Vector location, BaseBlock block, boolean notifyAdjacent) throws WorldEditException {
+ // Update minimum
+ if (min == null) {
+ min = location;
+ } else {
+ min = Vector.getMinimum(min, location);
+ }
+
+ // Update maximum
+ if (max == null) {
+ max = location;
+ } else {
+ max = Vector.getMaximum(max, location);
+ }
+
+ BlockVector blockVector = location.toBlockVector();
+ if (mask.test(blockVector)) {
+ buffer.put(blockVector, block);
+ return true;
+ } else {
+ return delegate.setBlock(location, block, notifyAdjacent);
+ }
+ }
+
+ @Override
+ public BaseBlock next(Vector pos) {
+ BaseBlock block = buffer.get(pos.toBlockVector());
+ if (block != null) {
+ return block;
+ } else {
+ return AIR;
+ }
+ }
+
+ @Override
+ public BaseBlock next(int x, int y, int z) {
+ return next(new Vector(x, y, z));
+ }
+
+ /**
+ * Return a region representation of this buffer.
+ *
+ * @return a region
+ */
+ public Region asRegion() {
+ return new AbstractRegion(null) {
+ @Override
+ public Vector getMinimumPoint() {
+ return min != null ? min : new Vector();
+ }
+
+ @Override
+ public Vector getMaximumPoint() {
+ return max != null ? max : new Vector();
+ }
+
+ @Override
+ public void expand(Vector... changes) throws RegionOperationException {
+ throw new UnsupportedOperationException("Cannot change the size of this region");
+ }
+
+ @Override
+ public void contract(Vector... changes) throws RegionOperationException {
+ throw new UnsupportedOperationException("Cannot change the size of this region");
+ }
+
+ @Override
+ public boolean contains(Vector pt) {
+ return buffer.containsKey(pt.toBlockVector());
+ }
+
+ @Override
+ public Iterator iterator() {
+ return buffer.keySet().iterator();
+ }
+ };
+ }
+}
From 5c3db177a41befd09ee3a45c734a0be07d66d9a6 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:27:25 -0700
Subject: [PATCH 053/106] ForwardExtentCopy can now apply a function to source
blocks after copy.
---
.../function/operation/ForwardExtentCopy.java | 26 ++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
index 286b081ad..f768ee73f 100644
--- a/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
+++ b/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
@@ -22,6 +22,8 @@ package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.function.CombinedRegionFunction;
+import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
import com.sk89q.worldedit.function.mask.Mask;
@@ -49,6 +51,7 @@ public class ForwardExtentCopy implements Operation {
private final Vector to;
private int repetitions = 1;
private Mask sourceMask = Masks.alwaysTrue();
+ private RegionFunction sourceFunction = null;
private Transform transform = new Identity();
private Transform currentTransform = null;
private RegionVisitor lastVisitor;
@@ -117,6 +120,26 @@ public class ForwardExtentCopy implements Operation {
this.sourceMask = sourceMask;
}
+ /**
+ * Get the function that gets applied to all source blocks after
+ * the copy has been made.
+ *
+ * @return a source function, or null if none is to be applied
+ */
+ public RegionFunction getSourceFunction() {
+ return sourceFunction;
+ }
+
+ /**
+ * Set the function that gets applied to all source blocks after
+ * the copy has been made.
+ *
+ * @param function a source function, or null if none is to be applied
+ */
+ public void setSourceFunction(RegionFunction function) {
+ this.sourceFunction = function;
+ }
+
/**
* Get the number of repetitions left.
*
@@ -161,7 +184,8 @@ public class ForwardExtentCopy implements Operation {
ExtentBlockCopy copy = new ExtentBlockCopy(source, region.getMinimumPoint(), destination, to, currentTransform);
RegionMaskingFilter filter = new RegionMaskingFilter(sourceMask, copy);
- RegionVisitor visitor = new RegionVisitor(region, filter);
+ RegionFunction function = sourceFunction != null ? new CombinedRegionFunction(filter, sourceFunction) : filter;
+ RegionVisitor visitor = new RegionVisitor(region, function);
lastVisitor = visitor;
currentTransform = currentTransform.combine(transform);
return new DelegateOperation(this, visitor);
From c8ee9ce9314e5a65d9422b11881c463571f9758d Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 10:29:00 -0700
Subject: [PATCH 054/106] Converted //move to visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 71 +++++++++----------
1 file changed, 34 insertions(+), 37 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 46c149a8a..66f463a53 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -27,6 +27,7 @@ import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.expression.Expression;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
+import com.sk89q.worldedit.extent.ExtentBuffer;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.BlockCount;
@@ -36,6 +37,7 @@ import com.sk89q.worldedit.function.generator.GardenPatchGenerator;
import com.sk89q.worldedit.function.mask.*;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.OperationHelper;
+import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
@@ -1203,7 +1205,7 @@ public class EditSession implements Extent {
checkNotNull(region);
checkNotNull(dir);
checkArgument(count >= 1, "count >= 1 required");
-
+
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
Vector to = region.getMinimumPoint();
ForwardExtentCopy copy = new ForwardExtentCopy(this, region, this, to);
@@ -1217,51 +1219,46 @@ public class EditSession implements Extent {
}
/**
- * Move a region.
+ * Move the blocks in a region a certain direction.
*
- * @param region
- * @param dir
- * @param distance
- * @param copyAir
- * @param replace
+ * @param region the region to move
+ * @param dir the direction
+ * @param distance the distance to move
+ * @param copyAir true to copy air blocks
+ * @param replacement the replacement block to fill in after moving, or null to use air
* @return number of blocks moved
- * @throws MaxChangedBlocksException
- * @throws RegionOperationException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int moveRegion(Region region, Vector dir, int distance,
- boolean copyAir, BaseBlock replace)
- throws MaxChangedBlocksException, RegionOperationException {
- int affected = 0;
+ public int moveRegion(Region region, Vector dir, int distance, boolean copyAir, BaseBlock replacement) throws MaxChangedBlocksException {
+ checkNotNull(region);
+ checkNotNull(dir);
+ checkArgument(distance >= 1, "distance >= 1 required");
- final Vector shift = dir.multiply(distance);
+ Vector to = region.getMinimumPoint();
- final Region newRegion = region.clone();
- newRegion.shift(shift);
+ // Remove the original blocks
+ Pattern pattern = replacement != null ?
+ new SingleBlockPattern(replacement) :
+ new SingleBlockPattern(new BaseBlock(BlockID.AIR));
+ BlockReplace remove = new BlockReplace(this, pattern);
- final Map delayed = new LinkedHashMap();
-
- for (Vector pos : region) {
- final BaseBlock block = getBlock(pos);
-
- if (!block.isAir() || copyAir) {
- final Vector newPos = pos.add(shift);
-
- delayed.put(newPos, getBlock(pos));
-
- // Don't want to replace the old block if it's in
- // the new area
- if (!newRegion.contains(pos)) {
- setBlock(pos, replace);
- }
- }
+ // Copy to a buffer so we don't destroy our original before we can copy all the blocks from it
+ ExtentBuffer buffer = new ExtentBuffer(this, new RegionMask(region));
+ ForwardExtentCopy copy = new ForwardExtentCopy(this, region, buffer, to);
+ copy.setTransform(new AffineTransform().translate(dir.multiply(distance)));
+ copy.setSourceFunction(remove); // Remove
+ if (!copyAir) {
+ copy.setSourceMask(new ExistingBlockMask(this));
}
- for (Map.Entry entry : delayed.entrySet()) {
- setBlock(entry.getKey(), entry.getValue());
- ++affected;
- }
+ // Then we need to copy the buffer to the world
+ BlockReplace replace = new BlockReplace(this, buffer);
+ RegionVisitor visitor = new RegionVisitor(buffer.asRegion(), replace);
- return affected;
+ OperationQueue operation = new OperationQueue(copy, visitor);
+ OperationHelper.completeLegacy(operation);
+
+ return copy.getAffected();
}
/**
From 75bee27610e785be0b796e3f5cd93acd4831d97b Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 12:03:12 -0700
Subject: [PATCH 055/106] Move Extent to extent sub-package.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 1 +
src/main/java/com/sk89q/worldedit/LocalWorld.java | 1 +
src/main/java/com/sk89q/worldedit/{ => extent}/Extent.java | 4 +++-
src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java | 1 -
.../java/com/sk89q/worldedit/function/block/BlockReplace.java | 2 +-
.../com/sk89q/worldedit/function/block/ExtentBlockCopy.java | 2 +-
.../com/sk89q/worldedit/function/mask/AbstractExtentMask.java | 2 +-
.../java/com/sk89q/worldedit/function/mask/BlockMask.java | 2 +-
.../com/sk89q/worldedit/function/mask/ExistingBlockMask.java | 2 +-
.../com/sk89q/worldedit/function/mask/FuzzyBlockMask.java | 2 +-
.../com/sk89q/worldedit/function/mask/SolidBlockMask.java | 2 +-
.../sk89q/worldedit/function/operation/ForwardExtentCopy.java | 2 +-
12 files changed, 13 insertions(+), 10 deletions(-)
rename src/main/java/com/sk89q/worldedit/{ => extent}/Extent.java (96%)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 66f463a53..4442de0c4 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -27,6 +27,7 @@ import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.expression.Expression;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.expression.runtime.RValue;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.ExtentBuffer;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
diff --git a/src/main/java/com/sk89q/worldedit/LocalWorld.java b/src/main/java/com/sk89q/worldedit/LocalWorld.java
index 6b77884e1..e4659459c 100644
--- a/src/main/java/com/sk89q/worldedit/LocalWorld.java
+++ b/src/main/java/com/sk89q/worldedit/LocalWorld.java
@@ -20,6 +20,7 @@
package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.*;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.foundation.Block;
import com.sk89q.worldedit.foundation.World;
import com.sk89q.worldedit.regions.Region;
diff --git a/src/main/java/com/sk89q/worldedit/Extent.java b/src/main/java/com/sk89q/worldedit/extent/Extent.java
similarity index 96%
rename from src/main/java/com/sk89q/worldedit/Extent.java
rename to src/main/java/com/sk89q/worldedit/extent/Extent.java
index 284a35603..6047f1e41 100644
--- a/src/main/java/com/sk89q/worldedit/Extent.java
+++ b/src/main/java/com/sk89q/worldedit/extent/Extent.java
@@ -17,8 +17,10 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit;
+package com.sk89q.worldedit.extent;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
diff --git a/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java b/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
index 741bac613..06074cb16 100644
--- a/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
+++ b/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
@@ -20,7 +20,6 @@
package com.sk89q.worldedit.extent;
import com.sk89q.worldedit.BlockVector;
-import com.sk89q.worldedit.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
diff --git a/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
index a3d80e6eb..b4162929a 100644
--- a/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
+++ b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.block;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
diff --git a/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java b/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
index c0ba48fae..af28924a9 100644
--- a/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
+++ b/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.block;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java b/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java
index 4d90b4e43..7e11ece0c 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/AbstractExtentMask.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
index 4228b0deb..875f9f0ac 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
index b2fe813df..47d11a177 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java
index 10251e172..b08d53cb9 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/FuzzyBlockMask.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
diff --git a/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java b/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
index fb0607637..8769236c0 100644
--- a/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
+++ b/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.mask;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType;
diff --git a/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
index f768ee73f..c0262bd5e 100644
--- a/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
+++ b/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java
@@ -19,7 +19,7 @@
package com.sk89q.worldedit.function.operation;
-import com.sk89q.worldedit.Extent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.CombinedRegionFunction;
From b07fd594e926f1d00706b26aead5889206060041 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 12:13:45 -0700
Subject: [PATCH 056/106] Moved interpolation, filtering packages to math.
---
.../java/com/sk89q/worldedit/EditSession.java | 6 +-
.../java/com/sk89q/worldedit/HeightMap.java | 2 +-
.../worldedit/commands/RegionCommands.java | 4 +-
.../convolution}/GaussianKernel.java | 114 ++++-----
.../convolution}/HeightMapFilter.java | 240 +++++++++---------
.../convolution}/LinearKernel.java | 88 +++----
.../interpolation/Interpolation.java | 2 +-
.../KochanekBartelsInterpolation.java | 2 +-
.../interpolation/LinearInterpolation.java | 2 +-
.../{ => math}/interpolation/Node.java | 2 +-
.../ReparametrisingInterpolation.java | 2 +-
.../worldedit/tools/brushes/SmoothBrush.java | 4 +-
12 files changed, 234 insertions(+), 234 deletions(-)
rename src/main/java/com/sk89q/worldedit/{filtering => math/convolution}/GaussianKernel.java (94%)
rename src/main/java/com/sk89q/worldedit/{filtering => math/convolution}/HeightMapFilter.java (95%)
rename src/main/java/com/sk89q/worldedit/{filtering => math/convolution}/LinearKernel.java (93%)
rename src/main/java/com/sk89q/worldedit/{ => math}/interpolation/Interpolation.java (97%)
rename src/main/java/com/sk89q/worldedit/{ => math}/interpolation/KochanekBartelsInterpolation.java (99%)
rename src/main/java/com/sk89q/worldedit/{ => math}/interpolation/LinearInterpolation.java (98%)
rename src/main/java/com/sk89q/worldedit/{ => math}/interpolation/Node.java (97%)
rename src/main/java/com/sk89q/worldedit/{ => math}/interpolation/ReparametrisingInterpolation.java (98%)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 4442de0c4..4c7d09e74 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -44,9 +44,9 @@ import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
-import com.sk89q.worldedit.interpolation.Interpolation;
-import com.sk89q.worldedit.interpolation.KochanekBartelsInterpolation;
-import com.sk89q.worldedit.interpolation.Node;
+import com.sk89q.worldedit.math.interpolation.Interpolation;
+import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
+import com.sk89q.worldedit.math.interpolation.Node;
import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.math.transform.AffineTransform;
diff --git a/src/main/java/com/sk89q/worldedit/HeightMap.java b/src/main/java/com/sk89q/worldedit/HeightMap.java
index d7f786599..7ac34b8a8 100644
--- a/src/main/java/com/sk89q/worldedit/HeightMap.java
+++ b/src/main/java/com/sk89q/worldedit/HeightMap.java
@@ -21,7 +21,7 @@ package com.sk89q.worldedit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.filtering.HeightMapFilter;
+import com.sk89q.worldedit.math.convolution.HeightMapFilter;
import com.sk89q.worldedit.regions.Region;
/**
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index bc72cdb3d..c748a7926 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -27,8 +27,8 @@ import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.expression.ExpressionException;
-import com.sk89q.worldedit.filtering.GaussianKernel;
-import com.sk89q.worldedit.filtering.HeightMapFilter;
+import com.sk89q.worldedit.math.convolution.GaussianKernel;
+import com.sk89q.worldedit.math.convolution.HeightMapFilter;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.generator.FloraGenerator;
import com.sk89q.worldedit.function.generator.ForestGenerator;
diff --git a/src/main/java/com/sk89q/worldedit/filtering/GaussianKernel.java b/src/main/java/com/sk89q/worldedit/math/convolution/GaussianKernel.java
similarity index 94%
rename from src/main/java/com/sk89q/worldedit/filtering/GaussianKernel.java
rename to src/main/java/com/sk89q/worldedit/math/convolution/GaussianKernel.java
index 2aa4ac957..44813a426 100644
--- a/src/main/java/com/sk89q/worldedit/filtering/GaussianKernel.java
+++ b/src/main/java/com/sk89q/worldedit/math/convolution/GaussianKernel.java
@@ -1,57 +1,57 @@
-// $Id$
-/*
- * WorldEditLibrary
- * Copyright (C) 2010 sk89q and contributors
- *
- * 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.filtering;
-
-import java.awt.image.Kernel;
-
-/**
- * A Gaussian Kernel generator (2D bellcurve)
- *
- * @author Grum
- */
-
-public class GaussianKernel extends Kernel {
-
- /**
- * Constructor of the kernel
- *
- * @param radius the resulting diameter will be radius * 2 + 1
- * @param sigma controls 'flatness'
- */
-
- public GaussianKernel(int radius, double sigma) {
- super(radius * 2 + 1, radius * 2 + 1, createKernel(radius, sigma));
- }
-
- private static float[] createKernel(int radius, double sigma) {
- int diameter = radius * 2 + 1;
- float[] data = new float[diameter * diameter];
-
- double sigma22 = 2 * sigma * sigma;
- double constant = Math.PI * sigma22;
- for (int y = -radius; y <= radius; ++y) {
- for (int x = -radius; x <= radius; ++x) {
- data[(y + radius) * diameter + x + radius] = (float) (Math.exp(-(x * x + y * y) / sigma22) / constant);
- }
- }
-
- return data;
- }
-}
+// $Id$
+/*
+ * WorldEditLibrary
+ * Copyright (C) 2010 sk89q and contributors
+ *
+ * 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.math.convolution;
+
+import java.awt.image.Kernel;
+
+/**
+ * A Gaussian Kernel generator (2D bellcurve)
+ *
+ * @author Grum
+ */
+
+public class GaussianKernel extends Kernel {
+
+ /**
+ * Constructor of the kernel
+ *
+ * @param radius the resulting diameter will be radius * 2 + 1
+ * @param sigma controls 'flatness'
+ */
+
+ public GaussianKernel(int radius, double sigma) {
+ super(radius * 2 + 1, radius * 2 + 1, createKernel(radius, sigma));
+ }
+
+ private static float[] createKernel(int radius, double sigma) {
+ int diameter = radius * 2 + 1;
+ float[] data = new float[diameter * diameter];
+
+ double sigma22 = 2 * sigma * sigma;
+ double constant = Math.PI * sigma22;
+ for (int y = -radius; y <= radius; ++y) {
+ for (int x = -radius; x <= radius; ++x) {
+ data[(y + radius) * diameter + x + radius] = (float) (Math.exp(-(x * x + y * y) / sigma22) / constant);
+ }
+ }
+
+ return data;
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/filtering/HeightMapFilter.java b/src/main/java/com/sk89q/worldedit/math/convolution/HeightMapFilter.java
similarity index 95%
rename from src/main/java/com/sk89q/worldedit/filtering/HeightMapFilter.java
rename to src/main/java/com/sk89q/worldedit/math/convolution/HeightMapFilter.java
index 8078f5f7f..3f802f295 100644
--- a/src/main/java/com/sk89q/worldedit/filtering/HeightMapFilter.java
+++ b/src/main/java/com/sk89q/worldedit/math/convolution/HeightMapFilter.java
@@ -1,120 +1,120 @@
-// $Id$
-/*
- * WorldEditLibrary
- * Copyright (C) 2010 sk89q and contributors
- *
- * 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.filtering;
-
-import java.awt.image.Kernel;
-
-/**
- * Allows applications of Kernels onto the region's heightmap.
- * Only used for smoothing (with a GaussianKernel).
- *
- * @author Grum
- */
-
-public class HeightMapFilter {
- private Kernel kernel;
-
- /**
- * Construct the HeightMapFilter object.
- *
- * @param kernel
- */
- public HeightMapFilter(Kernel kernel) {
- this.kernel = kernel;
- }
-
- /**
- * Construct the HeightMapFilter object.
- *
- * @param kernelWidth
- * @param kernelHeight
- * @param kernelData
- */
- public HeightMapFilter(int kernelWidth, int kernelHeight, float[] kernelData) {
- this.kernel = new Kernel(kernelWidth, kernelHeight, kernelData);
- }
-
- /**
- * @return the kernel
- */
- public Kernel getKernel() {
- return kernel;
- }
-
- /**
- * Set Kernel
- *
- * @param kernel
- */
- public void setKernel(Kernel kernel) {
- this.kernel = kernel;
- }
-
- /**
- * Filter with a 2D kernel
- *
- * @param inData
- * @param width
- * @param height
- * @return the modified heightmap
- */
- public int[] filter(int[] inData, int width, int height) {
- int index = 0;
- float[] matrix = kernel.getKernelData(null);
- int[] outData = new int[inData.length];
-
- int kh = kernel.getHeight();
- int kw = kernel.getWidth();
- int kox = kernel.getXOrigin();
- int koy = kernel.getYOrigin();
-
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- float z = 0;
-
- for (int ky = 0; ky < kh; ++ky) {
- int offsetY = y + ky - koy;
- // Clamp coordinates inside data
- if (offsetY < 0 || offsetY >= height) {
- offsetY = y;
- }
-
- offsetY *= width;
-
- int matrixOffset = ky * kw;
- for (int kx = 0; kx < kw; ++kx) {
- float f = matrix[matrixOffset + kx];
- if (f == 0) continue;
-
- int offsetX = x + kx - kox;
- // Clamp coordinates inside data
- if (offsetX < 0 || offsetX >= width) {
- offsetX = x;
- }
-
- z += f * inData[offsetY + offsetX];
- }
- }
- outData[index++] = (int) (z + 0.5);
- }
- }
- return outData;
- }
-}
+// $Id$
+/*
+ * WorldEditLibrary
+ * Copyright (C) 2010 sk89q and contributors
+ *
+ * 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.math.convolution;
+
+import java.awt.image.Kernel;
+
+/**
+ * Allows applications of Kernels onto the region's heightmap.
+ * Only used for smoothing (with a GaussianKernel).
+ *
+ * @author Grum
+ */
+
+public class HeightMapFilter {
+ private Kernel kernel;
+
+ /**
+ * Construct the HeightMapFilter object.
+ *
+ * @param kernel
+ */
+ public HeightMapFilter(Kernel kernel) {
+ this.kernel = kernel;
+ }
+
+ /**
+ * Construct the HeightMapFilter object.
+ *
+ * @param kernelWidth
+ * @param kernelHeight
+ * @param kernelData
+ */
+ public HeightMapFilter(int kernelWidth, int kernelHeight, float[] kernelData) {
+ this.kernel = new Kernel(kernelWidth, kernelHeight, kernelData);
+ }
+
+ /**
+ * @return the kernel
+ */
+ public Kernel getKernel() {
+ return kernel;
+ }
+
+ /**
+ * Set Kernel
+ *
+ * @param kernel
+ */
+ public void setKernel(Kernel kernel) {
+ this.kernel = kernel;
+ }
+
+ /**
+ * Filter with a 2D kernel
+ *
+ * @param inData
+ * @param width
+ * @param height
+ * @return the modified heightmap
+ */
+ public int[] filter(int[] inData, int width, int height) {
+ int index = 0;
+ float[] matrix = kernel.getKernelData(null);
+ int[] outData = new int[inData.length];
+
+ int kh = kernel.getHeight();
+ int kw = kernel.getWidth();
+ int kox = kernel.getXOrigin();
+ int koy = kernel.getYOrigin();
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ float z = 0;
+
+ for (int ky = 0; ky < kh; ++ky) {
+ int offsetY = y + ky - koy;
+ // Clamp coordinates inside data
+ if (offsetY < 0 || offsetY >= height) {
+ offsetY = y;
+ }
+
+ offsetY *= width;
+
+ int matrixOffset = ky * kw;
+ for (int kx = 0; kx < kw; ++kx) {
+ float f = matrix[matrixOffset + kx];
+ if (f == 0) continue;
+
+ int offsetX = x + kx - kox;
+ // Clamp coordinates inside data
+ if (offsetX < 0 || offsetX >= width) {
+ offsetX = x;
+ }
+
+ z += f * inData[offsetY + offsetX];
+ }
+ }
+ outData[index++] = (int) (z + 0.5);
+ }
+ }
+ return outData;
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/filtering/LinearKernel.java b/src/main/java/com/sk89q/worldedit/math/convolution/LinearKernel.java
similarity index 93%
rename from src/main/java/com/sk89q/worldedit/filtering/LinearKernel.java
rename to src/main/java/com/sk89q/worldedit/math/convolution/LinearKernel.java
index ea8aa98ab..1f52474ee 100644
--- a/src/main/java/com/sk89q/worldedit/filtering/LinearKernel.java
+++ b/src/main/java/com/sk89q/worldedit/math/convolution/LinearKernel.java
@@ -1,44 +1,44 @@
-// $Id$
-/*
- * WorldEditLibrary
- * Copyright (C) 2010 sk89q and contributors
- *
- * 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.filtering;
-
-import java.awt.image.Kernel;
-
-/**
- * A linear Kernel generator (all cells weight the same)
- *
- * @author Grum
- */
-
-public class LinearKernel extends Kernel {
-
- public LinearKernel(int radius) {
- super(radius * 2 + 1, radius * 2 + 1, createKernel(radius));
- }
-
- private static float[] createKernel(int radius) {
- int diameter = radius * 2 + 1;
- float[] data = new float[diameter * diameter];
-
- for (int i = 0; i < data.length; data[i++] = 1.0f / data.length) ;
-
- return data;
- }
-}
+// $Id$
+/*
+ * WorldEditLibrary
+ * Copyright (C) 2010 sk89q and contributors
+ *
+ * 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.math.convolution;
+
+import java.awt.image.Kernel;
+
+/**
+ * A linear Kernel generator (all cells weight the same)
+ *
+ * @author Grum
+ */
+
+public class LinearKernel extends Kernel {
+
+ public LinearKernel(int radius) {
+ super(radius * 2 + 1, radius * 2 + 1, createKernel(radius));
+ }
+
+ private static float[] createKernel(int radius) {
+ int diameter = radius * 2 + 1;
+ float[] data = new float[diameter * diameter];
+
+ for (int i = 0; i < data.length; data[i++] = 1.0f / data.length) ;
+
+ return data;
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/interpolation/Interpolation.java b/src/main/java/com/sk89q/worldedit/math/interpolation/Interpolation.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/interpolation/Interpolation.java
rename to src/main/java/com/sk89q/worldedit/math/interpolation/Interpolation.java
index 62d1412e2..c07d72860 100644
--- a/src/main/java/com/sk89q/worldedit/interpolation/Interpolation.java
+++ b/src/main/java/com/sk89q/worldedit/math/interpolation/Interpolation.java
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.interpolation;
+package com.sk89q.worldedit.math.interpolation;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/interpolation/KochanekBartelsInterpolation.java b/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java
similarity index 99%
rename from src/main/java/com/sk89q/worldedit/interpolation/KochanekBartelsInterpolation.java
rename to src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java
index 72dd305d3..81a338011 100644
--- a/src/main/java/com/sk89q/worldedit/interpolation/KochanekBartelsInterpolation.java
+++ b/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.interpolation;
+package com.sk89q.worldedit.math.interpolation;
import java.util.Collections;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/interpolation/LinearInterpolation.java b/src/main/java/com/sk89q/worldedit/math/interpolation/LinearInterpolation.java
similarity index 98%
rename from src/main/java/com/sk89q/worldedit/interpolation/LinearInterpolation.java
rename to src/main/java/com/sk89q/worldedit/math/interpolation/LinearInterpolation.java
index 68fb2aaad..0da212a8d 100644
--- a/src/main/java/com/sk89q/worldedit/interpolation/LinearInterpolation.java
+++ b/src/main/java/com/sk89q/worldedit/math/interpolation/LinearInterpolation.java
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.interpolation;
+package com.sk89q.worldedit.math.interpolation;
import java.util.List;
diff --git a/src/main/java/com/sk89q/worldedit/interpolation/Node.java b/src/main/java/com/sk89q/worldedit/math/interpolation/Node.java
similarity index 97%
rename from src/main/java/com/sk89q/worldedit/interpolation/Node.java
rename to src/main/java/com/sk89q/worldedit/math/interpolation/Node.java
index 6e1a53e18..d4ccbf5a6 100644
--- a/src/main/java/com/sk89q/worldedit/interpolation/Node.java
+++ b/src/main/java/com/sk89q/worldedit/math/interpolation/Node.java
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.interpolation;
+package com.sk89q.worldedit.math.interpolation;
import com.sk89q.worldedit.Vector;
diff --git a/src/main/java/com/sk89q/worldedit/interpolation/ReparametrisingInterpolation.java b/src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java
similarity index 98%
rename from src/main/java/com/sk89q/worldedit/interpolation/ReparametrisingInterpolation.java
rename to src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java
index 047a38df1..6fe515762 100644
--- a/src/main/java/com/sk89q/worldedit/interpolation/ReparametrisingInterpolation.java
+++ b/src/main/java/com/sk89q/worldedit/math/interpolation/ReparametrisingInterpolation.java
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.interpolation;
+package com.sk89q.worldedit.math.interpolation;
import java.util.List;
import java.util.Map.Entry;
diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java b/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java
index cd8bde553..06911372c 100644
--- a/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java
+++ b/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java
@@ -24,8 +24,8 @@ import com.sk89q.worldedit.HeightMap;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldVector;
-import com.sk89q.worldedit.filtering.GaussianKernel;
-import com.sk89q.worldedit.filtering.HeightMapFilter;
+import com.sk89q.worldedit.math.convolution.GaussianKernel;
+import com.sk89q.worldedit.math.convolution.HeightMapFilter;
import com.sk89q.worldedit.patterns.Pattern;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
From dd3f32b8f1f53869a273bb1fe518f3db0680c2f1 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 12:15:39 -0700
Subject: [PATCH 057/106] Moved HeightMap to math.convolution.
---
.../worldedit/commands/RegionCommands.java | 1 +
.../{ => math/convolution}/HeightMap.java | 360 +++++++++---------
.../worldedit/tools/brushes/SmoothBrush.java | 2 +-
3 files changed, 183 insertions(+), 180 deletions(-)
rename src/main/java/com/sk89q/worldedit/{ => math/convolution}/HeightMap.java (95%)
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index c748a7926..74748c60b 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -28,6 +28,7 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.expression.ExpressionException;
import com.sk89q.worldedit.math.convolution.GaussianKernel;
+import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.math.convolution.HeightMapFilter;
import com.sk89q.worldedit.function.GroundFunction;
import com.sk89q.worldedit.function.generator.FloraGenerator;
diff --git a/src/main/java/com/sk89q/worldedit/HeightMap.java b/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
similarity index 95%
rename from src/main/java/com/sk89q/worldedit/HeightMap.java
rename to src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
index 7ac34b8a8..e1ced85df 100644
--- a/src/main/java/com/sk89q/worldedit/HeightMap.java
+++ b/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java
@@ -1,179 +1,181 @@
-// $Id$
-/*
- * WorldEditLibrary
- * Copyright (C) 2010 sk89q and contributors
- *
- * 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;
-
-import com.sk89q.worldedit.blocks.BaseBlock;
-import com.sk89q.worldedit.blocks.BlockID;
-import com.sk89q.worldedit.math.convolution.HeightMapFilter;
-import com.sk89q.worldedit.regions.Region;
-
-/**
- * Allows applications of Kernels onto the region's heightmap.
- * Currently only used for smoothing (with a GaussianKernel).
- *
- * @author Grum
- */
-
-public class HeightMap {
- private int[] data;
- private int width;
- private int height;
-
- private Region region;
- private EditSession session;
-
- /**
- * Constructs the HeightMap
- *
- * @param session
- * @param region
- */
- public HeightMap(EditSession session, Region region) {
- this(session, region, false);
- }
-
- /**
- * Constructs the HeightMap
- *
- * @param session
- * @param region
- * @param naturalOnly ignore non-natural blocks
- */
- public HeightMap(EditSession session, Region region, boolean naturalOnly) {
- this.session = session;
- this.region = region;
-
- this.width = region.getWidth();
- this.height = region.getLength();
-
- int minX = region.getMinimumPoint().getBlockX();
- int minY = region.getMinimumPoint().getBlockY();
- int minZ = region.getMinimumPoint().getBlockZ();
- int maxY = region.getMaximumPoint().getBlockY();
-
- // Store current heightmap data
- data = new int[width * height];
- for (int z = 0; z < height; ++z) {
- for (int x = 0; x < width; ++x) {
- data[z * width + x] = session.getHighestTerrainBlock(x + minX, z + minZ, minY, maxY, naturalOnly);
- }
- }
- }
-
- /**
- * Apply the filter 'iterations' amount times.
- *
- * @param filter
- * @param iterations
- * @return number of blocks affected
- * @throws MaxChangedBlocksException
- */
-
- public int applyFilter(HeightMapFilter filter, int iterations) throws MaxChangedBlocksException {
- int[] newData = new int[data.length];
- System.arraycopy(data, 0, newData, 0, data.length);
-
- for (int i = 0; i < iterations; ++i) {
- newData = filter.filter(newData, width, height);
- }
-
- return apply(newData);
- }
-
- /**
- * Apply a raw heightmap to the region
- *
- * @param data
- * @return number of blocks affected
- * @throws MaxChangedBlocksException
- */
-
- public int apply(int[] data) throws MaxChangedBlocksException {
- Vector minY = region.getMinimumPoint();
- int originX = minY.getBlockX();
- int originY = minY.getBlockY();
- int originZ = minY.getBlockZ();
-
- int maxY = region.getMaximumPoint().getBlockY();
- BaseBlock fillerAir = new BaseBlock(BlockID.AIR);
-
- int blocksChanged = 0;
-
- // Apply heightmap
- for (int z = 0; z < height; ++z) {
- for (int x = 0; x < width; ++x) {
- int index = z * width + x;
- int curHeight = this.data[index];
-
- // Clamp newHeight within the selection area
- int newHeight = Math.min(maxY, data[index]);
-
- // Offset x,z to be 'real' coordinates
- int X = x + originX;
- int Z = z + originZ;
-
- // We are keeping the topmost blocks so take that in account for the scale
- double scale = (double) (curHeight - originY) / (double) (newHeight - originY);
-
- // Depending on growing or shrinking we need to start at the bottom or top
- if (newHeight > curHeight) {
- // Set the top block of the column to be the same type (this might go wrong with rounding)
- BaseBlock existing = session.getBlock(new Vector(X, curHeight, Z));
-
- // Skip water/lava
- if (existing.getType() != BlockID.WATER && existing.getType() != BlockID.STATIONARY_WATER
- && existing.getType() != BlockID.LAVA && existing.getType() != BlockID.STATIONARY_LAVA) {
- session.setBlock(new Vector(X, newHeight, Z), existing);
- ++blocksChanged;
-
- // Grow -- start from 1 below top replacing airblocks
- for (int y = newHeight - 1 - originY; y >= 0; --y) {
- int copyFrom = (int) (y * scale);
- session.setBlock(new Vector(X, originY + y, Z), session.getBlock(new Vector(X, originY + copyFrom, Z)));
- ++blocksChanged;
- }
- }
- } else if (curHeight > newHeight) {
- // Shrink -- start from bottom
- for (int y = 0; y < newHeight - originY; ++y) {
- int copyFrom = (int) (y * scale);
- session.setBlock(new Vector(X, originY + y, Z), session.getBlock(new Vector(X, originY + copyFrom, Z)));
- ++blocksChanged;
- }
-
- // Set the top block of the column to be the same type
- // (this could otherwise go wrong with rounding)
- session.setBlock(new Vector(X, newHeight, Z), session.getBlock(new Vector(X, curHeight, Z)));
- ++blocksChanged;
-
- // Fill rest with air
- for (int y = newHeight + 1; y <= curHeight; ++y) {
- session.setBlock(new Vector(X, y, Z), fillerAir);
- ++blocksChanged;
- }
- }
- }
- }
-
- // Drop trees to the floor -- TODO
-
- return blocksChanged;
- }
-}
+// $Id$
+/*
+ * WorldEditLibrary
+ * Copyright (C) 2010 sk89q and contributors
+ *
+ * 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.math.convolution;
+
+import com.sk89q.worldedit.EditSession;
+import com.sk89q.worldedit.MaxChangedBlocksException;
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.blocks.BlockID;
+import com.sk89q.worldedit.regions.Region;
+
+/**
+ * Allows applications of Kernels onto the region's heightmap.
+ * Currently only used for smoothing (with a GaussianKernel).
+ *
+ * @author Grum
+ */
+
+public class HeightMap {
+ private int[] data;
+ private int width;
+ private int height;
+
+ private Region region;
+ private EditSession session;
+
+ /**
+ * Constructs the HeightMap
+ *
+ * @param session
+ * @param region
+ */
+ public HeightMap(EditSession session, Region region) {
+ this(session, region, false);
+ }
+
+ /**
+ * Constructs the HeightMap
+ *
+ * @param session
+ * @param region
+ * @param naturalOnly ignore non-natural blocks
+ */
+ public HeightMap(EditSession session, Region region, boolean naturalOnly) {
+ this.session = session;
+ this.region = region;
+
+ this.width = region.getWidth();
+ this.height = region.getLength();
+
+ int minX = region.getMinimumPoint().getBlockX();
+ int minY = region.getMinimumPoint().getBlockY();
+ int minZ = region.getMinimumPoint().getBlockZ();
+ int maxY = region.getMaximumPoint().getBlockY();
+
+ // Store current heightmap data
+ data = new int[width * height];
+ for (int z = 0; z < height; ++z) {
+ for (int x = 0; x < width; ++x) {
+ data[z * width + x] = session.getHighestTerrainBlock(x + minX, z + minZ, minY, maxY, naturalOnly);
+ }
+ }
+ }
+
+ /**
+ * Apply the filter 'iterations' amount times.
+ *
+ * @param filter
+ * @param iterations
+ * @return number of blocks affected
+ * @throws MaxChangedBlocksException
+ */
+
+ public int applyFilter(HeightMapFilter filter, int iterations) throws MaxChangedBlocksException {
+ int[] newData = new int[data.length];
+ System.arraycopy(data, 0, newData, 0, data.length);
+
+ for (int i = 0; i < iterations; ++i) {
+ newData = filter.filter(newData, width, height);
+ }
+
+ return apply(newData);
+ }
+
+ /**
+ * Apply a raw heightmap to the region
+ *
+ * @param data
+ * @return number of blocks affected
+ * @throws MaxChangedBlocksException
+ */
+
+ public int apply(int[] data) throws MaxChangedBlocksException {
+ Vector minY = region.getMinimumPoint();
+ int originX = minY.getBlockX();
+ int originY = minY.getBlockY();
+ int originZ = minY.getBlockZ();
+
+ int maxY = region.getMaximumPoint().getBlockY();
+ BaseBlock fillerAir = new BaseBlock(BlockID.AIR);
+
+ int blocksChanged = 0;
+
+ // Apply heightmap
+ for (int z = 0; z < height; ++z) {
+ for (int x = 0; x < width; ++x) {
+ int index = z * width + x;
+ int curHeight = this.data[index];
+
+ // Clamp newHeight within the selection area
+ int newHeight = Math.min(maxY, data[index]);
+
+ // Offset x,z to be 'real' coordinates
+ int X = x + originX;
+ int Z = z + originZ;
+
+ // We are keeping the topmost blocks so take that in account for the scale
+ double scale = (double) (curHeight - originY) / (double) (newHeight - originY);
+
+ // Depending on growing or shrinking we need to start at the bottom or top
+ if (newHeight > curHeight) {
+ // Set the top block of the column to be the same type (this might go wrong with rounding)
+ BaseBlock existing = session.getBlock(new Vector(X, curHeight, Z));
+
+ // Skip water/lava
+ if (existing.getType() != BlockID.WATER && existing.getType() != BlockID.STATIONARY_WATER
+ && existing.getType() != BlockID.LAVA && existing.getType() != BlockID.STATIONARY_LAVA) {
+ session.setBlock(new Vector(X, newHeight, Z), existing);
+ ++blocksChanged;
+
+ // Grow -- start from 1 below top replacing airblocks
+ for (int y = newHeight - 1 - originY; y >= 0; --y) {
+ int copyFrom = (int) (y * scale);
+ session.setBlock(new Vector(X, originY + y, Z), session.getBlock(new Vector(X, originY + copyFrom, Z)));
+ ++blocksChanged;
+ }
+ }
+ } else if (curHeight > newHeight) {
+ // Shrink -- start from bottom
+ for (int y = 0; y < newHeight - originY; ++y) {
+ int copyFrom = (int) (y * scale);
+ session.setBlock(new Vector(X, originY + y, Z), session.getBlock(new Vector(X, originY + copyFrom, Z)));
+ ++blocksChanged;
+ }
+
+ // Set the top block of the column to be the same type
+ // (this could otherwise go wrong with rounding)
+ session.setBlock(new Vector(X, newHeight, Z), session.getBlock(new Vector(X, curHeight, Z)));
+ ++blocksChanged;
+
+ // Fill rest with air
+ for (int y = newHeight + 1; y <= curHeight; ++y) {
+ session.setBlock(new Vector(X, y, Z), fillerAir);
+ ++blocksChanged;
+ }
+ }
+ }
+ }
+
+ // Drop trees to the floor -- TODO
+
+ return blocksChanged;
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java b/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java
index 06911372c..27a41c0c1 100644
--- a/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java
+++ b/src/main/java/com/sk89q/worldedit/tools/brushes/SmoothBrush.java
@@ -20,7 +20,7 @@
package com.sk89q.worldedit.tools.brushes;
import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.HeightMap;
+import com.sk89q.worldedit.math.convolution.HeightMap;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldVector;
From e7f7d17f25c5ffc3346558b620e6ca28c8803f50 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 12:27:10 -0700
Subject: [PATCH 058/106] Moved DocumentationPrinter to internal.util.
---
.../util}/DocumentationPrinter.java | 418 +++++++++---------
1 file changed, 209 insertions(+), 209 deletions(-)
rename src/main/java/com/sk89q/worldedit/{dev => internal/util}/DocumentationPrinter.java (96%)
diff --git a/src/main/java/com/sk89q/worldedit/dev/DocumentationPrinter.java b/src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java
similarity index 96%
rename from src/main/java/com/sk89q/worldedit/dev/DocumentationPrinter.java
rename to src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java
index 0a738d34c..86e6cb976 100644
--- a/src/main/java/com/sk89q/worldedit/dev/DocumentationPrinter.java
+++ b/src/main/java/com/sk89q/worldedit/internal/util/DocumentationPrinter.java
@@ -1,209 +1,209 @@
-// $Id$
-/*
- * WorldEditLibrary
- * Copyright (C) 2010 sk89q and contributors
- *
- * 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.dev;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import com.sk89q.minecraft.util.commands.Command;
-import com.sk89q.minecraft.util.commands.CommandPermissions;
-import com.sk89q.minecraft.util.commands.NestedCommand;
-import com.sk89q.worldedit.commands.BiomeCommands;
-import com.sk89q.worldedit.commands.ChunkCommands;
-import com.sk89q.worldedit.commands.ClipboardCommands;
-import com.sk89q.worldedit.commands.GeneralCommands;
-import com.sk89q.worldedit.commands.GenerationCommands;
-import com.sk89q.worldedit.commands.HistoryCommands;
-import com.sk89q.worldedit.commands.NavigationCommands;
-import com.sk89q.worldedit.commands.RegionCommands;
-import com.sk89q.worldedit.commands.ScriptingCommands;
-import com.sk89q.worldedit.commands.SelectionCommands;
-import com.sk89q.worldedit.commands.SnapshotUtilCommands;
-import com.sk89q.worldedit.commands.ToolCommands;
-import com.sk89q.worldedit.commands.ToolUtilCommands;
-import com.sk89q.worldedit.commands.UtilityCommands;
-
-public class DocumentationPrinter {
- public static void main(String[] args) throws IOException {
- File commandsDir = new File(args[0]);
-
- List> commandClasses = getCommandClasses(commandsDir);
-
- System.out.println("Writing permissions wiki table...");
- writePermissionsWikiTable(commandClasses);
- System.out.println("Writing Bukkit plugin.yml...");
- writeBukkitYAML();
-
- System.out.println("Done!");
- }
-
- private static List> getCommandClasses(File dir) {
- List> classes = new ArrayList>();
-
- classes.add(BiomeCommands.class);
- classes.add(ChunkCommands.class);
- classes.add(ClipboardCommands.class);
- classes.add(GeneralCommands.class);
- classes.add(GenerationCommands.class);
- classes.add(HistoryCommands.class);
- classes.add(NavigationCommands.class);
- classes.add(RegionCommands.class);
- classes.add(ScriptingCommands.class);
- classes.add(SelectionCommands.class);
- classes.add(SnapshotUtilCommands.class);
- classes.add(ToolUtilCommands.class);
- classes.add(ToolCommands.class);
- classes.add(UtilityCommands.class);
-
- /*for (File f : dir.listFiles()) {
- if (!f.getName().matches("^.*\\.java$")) {
- continue;
- }
-
- String className = "com.sk89q.worldedit.commands."
- + f.getName().substring(0, f.getName().lastIndexOf("."));
-
- Class> cls;
- try {
- cls = Class.forName(className, true,
- Thread.currentThread().getContextClassLoader());
- } catch (ClassNotFoundException e) {
- continue;
- }
-
- classes.add(cls);
- }*/
-
- return classes;
- }
-
- private static void writePermissionsWikiTable(List> commandClasses)
- throws IOException {
- FileOutputStream stream = null;
- try {
- stream = new FileOutputStream("wiki_permissions.txt");
- PrintStream print = new PrintStream(stream);
- _writePermissionsWikiTable(print, commandClasses, "/");
- } finally {
- if (stream != null) {
- stream.close();
- }
- }
- }
-
- private static void _writePermissionsWikiTable(PrintStream stream,
- List> commandClasses, String prefix) {
-
- for (Class> cls : commandClasses) {
- for (Method method : cls.getMethods()) {
- if (!method.isAnnotationPresent(Command.class)) {
- continue;
- }
-
- Command cmd = method.getAnnotation(Command.class);
-
- stream.println("|-");
- stream.print("| " + prefix + cmd.aliases()[0]);
- stream.print(" || ");
-
- if (method.isAnnotationPresent(CommandPermissions.class)) {
- CommandPermissions perms =
- method.getAnnotation(CommandPermissions.class);
-
- String[] permKeys = perms.value();
- for (int i = 0; i < permKeys.length; ++i) {
- if (i > 0) {
- stream.print(", ");
- }
- stream.print(permKeys[i]);
- }
- }
-
- stream.print(" || ");
-
- boolean firstAlias = true;
- if (cmd.aliases().length != 0) {
- for (String alias : cmd.aliases()) {
- if (!firstAlias) stream.print("
");
- stream.print(prefix + alias);
- firstAlias = false;
- }
- }
-
- stream.print(" || ");
-
- if (cmd.flags() != null && !cmd.flags().equals("")) {
- stream.print(cmd.flags());
- }
-
- stream.print(" || ");
-
- if (cmd.desc() != null && !cmd.desc().equals("")) {
- stream.print(cmd.desc());
- }
-
- stream.println();
-
- if (method.isAnnotationPresent(NestedCommand.class)) {
- NestedCommand nested =
- method.getAnnotation(NestedCommand.class);
-
- Class>[] nestedClasses = nested.value();
- _writePermissionsWikiTable(stream,
- Arrays.asList(nestedClasses),
- prefix + cmd.aliases()[0] + " ");
- }
- }
- }
- }
-
- private static void writeBukkitYAML()
- throws IOException {
- FileOutputStream stream = null;
- try {
- stream = new FileOutputStream("plugin.yml");
- PrintStream print = new PrintStream(stream);
- _writeBukkitYAML(print);
- } finally {
- if (stream != null) {
- stream.close();
- }
- }
- }
-
- private static void _writeBukkitYAML(PrintStream stream) {
-
- stream.println("name: WorldEdit");
- stream.println("main: com.sk89q.worldedit.bukkit.WorldEditPlugin");
- stream.println("version: ${project.version}");
- stream.println("softdepend: [Spout] #hack to fix trove errors");
-
- stream.println();
- stream.println();
- stream.println("# Permissions aren't here. Read http://wiki.sk89q.com/wiki/WEPIF/DinnerPerms");
- stream.println("# for how WorldEdit permissions actually work.");
- }
-}
+// $Id$
+/*
+ * WorldEditLibrary
+ * Copyright (C) 2010 sk89q and contributors
+ *
+ * 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.internal.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.sk89q.minecraft.util.commands.Command;
+import com.sk89q.minecraft.util.commands.CommandPermissions;
+import com.sk89q.minecraft.util.commands.NestedCommand;
+import com.sk89q.worldedit.commands.BiomeCommands;
+import com.sk89q.worldedit.commands.ChunkCommands;
+import com.sk89q.worldedit.commands.ClipboardCommands;
+import com.sk89q.worldedit.commands.GeneralCommands;
+import com.sk89q.worldedit.commands.GenerationCommands;
+import com.sk89q.worldedit.commands.HistoryCommands;
+import com.sk89q.worldedit.commands.NavigationCommands;
+import com.sk89q.worldedit.commands.RegionCommands;
+import com.sk89q.worldedit.commands.ScriptingCommands;
+import com.sk89q.worldedit.commands.SelectionCommands;
+import com.sk89q.worldedit.commands.SnapshotUtilCommands;
+import com.sk89q.worldedit.commands.ToolCommands;
+import com.sk89q.worldedit.commands.ToolUtilCommands;
+import com.sk89q.worldedit.commands.UtilityCommands;
+
+public class DocumentationPrinter {
+ public static void main(String[] args) throws IOException {
+ File commandsDir = new File(args[0]);
+
+ List> commandClasses = getCommandClasses(commandsDir);
+
+ System.out.println("Writing permissions wiki table...");
+ writePermissionsWikiTable(commandClasses);
+ System.out.println("Writing Bukkit plugin.yml...");
+ writeBukkitYAML();
+
+ System.out.println("Done!");
+ }
+
+ private static List> getCommandClasses(File dir) {
+ List> classes = new ArrayList>();
+
+ classes.add(BiomeCommands.class);
+ classes.add(ChunkCommands.class);
+ classes.add(ClipboardCommands.class);
+ classes.add(GeneralCommands.class);
+ classes.add(GenerationCommands.class);
+ classes.add(HistoryCommands.class);
+ classes.add(NavigationCommands.class);
+ classes.add(RegionCommands.class);
+ classes.add(ScriptingCommands.class);
+ classes.add(SelectionCommands.class);
+ classes.add(SnapshotUtilCommands.class);
+ classes.add(ToolUtilCommands.class);
+ classes.add(ToolCommands.class);
+ classes.add(UtilityCommands.class);
+
+ /*for (File f : dir.listFiles()) {
+ if (!f.getName().matches("^.*\\.java$")) {
+ continue;
+ }
+
+ String className = "com.sk89q.worldedit.commands."
+ + f.getName().substring(0, f.getName().lastIndexOf("."));
+
+ Class> cls;
+ try {
+ cls = Class.forName(className, true,
+ Thread.currentThread().getContextClassLoader());
+ } catch (ClassNotFoundException e) {
+ continue;
+ }
+
+ classes.add(cls);
+ }*/
+
+ return classes;
+ }
+
+ private static void writePermissionsWikiTable(List> commandClasses)
+ throws IOException {
+ FileOutputStream stream = null;
+ try {
+ stream = new FileOutputStream("wiki_permissions.txt");
+ PrintStream print = new PrintStream(stream);
+ _writePermissionsWikiTable(print, commandClasses, "/");
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+ private static void _writePermissionsWikiTable(PrintStream stream,
+ List> commandClasses, String prefix) {
+
+ for (Class> cls : commandClasses) {
+ for (Method method : cls.getMethods()) {
+ if (!method.isAnnotationPresent(Command.class)) {
+ continue;
+ }
+
+ Command cmd = method.getAnnotation(Command.class);
+
+ stream.println("|-");
+ stream.print("| " + prefix + cmd.aliases()[0]);
+ stream.print(" || ");
+
+ if (method.isAnnotationPresent(CommandPermissions.class)) {
+ CommandPermissions perms =
+ method.getAnnotation(CommandPermissions.class);
+
+ String[] permKeys = perms.value();
+ for (int i = 0; i < permKeys.length; ++i) {
+ if (i > 0) {
+ stream.print(", ");
+ }
+ stream.print(permKeys[i]);
+ }
+ }
+
+ stream.print(" || ");
+
+ boolean firstAlias = true;
+ if (cmd.aliases().length != 0) {
+ for (String alias : cmd.aliases()) {
+ if (!firstAlias) stream.print("
");
+ stream.print(prefix + alias);
+ firstAlias = false;
+ }
+ }
+
+ stream.print(" || ");
+
+ if (cmd.flags() != null && !cmd.flags().equals("")) {
+ stream.print(cmd.flags());
+ }
+
+ stream.print(" || ");
+
+ if (cmd.desc() != null && !cmd.desc().equals("")) {
+ stream.print(cmd.desc());
+ }
+
+ stream.println();
+
+ if (method.isAnnotationPresent(NestedCommand.class)) {
+ NestedCommand nested =
+ method.getAnnotation(NestedCommand.class);
+
+ Class>[] nestedClasses = nested.value();
+ _writePermissionsWikiTable(stream,
+ Arrays.asList(nestedClasses),
+ prefix + cmd.aliases()[0] + " ");
+ }
+ }
+ }
+ }
+
+ private static void writeBukkitYAML()
+ throws IOException {
+ FileOutputStream stream = null;
+ try {
+ stream = new FileOutputStream("plugin.yml");
+ PrintStream print = new PrintStream(stream);
+ _writeBukkitYAML(print);
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ }
+
+ private static void _writeBukkitYAML(PrintStream stream) {
+
+ stream.println("name: WorldEdit");
+ stream.println("main: com.sk89q.worldedit.bukkit.WorldEditPlugin");
+ stream.println("version: ${project.version}");
+ stream.println("softdepend: [Spout] #hack to fix trove errors");
+
+ stream.println();
+ stream.println();
+ stream.println("# Permissions aren't here. Read http://wiki.sk89q.com/wiki/WEPIF/DinnerPerms");
+ stream.println("# for how WorldEdit permissions actually work.");
+ }
+}
From f0d97c5231e68cc1c3a7c9bb3d31862ab3c3bf0a Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 12:59:39 -0700
Subject: [PATCH 059/106] Added new Pattern interface.
---
.../java/com/sk89q/worldedit/EditSession.java | 11 +--
.../sk89q/worldedit/extent/ExtentBuffer.java | 9 +-
.../function/block/BlockReplace.java | 4 +-
.../function/generator/FloraGenerator.java | 33 ++++---
.../generator/GardenPatchGenerator.java | 25 +++---
.../function/pattern/AbstractPattern.java | 26 ++++++
.../function/pattern/BlockPattern.java | 67 ++++++++++++++
.../worldedit/function/pattern/Pattern.java | 38 ++++++++
.../worldedit/function/pattern/Patterns.java | 51 +++++++++++
.../function/pattern/RandomPattern.java | 88 +++++++++++++++++++
.../sk89q/worldedit/patterns/BlockChance.java | 5 +-
.../com/sk89q/worldedit/patterns/Pattern.java | 6 +-
.../worldedit/patterns/RandomFillPattern.java | 15 ++--
.../patterns/SingleBlockPattern.java | 6 +-
14 files changed, 321 insertions(+), 63 deletions(-)
create mode 100644 src/main/java/com/sk89q/worldedit/function/pattern/AbstractPattern.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/pattern/BlockPattern.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/pattern/Patterns.java
create mode 100644 src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 4c7d09e74..ef1021570 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -39,6 +39,7 @@ import com.sk89q.worldedit.function.mask.*;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.operation.OperationQueue;
+import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
@@ -831,7 +832,7 @@ public class EditSession implements Extent {
Masks.negate(new ExistingBlockMask(this)));
// Want to replace blocks
- BlockReplace replace = new BlockReplace(this, pattern);
+ BlockReplace replace = new BlockReplace(this, Patterns.wrap(pattern));
// Pick how we're going to visit blocks
RecursiveVisitor visitor;
@@ -941,7 +942,7 @@ public class EditSession implements Extent {
checkNotNull(region);
checkNotNull(pattern);
- BlockReplace replace = new BlockReplace(this, pattern);
+ BlockReplace replace = new BlockReplace(this, Patterns.wrap(pattern));
RegionVisitor visitor = new RegionVisitor(region, replace);
OperationHelper.completeLegacy(visitor);
return visitor.getAffected();
@@ -991,7 +992,7 @@ public class EditSession implements Extent {
checkNotNull(mask);
checkNotNull(pattern);
- BlockReplace replace = new BlockReplace(this, pattern);
+ BlockReplace replace = new BlockReplace(this, Patterns.wrap(pattern));
RegionMaskingFilter filter = new RegionMaskingFilter(Masks.wrap(this, mask), replace);
RegionVisitor visitor = new RegionVisitor(region, filter);
OperationHelper.completeLegacy(visitor);
@@ -1164,7 +1165,7 @@ public class EditSession implements Extent {
checkNotNull(region);
checkNotNull(pattern);
- BlockReplace replace = new BlockReplace(this, pattern);
+ BlockReplace replace = new BlockReplace(this, Patterns.wrap(pattern));
RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
GroundFunction ground = new GroundFunction(this, offset);
LayerVisitor visitor = new LayerVisitor(
@@ -1241,7 +1242,7 @@ public class EditSession implements Extent {
Pattern pattern = replacement != null ?
new SingleBlockPattern(replacement) :
new SingleBlockPattern(new BaseBlock(BlockID.AIR));
- BlockReplace remove = new BlockReplace(this, pattern);
+ BlockReplace remove = new BlockReplace(this, Patterns.wrap(pattern));
// Copy to a buffer so we don't destroy our original before we can copy all the blocks from it
ExtentBuffer buffer = new ExtentBuffer(this, new RegionMask(region));
diff --git a/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java b/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
index 06074cb16..e13594169 100644
--- a/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
+++ b/src/main/java/com/sk89q/worldedit/extent/ExtentBuffer.java
@@ -26,7 +26,7 @@ import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
-import com.sk89q.worldedit.patterns.Pattern;
+import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.regions.AbstractRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionOperationException;
@@ -115,7 +115,7 @@ public class ExtentBuffer implements Extent, Pattern {
}
@Override
- public BaseBlock next(Vector pos) {
+ public BaseBlock apply(Vector pos) {
BaseBlock block = buffer.get(pos.toBlockVector());
if (block != null) {
return block;
@@ -124,11 +124,6 @@ public class ExtentBuffer implements Extent, Pattern {
}
}
- @Override
- public BaseBlock next(int x, int y, int z) {
- return next(new Vector(x, y, z));
- }
-
/**
* Return a region representation of this buffer.
*
diff --git a/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
index b4162929a..c8a5dbedc 100644
--- a/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
+++ b/src/main/java/com/sk89q/worldedit/function/block/BlockReplace.java
@@ -23,7 +23,7 @@ import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
-import com.sk89q.worldedit.patterns.Pattern;
+import com.sk89q.worldedit.function.pattern.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -50,7 +50,7 @@ public class BlockReplace implements RegionFunction {
@Override
public boolean apply(Vector position) throws WorldEditException {
- return extent.setBlock(position, pattern.next(position), true);
+ return extent.setBlock(position, pattern.apply(position), true);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java b/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
index 56085eee6..9eff8bc63 100644
--- a/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/function/generator/FloraGenerator.java
@@ -25,12 +25,9 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.function.RegionFunction;
-import com.sk89q.worldedit.patterns.BlockChance;
-import com.sk89q.worldedit.patterns.Pattern;
-import com.sk89q.worldedit.patterns.RandomFillPattern;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.sk89q.worldedit.function.pattern.BlockPattern;
+import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.function.pattern.RandomPattern;
/**
* Generates flora (which may include tall grass, flowers, etc.).
@@ -85,11 +82,11 @@ public class FloraGenerator implements RegionFunction {
* @return a pattern that places flora
*/
public static Pattern getDesertPattern() {
- List chance = new ArrayList();
- chance.add(new BlockChance(new BaseBlock(BlockID.DEAD_BUSH), 30));
- chance.add(new BlockChance(new BaseBlock(BlockID.CACTUS), 20));
- chance.add(new BlockChance(new BaseBlock(BlockID.AIR), 300));
- return new RandomFillPattern(chance);
+ RandomPattern pattern = new RandomPattern();
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.DEAD_BUSH)), 30);
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.CACTUS)), 20);
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.AIR)), 300);
+ return pattern;
}
/**
@@ -98,11 +95,11 @@ public class FloraGenerator implements RegionFunction {
* @return a pattern that places flora
*/
public static Pattern getTemperatePattern() {
- List chance = new ArrayList();
- chance.add(new BlockChance(new BaseBlock(BlockID.LONG_GRASS, 1), 300));
- chance.add(new BlockChance(new BaseBlock(BlockID.RED_FLOWER), 5));
- chance.add(new BlockChance(new BaseBlock(BlockID.YELLOW_FLOWER), 5));
- return new RandomFillPattern(chance);
+ RandomPattern pattern = new RandomPattern();
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.LONG_GRASS, 1)), 300);
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.RED_FLOWER)), 5);
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.YELLOW_FLOWER)), 5);
+ return pattern;
}
@Override
@@ -110,10 +107,10 @@ public class FloraGenerator implements RegionFunction {
BaseBlock block = editSession.getBlock(position);
if (block.getType() == BlockID.GRASS) {
- editSession.setBlock(position.add(0, 1, 0), temperatePattern.next(position));
+ editSession.setBlock(position.add(0, 1, 0), temperatePattern.apply(position));
return true;
} else if (block.getType() == BlockID.SAND) {
- editSession.setBlock(position.add(0, 1, 0), desertPattern.next(position));
+ editSession.setBlock(position.add(0, 1, 0), desertPattern.apply(position));
return true;
}
diff --git a/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java b/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
index 2a145410b..eb11ed1ae 100644
--- a/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
+++ b/src/main/java/com/sk89q/worldedit/function/generator/GardenPatchGenerator.java
@@ -26,13 +26,10 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.function.RegionFunction;
-import com.sk89q.worldedit.patterns.BlockChance;
-import com.sk89q.worldedit.patterns.Pattern;
-import com.sk89q.worldedit.patterns.RandomFillPattern;
-import com.sk89q.worldedit.patterns.SingleBlockPattern;
+import com.sk89q.worldedit.function.pattern.BlockPattern;
+import com.sk89q.worldedit.function.pattern.Pattern;
+import com.sk89q.worldedit.function.pattern.RandomPattern;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Random;
public class GardenPatchGenerator implements RegionFunction {
@@ -115,7 +112,7 @@ public class GardenPatchGenerator implements RegionFunction {
editSession.setBlockIfAir(pos.add(1, h, -1), log);
affected++;
}
- editSession.setBlockIfAir(p = pos.add(0, 0, -1), plant.next(p));
+ editSession.setBlockIfAir(p = pos.add(0, 0, -1), plant.apply(p));
affected++;
break;
@@ -127,7 +124,7 @@ public class GardenPatchGenerator implements RegionFunction {
editSession.setBlockIfAir(pos.add(1, h, 0), log);
affected++;
}
- editSession.setBlockIfAir(p = pos.add(1, 0, 1), plant.next(p));
+ editSession.setBlockIfAir(p = pos.add(1, 0, 1), plant.apply(p));
affected++;
break;
@@ -139,7 +136,7 @@ public class GardenPatchGenerator implements RegionFunction {
editSession.setBlockIfAir(pos.add(-1, h, 0), log);
affected++;
}
- editSession.setBlockIfAir(p = pos.add(-1, 0, 1), plant.next(p));
+ editSession.setBlockIfAir(p = pos.add(-1, 0, 1), plant.apply(p));
affected++;
break;
@@ -151,7 +148,7 @@ public class GardenPatchGenerator implements RegionFunction {
editSession.setBlockIfAir(pos.add(-1, h, -1), log);
affected++;
}
- editSession.setBlockIfAir(p = pos.add(-1, 0, -1), plant.next(p));
+ editSession.setBlockIfAir(p = pos.add(-1, 0, -1), plant.apply(p));
affected++;
break;
}
@@ -185,11 +182,11 @@ public class GardenPatchGenerator implements RegionFunction {
* @return a pumpkin pattern
*/
public static Pattern getPumpkinPattern() {
- List chance = new ArrayList();
+ RandomPattern pattern = new RandomPattern();
for (int i = 0; i < 4; i++) {
- chance.add(new BlockChance(new BaseBlock(BlockID.PUMPKIN, i), 100));
+ pattern.add(new BlockPattern(new BaseBlock(BlockID.PUMPKIN, i)), 100);
}
- return new RandomFillPattern(chance);
+ return pattern;
}
/**
@@ -198,6 +195,6 @@ public class GardenPatchGenerator implements RegionFunction {
* @return a melon pattern
*/
public static Pattern getMelonPattern() {
- return new SingleBlockPattern(new BaseBlock(BlockID.MELON_BLOCK));
+ return new BlockPattern(new BaseBlock(BlockID.MELON_BLOCK));
}
}
diff --git a/src/main/java/com/sk89q/worldedit/function/pattern/AbstractPattern.java b/src/main/java/com/sk89q/worldedit/function/pattern/AbstractPattern.java
new file mode 100644
index 000000000..bfe05592f
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/pattern/AbstractPattern.java
@@ -0,0 +1,26 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.pattern;
+
+/**
+ * An abstract implementation for {@link Pattern}s.
+ */
+public abstract class AbstractPattern implements Pattern {
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/pattern/BlockPattern.java b/src/main/java/com/sk89q/worldedit/function/pattern/BlockPattern.java
new file mode 100644
index 000000000..ac363d341
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/pattern/BlockPattern.java
@@ -0,0 +1,67 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.pattern;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A pattern that returns the same {@link BaseBlock} each time.
+ */
+public class BlockPattern extends AbstractPattern {
+
+ private BaseBlock block;
+
+ /**
+ * Create a new pattern with the given block.
+ *
+ * @param block the block
+ */
+ public BlockPattern(BaseBlock block) {
+ setBlock(block);
+ }
+
+ /**
+ * Get the block.
+ *
+ * @return the block that is always returned
+ */
+ public BaseBlock getBlock() {
+ return block;
+ }
+
+ /**
+ * Set the block that is returned.
+ *
+ * @param block the block
+ */
+ public void setBlock(BaseBlock block) {
+ checkNotNull(block);
+ this.block = block;
+ }
+
+ @Override
+ public BaseBlock apply(Vector position) {
+ return block;
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java
new file mode 100644
index 000000000..ac51ce464
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java
@@ -0,0 +1,38 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.pattern;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+/**
+ * Returns a {@link BaseBlock} for a given position.
+ */
+public interface Pattern {
+
+ /**
+ * Return a {@link BaseBlock} for the given position.
+ *
+ * @param position the position
+ * @return a block
+ */
+ BaseBlock apply(Vector position);
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/pattern/Patterns.java b/src/main/java/com/sk89q/worldedit/function/pattern/Patterns.java
new file mode 100644
index 000000000..9e42dbe7e
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/pattern/Patterns.java
@@ -0,0 +1,51 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.pattern;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Utility methods related to {@link Pattern}s.
+ */
+public final class Patterns {
+
+ private Patterns() {
+ }
+
+ /**
+ * Wrap an old-style pattern and return a new pattern.
+ *
+ * @param pattern the pattern
+ * @return a new-style pattern
+ */
+ public static Pattern wrap(final com.sk89q.worldedit.patterns.Pattern pattern) {
+ checkNotNull(pattern);
+ return new Pattern() {
+ @Override
+ public BaseBlock apply(Vector position) {
+ return pattern.next(position);
+ }
+ };
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
new file mode 100644
index 000000000..c90dbc534
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
@@ -0,0 +1,88 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * 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 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.function.pattern;
+
+import com.sk89q.worldedit.Vector;
+import com.sk89q.worldedit.blocks.BaseBlock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Uses a random pattern of a weighted list of patterns.
+ */
+public class RandomPattern extends AbstractPattern {
+
+ private final Random random = new Random();
+ private List patterns = new ArrayList();
+ private double max = 0;
+
+ /**
+ * Add a pattern to the weight list of patterns.
+ *
+ * The probability for the pattern added is chance / max where max is the sum
+ * of the probabilities of all added patterns.
+ *
+ * @param pattern the pattern
+ * @param chance the chance, which can be any positive number
+ */
+ public void add(Pattern pattern, double chance) {
+ checkNotNull(pattern);
+ patterns.add(new Chance(pattern, chance));
+ max += chance;
+ }
+
+ @Override
+ public BaseBlock apply(Vector position) {
+ double r = random.nextDouble();
+ double offset = 0;
+
+ for (Chance chance : patterns) {
+ if (r <= (offset + chance.getChance()) / max) {
+ return chance.getPattern().apply(position);
+ }
+ offset += chance.getChance();
+ }
+
+ throw new RuntimeException("ProportionalFillPattern");
+ }
+
+ private static class Chance {
+ private Pattern pattern;
+ private double chance;
+
+ private Chance(Pattern pattern, double chance) {
+ this.pattern = pattern;
+ this.chance = chance;
+ }
+
+ public Pattern getPattern() {
+ return pattern;
+ }
+
+ public double getChance() {
+ return chance;
+ }
+ }
+
+}
diff --git a/src/main/java/com/sk89q/worldedit/patterns/BlockChance.java b/src/main/java/com/sk89q/worldedit/patterns/BlockChance.java
index b8427ae32..a51cacf29 100644
--- a/src/main/java/com/sk89q/worldedit/patterns/BlockChance.java
+++ b/src/main/java/com/sk89q/worldedit/patterns/BlockChance.java
@@ -22,10 +22,9 @@ package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
- * Gives a block a chance.
- *
- * @author sk89q
+ * @deprecated Will be removed in the future -- there is no replacement
*/
+@Deprecated
public class BlockChance {
/**
* Block.
diff --git a/src/main/java/com/sk89q/worldedit/patterns/Pattern.java b/src/main/java/com/sk89q/worldedit/patterns/Pattern.java
index d1ec4a25e..eb2b9f2dc 100644
--- a/src/main/java/com/sk89q/worldedit/patterns/Pattern.java
+++ b/src/main/java/com/sk89q/worldedit/patterns/Pattern.java
@@ -23,11 +23,9 @@ import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
/**
- * Used to get the block to set. This can be used to implement a pattern
- * for when setting a region with blocks.
- *
- * @author sk89q
+ * @deprecated See {@link com.sk89q.worldedit.function.pattern.Pattern}
*/
+@Deprecated
public interface Pattern {
/**
* Get a block for a position. This return value of this method does
diff --git a/src/main/java/com/sk89q/worldedit/patterns/RandomFillPattern.java b/src/main/java/com/sk89q/worldedit/patterns/RandomFillPattern.java
index 5217e4a9e..e322798ba 100644
--- a/src/main/java/com/sk89q/worldedit/patterns/RandomFillPattern.java
+++ b/src/main/java/com/sk89q/worldedit/patterns/RandomFillPattern.java
@@ -19,17 +19,18 @@
package com.sk89q.worldedit.patterns;
-import java.util.Random;
-import java.util.List;
-import java.util.ArrayList;
-import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.function.pattern.RandomPattern;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
/**
- * Pattern proportionally fills.
- *
- * @author sk89q
+ * @deprecated See {@link RandomPattern}
*/
+@Deprecated
public class RandomFillPattern implements Pattern {
/**
* Random number generator.
diff --git a/src/main/java/com/sk89q/worldedit/patterns/SingleBlockPattern.java b/src/main/java/com/sk89q/worldedit/patterns/SingleBlockPattern.java
index f518f8de1..94457610d 100644
--- a/src/main/java/com/sk89q/worldedit/patterns/SingleBlockPattern.java
+++ b/src/main/java/com/sk89q/worldedit/patterns/SingleBlockPattern.java
@@ -21,12 +21,12 @@ package com.sk89q.worldedit.patterns;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.blocks.BaseBlock;
+import com.sk89q.worldedit.function.pattern.BlockPattern;
/**
- * Always returns the same block type.
- *
- * @author sk89q
+ * @deprecated See {@link BlockPattern}
*/
+@Deprecated
public class SingleBlockPattern implements Pattern {
/**
* Block type.
From 25021b4a30db971bfac9062dfd7b90f590794fe6 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 13:46:20 -0700
Subject: [PATCH 060/106] Removed EditSession from RecursiveVisitor.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 8 +++++---
.../worldedit/function/visitor/DownwardVisitor.java | 6 ++----
.../worldedit/function/visitor/LayerVisitor.java | 5 +----
.../worldedit/function/visitor/RecursiveVisitor.java | 11 ++---------
4 files changed, 10 insertions(+), 20 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index ef1021570..69302e1bc 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -828,7 +828,9 @@ public class EditSession implements Extent {
MaskIntersection mask = new MaskIntersection(
new RegionMask(new EllipsoidRegion(null, origin, new Vector(radius, radius, radius))),
- new BoundedHeightMask(origin.getBlockY() - depth + 1, origin.getBlockY()),
+ new BoundedHeightMask(
+ Math.max(origin.getBlockY() - depth + 1, 0),
+ Math.min(getWorld().getMaxY(), origin.getBlockY())),
Masks.negate(new ExistingBlockMask(this)));
// Want to replace blocks
@@ -837,9 +839,9 @@ public class EditSession implements Extent {
// Pick how we're going to visit blocks
RecursiveVisitor visitor;
if (recursive) {
- visitor = new RecursiveVisitor(this, mask, replace);
+ visitor = new RecursiveVisitor(mask, replace);
} else {
- visitor = new DownwardVisitor(this, mask, replace, origin.getBlockY());
+ visitor = new DownwardVisitor(mask, replace, origin.getBlockY());
}
// Start at the origin
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
index 0af12c68e..3533eba0e 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
@@ -19,7 +19,6 @@
package com.sk89q.worldedit.function.visitor;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.Mask;
@@ -40,13 +39,12 @@ public class DownwardVisitor extends RecursiveVisitor {
/**
* Create a new visitor.
*
- * @param editSession the edit session
* @param mask the mask
* @param function the function
* @param baseY the base Y
*/
- public DownwardVisitor(EditSession editSession, Mask mask, RegionFunction function, int baseY) {
- super(editSession, mask, function);
+ public DownwardVisitor(Mask mask, RegionFunction function, int baseY) {
+ super(mask, function);
this.baseY = baseY;
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
index a7500ce74..a51bbc719 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
@@ -42,7 +42,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
public class LayerVisitor implements Operation {
- private final EditSession editSession;
private final FlatRegion flatRegion;
private final LayerFunction function;
private Mask2D mask = Masks.alwaysTrue2D();
@@ -57,13 +56,11 @@ public class LayerVisitor implements Operation {
* @param maxY the maximum Y to begin the search at
* @param function the layer function to apply t blocks
*/
- public LayerVisitor(EditSession editSession, FlatRegion flatRegion, int minY, int maxY, LayerFunction function) {
- checkNotNull(editSession);
+ public LayerVisitor(FlatRegion flatRegion, int minY, int maxY, LayerFunction function) {
checkNotNull(flatRegion);
checkArgument(minY <= maxY, "minY <= maxY required");
checkNotNull(function);
- this.editSession = editSession;
this.flatRegion = flatRegion;
this.minY = minY;
this.maxY = maxY;
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
index 4446c566a..3bb013f6a 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
@@ -19,10 +19,9 @@
package com.sk89q.worldedit.function.visitor;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
-import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.RegionFunction;
+import com.sk89q.worldedit.function.mask.Mask;
/**
* An implementation of an {@link BreadthFirstSearch} that uses a mask to
@@ -30,21 +29,15 @@ import com.sk89q.worldedit.function.RegionFunction;
*/
public class RecursiveVisitor extends BreadthFirstSearch {
- private final EditSession editSession;
private final Mask mask;
- public RecursiveVisitor(EditSession editSession, Mask mask, RegionFunction function) {
+ public RecursiveVisitor(Mask mask, RegionFunction function) {
super(function);
- this.editSession = editSession;
this.mask = mask;
}
@Override
protected boolean isVisitable(Vector from, Vector to) {
- int y = to.getBlockY();
- if (y < 0 || y > editSession.getWorld().getMaxY()) {
- return false;
- }
return mask.test(to);
}
}
From 7dc81f83508c7c588de9870993e256a69e1003f5 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 13:48:15 -0700
Subject: [PATCH 061/106] Added preconditions to BreadthFirstSearch and
subclasses.
---
.../worldedit/function/visitor/BreadthFirstSearch.java | 5 ++++-
.../worldedit/function/visitor/DownwardVisitor.java | 3 +++
.../sk89q/worldedit/function/visitor/LayerVisitor.java | 1 -
.../worldedit/function/visitor/RecursiveVisitor.java | 9 +++++++++
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java b/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
index 153882333..95f099a67 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java
@@ -27,6 +27,8 @@ import com.sk89q.worldedit.function.RegionFunction;
import java.util.*;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Performs a breadth-first search starting from points added with
* {@link #visit(com.sk89q.worldedit.Vector)}. The search continues
@@ -51,7 +53,8 @@ public abstract class BreadthFirstSearch implements Operation {
*
* @param function the function to apply to visited blocks
*/
- public BreadthFirstSearch(RegionFunction function) {
+ protected BreadthFirstSearch(RegionFunction function) {
+ checkNotNull(function);
this.function = function;
addAxes();
}
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
index 3533eba0e..16072b243 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java
@@ -25,6 +25,8 @@ import com.sk89q.worldedit.function.mask.Mask;
import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Visits adjacent points on the same X-Z plane as long as the points
* pass the given mask, and then executes the provided region
@@ -45,6 +47,7 @@ public class DownwardVisitor extends RecursiveVisitor {
*/
public DownwardVisitor(Mask mask, RegionFunction function, int baseY) {
super(mask, function);
+ checkNotNull(mask);
this.baseY = baseY;
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
index a51bbc719..3437ec6d0 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/LayerVisitor.java
@@ -19,7 +19,6 @@
package com.sk89q.worldedit.function.visitor;
-import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
diff --git a/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
index 3bb013f6a..d6531b933 100644
--- a/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
+++ b/src/main/java/com/sk89q/worldedit/function/visitor/RecursiveVisitor.java
@@ -23,6 +23,8 @@ import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.Mask;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* An implementation of an {@link BreadthFirstSearch} that uses a mask to
* determine where a block should be visited.
@@ -31,8 +33,15 @@ public class RecursiveVisitor extends BreadthFirstSearch {
private final Mask mask;
+ /**
+ * Create a new recursive visitor.
+ *
+ * @param mask the mask
+ * @param function the function
+ */
public RecursiveVisitor(Mask mask, RegionFunction function) {
super(function);
+ checkNotNull(mask);
this.mask = mask;
}
From 593a9e555a0ae7fbb8011aa85e688899b0dac644 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 13:49:26 -0700
Subject: [PATCH 062/106] Fixed LayerVisitor constructors in EditSession.
---
src/main/java/com/sk89q/worldedit/EditSession.java | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 69302e1bc..9ee634189 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -1170,8 +1170,7 @@ public class EditSession implements Extent {
BlockReplace replace = new BlockReplace(this, Patterns.wrap(pattern));
RegionOffset offset = new RegionOffset(new Vector(0, 1, 0), replace);
GroundFunction ground = new GroundFunction(this, offset);
- LayerVisitor visitor = new LayerVisitor(
- this, asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
OperationHelper.completeLegacy(visitor);
return ground.getAffected();
}
@@ -1189,8 +1188,7 @@ public class EditSession implements Extent {
Naturalizer naturalizer = new Naturalizer(this);
FlatRegion flatRegion = Regions.asFlatRegion(region);
- LayerVisitor visitor = new LayerVisitor(
- this, flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer);
+ LayerVisitor visitor = new LayerVisitor(flatRegion, minimumBlockY(region), maximumBlockY(region), naturalizer);
OperationHelper.completeLegacy(visitor);
return naturalizer.getAffected();
}
@@ -1935,8 +1933,7 @@ public class EditSession implements Extent {
double density = 0.02;
GroundFunction ground = new GroundFunction(this, generator);
- LayerVisitor visitor = new LayerVisitor(
- this, region, minimumBlockY(region), maximumBlockY(region), ground);
+ LayerVisitor visitor = new LayerVisitor(region, minimumBlockY(region), maximumBlockY(region), ground);
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
OperationHelper.completeLegacy(visitor);
return ground.getAffected();
From f48040572e24177807e7e4586c57df8c93de0c16 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 13:50:07 -0700
Subject: [PATCH 063/106] Fixed LayerVisitor constructors in RegionCommands.
---
.../java/com/sk89q/worldedit/commands/RegionCommands.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
index 74748c60b..8563446da 100644
--- a/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
+++ b/src/main/java/com/sk89q/worldedit/commands/RegionCommands.java
@@ -552,8 +552,7 @@ public class RegionCommands {
ForestGenerator generator = new ForestGenerator(editSession, new TreeGenerator(type));
GroundFunction ground = new GroundFunction(editSession, generator);
- LayerVisitor visitor = new LayerVisitor(
- editSession, asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
OperationHelper.completeLegacy(visitor);
@@ -575,8 +574,7 @@ public class RegionCommands {
Region region = session.getSelection(player.getWorld());
FloraGenerator generator = new FloraGenerator(editSession);
GroundFunction ground = new GroundFunction(editSession, generator);
- LayerVisitor visitor = new LayerVisitor(
- editSession, asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
+ LayerVisitor visitor = new LayerVisitor(asFlatRegion(region), minimumBlockY(region), maximumBlockY(region), ground);
visitor.setMask(new NoiseFilter2D(new RandomNoise(), density));
OperationHelper.completeLegacy(visitor);
From d64d3fbacb5f1ae6838e61c4614cad279aa99964 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 13:54:57 -0700
Subject: [PATCH 064/106] Added to @SuppressWarnings("deprecation") to
converted EditSession methods.
---
.../java/com/sk89q/worldedit/EditSession.java | 30 +++++++++++++++----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index 9ee634189..f0a776a1d 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -39,16 +39,17 @@ import com.sk89q.worldedit.function.mask.*;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.OperationHelper;
import com.sk89q.worldedit.function.operation.OperationQueue;
+import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Patterns;
import com.sk89q.worldedit.function.util.RegionOffset;
import com.sk89q.worldedit.function.visitor.DownwardVisitor;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
import com.sk89q.worldedit.function.visitor.RecursiveVisitor;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
+import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.math.interpolation.Interpolation;
import com.sk89q.worldedit.math.interpolation.KochanekBartelsInterpolation;
import com.sk89q.worldedit.math.interpolation.Node;
-import com.sk89q.worldedit.masks.Mask;
import com.sk89q.worldedit.math.noise.RandomNoise;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.patterns.Pattern;
@@ -804,6 +805,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int fillXZ(Vector origin, BaseBlock block, double radius, int depth, boolean recursive)
throws MaxChangedBlocksException {
return fillXZ(origin, new SingleBlockPattern(block), radius, depth, recursive);
@@ -820,6 +822,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int fillXZ(Vector origin, Pattern pattern, double radius, int depth, boolean recursive) throws MaxChangedBlocksException {
checkNotNull(origin);
checkNotNull(pattern);
@@ -862,6 +865,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int removeAbove(Vector position, int apothem, int height) throws MaxChangedBlocksException {
checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
@@ -884,6 +888,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int removeBelow(Vector position, int apothem, int height) throws MaxChangedBlocksException {
checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
@@ -906,6 +911,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int removeNear(Vector position, int blockType, int apothem) throws MaxChangedBlocksException {
checkNotNull(position);
checkArgument(apothem >= 1, "apothem >= 1");
@@ -928,6 +934,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int setBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
return setBlocks(region, new SingleBlockPattern(block));
}
@@ -940,6 +947,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -960,6 +968,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int replaceBlocks(Region region, Set filter, BaseBlock replacement) throws MaxChangedBlocksException {
return replaceBlocks(region, filter, new SingleBlockPattern(replacement));
}
@@ -974,6 +983,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException {
Mask mask = filter == null ? new com.sk89q.worldedit.masks.ExistingBlockMask() : new com.sk89q.worldedit.masks.FuzzyBlockMask(filter);
return replaceBlocks(region, mask, pattern);
@@ -989,6 +999,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(mask);
@@ -1011,6 +1022,7 @@ public class EditSession implements Extent {
* @return the number of blocks placed
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int center(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -1031,6 +1043,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
+ @SuppressWarnings("deprecation")
public int makeCuboidFaces(Region region, BaseBlock block) throws MaxChangedBlocksException {
return makeCuboidFaces(region, new SingleBlockPattern(block));
}
@@ -1043,6 +1056,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int makeCuboidFaces(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -1062,6 +1076,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int makeFaces(final Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -1083,6 +1098,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
+ @SuppressWarnings("deprecation")
public int makeCuboidWalls(Region region, BaseBlock block) throws MaxChangedBlocksException {
return makeCuboidWalls(region, new SingleBlockPattern(block));
}
@@ -1096,6 +1112,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int makeCuboidWalls(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -1115,6 +1132,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int makeWalls(final Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -1148,6 +1166,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int overlayCuboidBlocks(Region region, BaseBlock block) throws MaxChangedBlocksException {
checkNotNull(block);
@@ -1163,6 +1182,7 @@ public class EditSession implements Extent {
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
+ @SuppressWarnings("deprecation")
public int overlayCuboidBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(pattern);
@@ -1239,10 +1259,10 @@ public class EditSession implements Extent {
Vector to = region.getMinimumPoint();
// Remove the original blocks
- Pattern pattern = replacement != null ?
- new SingleBlockPattern(replacement) :
- new SingleBlockPattern(new BaseBlock(BlockID.AIR));
- BlockReplace remove = new BlockReplace(this, Patterns.wrap(pattern));
+ com.sk89q.worldedit.function.pattern.Pattern pattern = replacement != null ?
+ new BlockPattern(replacement) :
+ new BlockPattern(new BaseBlock(BlockID.AIR));
+ BlockReplace remove = new BlockReplace(this, pattern);
// Copy to a buffer so we don't destroy our original before we can copy all the blocks from it
ExtentBuffer buffer = new ExtentBuffer(this, new RegionMask(region));
From 21496915af648e48849fcababc6c8857163a896a Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 13:56:12 -0700
Subject: [PATCH 065/106] Made moveCuboidRegion() call moveRegion().
---
.../java/com/sk89q/worldedit/EditSession.java | 69 +++----------------
1 file changed, 9 insertions(+), 60 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index f0a776a1d..b7d3e0298 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -1284,69 +1284,18 @@ public class EditSession implements Extent {
}
/**
- * Move a cuboid region.
+ * Move the blocks in a region a certain direction.
*
- * @param region
- * @param dir
- * @param distance
- * @param copyAir
- * @param replace
+ * @param region the region to move
+ * @param dir the direction
+ * @param distance the distance to move
+ * @param copyAir true to copy air blocks
+ * @param replacement the replacement block to fill in after moving, or null to use air
* @return number of blocks moved
- * @throws MaxChangedBlocksException
+ * @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
- public int moveCuboidRegion(Region region, Vector dir, int distance,
- boolean copyAir, BaseBlock replace)
- throws MaxChangedBlocksException {
- int affected = 0;
-
- Vector shift = dir.multiply(distance);
- Vector min = region.getMinimumPoint();
- Vector max = region.getMaximumPoint();
-
- int minX = min.getBlockX();
- int minY = min.getBlockY();
- int minZ = min.getBlockZ();
- int maxX = max.getBlockX();
- int maxY = max.getBlockY();
- int maxZ = max.getBlockZ();
-
- Vector newMin = min.add(shift);
- Vector newMax = min.add(shift);
-
- Map delayed = new LinkedHashMap();
-
- for (int x = minX; x <= maxX; ++x) {
- for (int z = minZ; z <= maxZ; ++z) {
- for (int y = minY; y <= maxY; ++y) {
- Vector pos = new Vector(x, y, z);
- BaseBlock block = getBlock(pos);
-
- if (!block.isAir() || copyAir) {
- Vector newPos = pos.add(shift);
-
- delayed.put(newPos, getBlock(pos));
-
- // Don't want to replace the old block if it's in
- // the new area
- if (x >= newMin.getBlockX() && x <= newMax.getBlockX()
- && y >= newMin.getBlockY()
- && y <= newMax.getBlockY()
- && z >= newMin.getBlockZ()
- && z <= newMax.getBlockZ()) {
- } else {
- setBlock(pos, replace);
- }
- }
- }
- }
- }
-
- for (Map.Entry entry : delayed.entrySet()) {
- setBlock(entry.getKey(), entry.getValue());
- ++affected;
- }
-
- return affected;
+ public int moveCuboidRegion(Region region, Vector dir, int distance, boolean copyAir, BaseBlock replacement) throws MaxChangedBlocksException {
+ return moveRegion(region, dir, distance, copyAir, replacement);
}
/**
From 3ad5c9016aba121622e5c8bb57e27c5d0acc4969 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 14:09:50 -0700
Subject: [PATCH 066/106] Added CuboidRegion.fromCenter().
---
.../com/sk89q/worldedit/regions/CuboidRegion.java | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
index 35df1e097..dabdc848d 100644
--- a/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
+++ b/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
@@ -426,7 +427,21 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
* @return a new cuboid region
*/
public static CuboidRegion makeCuboid(Region region) {
+ checkNotNull(region);
return new CuboidRegion(region.getMinimumPoint(), region.getMaximumPoint());
}
+ /**
+ * Make a cuboid from the center.
+ *
+ * @param origin the origin
+ * @param apothem the apothem, where 0 is the minimum value to make a 1x1 cuboid
+ * @return a cuboid region
+ */
+ public static CuboidRegion fromCenter(Vector origin, int apothem) {
+ checkNotNull(origin);
+ checkArgument(apothem >= 0, "apothem => 0 required");
+ Vector size = new Vector(1, 1, 1).multiply(apothem);
+ return new CuboidRegion(origin.subtract(size), origin.add(size));
+ }
}
From cc8a89f415aa3993c8ed189519fbf4ba755bc1c7 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sun, 30 Mar 2014 14:10:01 -0700
Subject: [PATCH 067/106] Converted //drain to visitors.
---
.../java/com/sk89q/worldedit/EditSession.java | 74 ++++++-------------
1 file changed, 22 insertions(+), 52 deletions(-)
diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java
index b7d3e0298..c7c2aca03 100644
--- a/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -1301,67 +1301,37 @@ public class EditSession implements Extent {
/**
* Drain nearby pools of water or lava.
*
- * @param pos
- * @param radius
+ * @param origin the origin to drain from, which will search a 3x3 area
+ * @param radius the radius of the removal, where a value should be 0 or greater
* @return number of blocks affected
* @throws MaxChangedBlocksException
*/
- public int drainArea(Vector pos, double radius)
- throws MaxChangedBlocksException {
- int affected = 0;
+ public int drainArea(Vector origin, double radius) throws MaxChangedBlocksException {
+ checkNotNull(origin);
+ checkArgument(radius >= 0, "radius >= 0 required");
- HashSet visited = new HashSet