From 3c5c257a4151dbf0c1d474ed17c5c9833e866fc3 Mon Sep 17 00:00:00 2001
From: sk89q
Date: Sat, 29 Mar 2014 18:51:33 -0700
Subject: [PATCH] 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);
- }
-
-}