Switch to Gradle. Use git log --follow for history.

This converts the project into a multi-module Gradle build.

By default, Git does not show history past a rename, so use git log
--follow to see further history.
This commit is contained in:
sk89q
2014-11-14 11:27:39 -08:00
parent 44559cde68
commit 7192780251
714 changed files with 333 additions and 834 deletions

View File

@ -0,0 +1,91 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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<RegionFunction> functions = new ArrayList<RegionFunction>();
/**
* Create a combined region function.
*/
public CombinedRegionFunction() {
}
/**
* Create a combined region function.
*
* @param functions a list of functions to match
*/
public CombinedRegionFunction(Collection<RegionFunction> 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<RegionFunction> 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;
}
}

View File

@ -0,0 +1,39 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
/**
* Applies a function to entities.
*/
public interface EntityFunction {
/**
* Apply the function to the entity.
*
* @param entity the entity
* @return true if something was changed
* @throws WorldEditException thrown on an error
*/
public boolean apply(Entity entity) throws WorldEditException;
}

View File

@ -0,0 +1,41 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.regions.FlatRegion;
/**
* Performs a function on the columns in a {@link FlatRegion}, or also
* known as vectors with only X and Z components (where Y is height).
*/
public interface FlatRegionFunction {
/**
* Apply the function to the given position.
*
* @param position the position
* @return true if something was changed
* @throws WorldEditException thrown on an error
*/
public boolean apply(Vector2D position) throws WorldEditException;
}

View File

@ -0,0 +1,57 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.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.function.FlatRegionFunction} if they
* match the given mask.
*/
public class FlatRegionMaskingFilter implements FlatRegionFunction {
private final FlatRegionFunction function;
private Mask2D mask;
/**
* Create a new masking filter.
*
* @param mask the mask
* @param function the delegate function to call
*/
public FlatRegionMaskingFilter(Mask2D mask, FlatRegionFunction function) {
checkNotNull(function);
checkNotNull(mask);
this.mask = mask;
this.function = function;
}
@Override
public boolean apply(Vector2D position) throws WorldEditException {
return mask.test(position) && function.apply(position);
}
}

View File

@ -0,0 +1,94 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.Mask;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Applies a {@link RegionFunction} to the first ground block.
*/
public class GroundFunction implements LayerFunction {
private Mask mask;
private final RegionFunction function;
private int affected;
/**
* Create a new ground function.
*
* @param mask a mask
* @param function the function to apply
*/
public GroundFunction(Mask mask, RegionFunction function) {
checkNotNull(mask);
checkNotNull(function);
this.mask = mask;
this.function = function;
}
/**
* 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 isGround(Vector position) {
return mask.test(position);
}
@Override
public boolean apply(Vector position, int depth) throws WorldEditException {
if (depth == 0) {
if (function.apply(position)) {
affected++;
}
}
return false;
}
}

View File

@ -0,0 +1,52 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.visitor.LayerVisitor;
/**
* A function that takes a position and a depth.
*/
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.
*
* <p>The depth would be the number of blocks from the surface if
* a {@link LayerVisitor} was used.</p>
*
* @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 WorldEditException thrown on an error
*/
boolean apply(Vector position, int depth) throws WorldEditException;
}

View File

@ -0,0 +1,39 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
/**
* Performs a function on points in a region.
*/
public interface RegionFunction {
/**
* Apply the function to the given position.
*
* @param position the position
* @return true if something was changed
* @throws WorldEditException thrown on an error
*/
public boolean apply(Vector position) throws WorldEditException;
}

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.mask.Mask;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Passes calls to {@link #apply(com.sk89q.worldedit.Vector)} to the
* delegate {@link com.sk89q.worldedit.function.RegionFunction} if they
* match the given mask.
*/
public class RegionMaskingFilter implements RegionFunction {
private final RegionFunction function;
private Mask mask;
/**
* Create a new masking filter.
*
* @param mask the mask
* @param function the function
*/
public RegionMaskingFilter(Mask mask, RegionFunction function) {
checkNotNull(function);
checkNotNull(mask);
this.mask = mask;
this.function = function;
}
@Override
public boolean apply(Vector position) throws WorldEditException {
return mask.test(position) && function.apply(position);
}
}

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.biome;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.FlatRegionFunction;
import com.sk89q.worldedit.world.biome.BaseBiome;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Replaces the biome at the locations that this function is applied to.
*/
public class BiomeReplace implements FlatRegionFunction {
private final Extent extent;
private BaseBiome biome;
/**
* Create a new instance.
*
* @param extent an extent
* @param biome a biome
*/
public BiomeReplace(Extent extent, BaseBiome biome) {
checkNotNull(extent);
checkNotNull(biome);
this.extent = extent;
this.biome = biome;
}
@Override
public boolean apply(Vector2D position) throws WorldEditException {
return extent.setBiome(position, biome);
}
}

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.block;
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.function.pattern.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Replaces blocks with a given pattern.
*/
public class BlockReplace implements RegionFunction {
private final Extent extent;
private Pattern pattern;
/**
* Create a new instance.
*
* @param extent an extent
* @param pattern a pattern
*/
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 extent.setBlock(position, pattern.apply(position));
}
}

View File

@ -0,0 +1,48 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.block;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.RegionFunction;
/**
* Keeps a count of the number of times that {@link #apply(Vector)} is called.
*/
public class Counter implements RegionFunction {
private int count;
/**
* 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 {
count++;
return false;
}
}

View File

@ -0,0 +1,72 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.block;
import com.sk89q.worldedit.extent.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);
Vector orig = position.subtract(from);
Vector transformed = transform.apply(orig);
return destination.setBlock(transformed.add(to), block);
}
}

View File

@ -0,0 +1,91 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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;
}
}

View File

@ -0,0 +1,157 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.entity;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.internal.helper.MCDirections;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Direction.Flag;
import com.sk89q.worldedit.util.Location;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Copies entities provided to the function to the provided destination
* {@code Extent}.
*/
public class ExtentEntityCopy implements EntityFunction {
private final Extent destination;
private final Vector from;
private final Vector to;
private final Transform transform;
private boolean removing;
/**
* Create a new instance.
*
* @param from the from position
* @param destination the destination {@code Extent}
* @param to the destination position
* @param transform the transformation to apply to both position and orientation
*/
public ExtentEntityCopy(Vector from, Extent destination, Vector to, Transform transform) {
checkNotNull(from);
checkNotNull(destination);
checkNotNull(to);
checkNotNull(transform);
this.destination = destination;
this.from = from;
this.to = to;
this.transform = transform;
}
/**
* Return whether entities that are copied should be removed.
*
* @return true if removing
*/
public boolean isRemoving() {
return removing;
}
/**
* Set whether entities that are copied should be removed.
*
* @param removing true if removing
*/
public void setRemoving(boolean removing) {
this.removing = removing;
}
@Override
public boolean apply(Entity entity) throws WorldEditException {
BaseEntity state = entity.getState();
if (state != null) {
Location location = entity.getLocation();
Vector newPosition = transform.apply(location.toVector().subtract(from));
Vector newDirection = transform.apply(location.getDirection()).subtract(transform.apply(Vector.ZERO)).normalize();
Location newLocation = new Location(destination, newPosition.add(to), newDirection);
// Some entities store their position data in NBT
state = transformNbtData(state);
boolean success = destination.createEntity(newLocation, state) != null;
// Remove
if (isRemoving() && success) {
entity.remove();
}
return success;
} else {
return false;
}
}
/**
* Transform NBT data in the given entity state and return a new instance
* if the NBT data needs to be transformed.
*
* @param state the existing state
* @return a new state or the existing one
*/
private BaseEntity transformNbtData(BaseEntity state) {
CompoundTag tag = state.getNbtData();
if (tag != null) {
// Handle hanging entities (paintings, item frames, etc.)
boolean hasTilePosition = tag.containsKey("TileX") && tag.containsKey("TileY") && tag.containsKey("TileZ");
boolean hasDirection = tag.containsKey("Direction");
boolean hasLegacyDirection = tag.containsKey("Dir");
if (hasTilePosition) {
Vector tilePosition = new Vector(tag.asInt("TileX"), tag.asInt("TileY"), tag.asInt("TileZ"));
Vector newTilePosition = transform.apply(tilePosition.subtract(from)).add(to);
CompoundTagBuilder builder = tag.createBuilder()
.putInt("TileX", newTilePosition.getBlockX())
.putInt("TileY", newTilePosition.getBlockY())
.putInt("TileZ", newTilePosition.getBlockZ());
if (hasDirection || hasLegacyDirection) {
int d = hasDirection ? tag.asInt("Direction") : MCDirections.fromLegacyHanging((byte) tag.asInt("Dir"));
Direction direction = MCDirections.fromHanging(d);
if (direction != null) {
Vector vector = transform.apply(direction.toVector()).subtract(transform.apply(Vector.ZERO)).normalize();
Direction newDirection = Direction.findClosest(vector, Flag.CARDINAL);
builder.putByte("Direction", (byte) MCDirections.toHanging(newDirection));
builder.putByte("Dir", MCDirections.toLegacyHanging(MCDirections.toHanging(newDirection)));
}
}
return new BaseEntity(state.getTypeId(), builder.build());
}
}
return state;
}
}

View File

@ -0,0 +1,120 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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.function.RegionFunction;
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.).
*
* <p>The current implementation is not biome-aware, but it may become so in
* the future.</p>
*/
public class FloraGenerator implements RegionFunction {
private final EditSession editSession;
private boolean biomeAware = false;
private final Pattern desertPattern = getDesertPattern();
private final Pattern temperatePattern = getTemperatePattern();
/**
* Create a new flora generator.
*
* @param editSession the edit session
*/
public FloraGenerator(EditSession editSession) {
this.editSession = editSession;
}
/**
* Return whether the flora generator is set to be biome-aware.
*
* <p>By default, it is currently disabled by default, but
* this may change.</p>
*
* @return true if biome aware
*/
public boolean isBiomeAware() {
return biomeAware;
}
/**
* Set whether the generator is biome aware.
*
* <p>It is currently not possible to make the generator biome-aware.</p>
*
* @param biomeAware must always be false
*/
public void setBiomeAware(boolean biomeAware) {
if (biomeAware) {
throw new IllegalArgumentException("Cannot enable biome-aware mode; not yet implemented");
}
}
/**
* Get a pattern for plants to place inside a desert environment.
*
* @return a pattern that places flora
*/
public static Pattern getDesertPattern() {
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;
}
/**
* Get a pattern for plants to place inside a temperate environment.
*
* @return a pattern that places flora
*/
public static Pattern getTemperatePattern() {
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
public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = editSession.getBlock(position);
if (block.getType() == BlockID.GRASS) {
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.apply(position));
return true;
}
return false;
}
}

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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.function.RegionFunction;
import com.sk89q.worldedit.util.TreeGenerator;
/**
* Generates forests by searching for the ground starting from the given upper Y
* coordinate for every column given.
*/
public class ForestGenerator implements RegionFunction {
private final TreeGenerator treeGenerator;
private final EditSession editSession;
/**
* Create a new instance.
*
* @param editSession the edit session
* @param treeGenerator a tree generator
*/
public ForestGenerator(EditSession editSession, TreeGenerator treeGenerator) {
this.editSession = editSession;
this.treeGenerator = treeGenerator;
}
@Override
public boolean apply(Vector position) throws WorldEditException {
BaseBlock block = editSession.getBlock(position);
int t = block.getType();
if (t == BlockID.GRASS || t == BlockID.DIRT) {
treeGenerator.generate(editSession, position.add(0, 1, 0));
return true;
} else if (t == BlockID.SNOW) {
editSession.setBlock(position, new BaseBlock(BlockID.AIR));
return false;
} else { // Trees won't grow on this!
return false;
}
}
}

View File

@ -0,0 +1,203 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.generator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
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.RegionFunction;
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import java.util.Random;
/**
* Generates patches of fruit (i.e. pumpkin patches).
*/
public class GardenPatchGenerator implements RegionFunction {
private final Random random = new Random();
private final EditSession editSession;
private Pattern plant = getPumpkinPattern();
private int affected;
/**
* Create a new instance.
*
* @param editSession the edit session
*/
public GardenPatchGenerator(EditSession editSession) {
this.editSession = editSession;
}
/**
* Get the plant pattern that is placed.
*
* @return the plant pattern
*/
public Pattern getPlant() {
return plant;
}
/**
* Set the plant pattern that is placed.
*
* @param plant the plant pattern
*/
public void setPlant(Pattern plant) {
this.plant = plant;
}
/**
* Get the number of affected blocks.
*
* @return affected count
*/
public int getAffected() {
return affected;
}
/**
* Make a patch vine.
*
* @param basePos the base position
* @param pos the vine position
*/
private void placeVine(Vector basePos, Vector pos) throws MaxChangedBlocksException {
if (pos.distance(basePos) > 4) return;
if (editSession.getBlockType(pos) != 0) return;
for (int i = -1; i > -3; --i) {
Vector testPos = pos.add(0, i, 0);
if (editSession.getBlockType(testPos) == BlockID.AIR) {
pos = testPos;
} else {
break;
}
}
editSession.setBlockIfAir(pos, new BaseBlock(BlockID.LEAVES));
affected++;
int t = random.nextInt(4);
int h = random.nextInt(3) - 1;
Vector p;
BaseBlock log = new BaseBlock(BlockID.LOG);
switch (t) {
case 0:
if (random.nextBoolean()) {
placeVine(basePos, pos.add(1, 0, 0));
}
if (random.nextBoolean()) {
editSession.setBlockIfAir(pos.add(1, h, -1), log);
affected++;
}
editSession.setBlockIfAir(p = pos.add(0, 0, -1), plant.apply(p));
affected++;
break;
case 1:
if (random.nextBoolean()) {
placeVine(basePos, pos.add(0, 0, 1));
}
if (random.nextBoolean()) {
editSession.setBlockIfAir(pos.add(1, h, 0), log);
affected++;
}
editSession.setBlockIfAir(p = pos.add(1, 0, 1), plant.apply(p));
affected++;
break;
case 2:
if (random.nextBoolean()) {
placeVine(basePos, pos.add(0, 0, -1));
}
if (random.nextBoolean()) {
editSession.setBlockIfAir(pos.add(-1, h, 0), log);
affected++;
}
editSession.setBlockIfAir(p = pos.add(-1, 0, 1), plant.apply(p));
affected++;
break;
case 3:
if (random.nextBoolean()) {
placeVine(basePos, pos.add(-1, 0, 0));
}
if (random.nextBoolean()) {
editSession.setBlockIfAir(pos.add(-1, h, -1), log);
affected++;
}
editSession.setBlockIfAir(p = pos.add(-1, 0, -1), plant.apply(p));
affected++;
break;
}
}
@Override
public boolean apply(Vector position) throws WorldEditException {
if (editSession.getBlock(position).getType() != BlockID.AIR) {
position = position.add(0, 1, 0);
}
if (editSession.getBlock(position.add(0, -1, 0)).getType() != BlockID.GRASS) {
return false;
}
BaseBlock leavesBlock = new BaseBlock(BlockID.LEAVES);
editSession.setBlockIfAir(position, leavesBlock);
placeVine(position, position.add(0, 0, 1));
placeVine(position, position.add(0, 0, -1));
placeVine(position, position.add(1, 0, 0));
placeVine(position, position.add(-1, 0, 0));
return true;
}
/**
* Get a pattern that creates pumpkins with different faces.
*
* @return a pumpkin pattern
*/
public static Pattern getPumpkinPattern() {
RandomPattern pattern = new RandomPattern();
for (int i = 0; i < 4; i++) {
pattern.add(new BlockPattern(new BaseBlock(BlockID.PUMPKIN, i)), 100);
}
return pattern;
}
/**
* Get a pattern that creates melons.
*
* @return a melon pattern
*/
public static Pattern getMelonPattern() {
return new BlockPattern(new BaseBlock(BlockID.MELON_BLOCK));
}
}

View File

@ -0,0 +1,61 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.extent.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;
}
}

View File

@ -0,0 +1,26 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
/**
* A base class of {@link Mask} that all masks should inherit from.
*/
public abstract class AbstractMask implements Mask {
}

View File

@ -0,0 +1,26 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
/**
* A base class of {@link Mask2D} that all masks should inherit from.
*/
public abstract class AbstractMask2D implements Mask2D {
}

View File

@ -0,0 +1,98 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Tests true if the biome at applied points is the same as the one given.
*/
public class BiomeMask2D extends AbstractMask2D {
private final Extent extent;
private final Set<BaseBiome> biomes = new HashSet<BaseBiome>();
/**
* Create a new biome mask.
*
* @param extent the extent
* @param biomes a list of biomes to match
*/
public BiomeMask2D(Extent extent, Collection<BaseBiome> biomes) {
checkNotNull(extent);
checkNotNull(biomes);
this.extent = extent;
this.biomes.addAll(biomes);
}
/**
* Create a new biome mask.
*
* @param extent the extent
* @param biome an array of biomes to match
*/
public BiomeMask2D(Extent extent, BaseBiome... biome) {
this(extent, Arrays.asList(checkNotNull(biome)));
}
/**
* Add the given biomes to the list of criteria.
*
* @param biomes a list of biomes
*/
public void add(Collection<BaseBiome> biomes) {
checkNotNull(biomes);
this.biomes.addAll(biomes);
}
/**
* Add the given biomes to the list of criteria.
*
* @param biome an array of biomes
*/
public void add(BaseBiome... biome) {
add(Arrays.asList(checkNotNull(biome)));
}
/**
* Get the list of biomes that are tested with.
*
* @return a list of biomes
*/
public Collection<BaseBiome> getBiomes() {
return biomes;
}
@Override
public boolean test(Vector2D vector) {
BaseBiome biome = extent.getBiome(vector);
return biomes.contains(biome);
}
}

View File

@ -0,0 +1,107 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import javax.annotation.Nullable;
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 matched by
* a block in a list.
*
* <p>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.</p>
*/
public class BlockMask extends AbstractExtentMask {
private final Set<BaseBlock> blocks = new HashSet<BaseBlock>();
/**
* Create a new block mask.
*
* @param extent the extent
* @param blocks a list of blocks to match
*/
public BlockMask(Extent extent, Collection<BaseBlock> blocks) {
super(extent);
checkNotNull(blocks);
this.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<BaseBlock> blocks) {
checkNotNull(blocks);
this.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<BaseBlock> 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));
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -0,0 +1,60 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
/**
* Has the criteria where the Y value of passed positions must be within
* a certain range of Y values (inclusive).
*/
public class BoundedHeightMask extends AbstractMask {
private final int minY;
private final int 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 test(Vector vector) {
return vector.getY() >= minY && vector.getY() <= maxY;
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -0,0 +1,54 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
import javax.annotation.Nullable;
/**
* 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().getLazyBlock(vector).getType() != BlockID.AIR;
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -0,0 +1,77 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A mask that evaluates an expression.
*
* <p>Expressions are evaluated as {@code true} if they return a value
* greater than {@code 0}.</p>
*/
public class ExpressionMask extends AbstractMask {
private final Expression expression;
/**
* Create a new instance.
*
* @param expression the expression
* @throws ExpressionException thrown if there is an error with the expression
*/
public ExpressionMask(String expression) throws ExpressionException {
checkNotNull(expression);
this.expression = Expression.compile(expression, "x", "y", "z");
}
/**
* Create a new instance.
*
* @param expression the expression
*/
public ExpressionMask(Expression expression) {
checkNotNull(expression);
this.expression = expression;
}
@Override
public boolean test(Vector vector) {
try {
return expression.evaluate(vector.getX(), vector.getY(), vector.getZ()) > 0;
} catch (EvaluationException e) {
return false;
}
}
@Nullable
@Override
public Mask2D toMask2D() {
return new ExpressionMask2D(expression);
}
}

View File

@ -0,0 +1,63 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.internal.expression.Expression;
import com.sk89q.worldedit.internal.expression.ExpressionException;
import com.sk89q.worldedit.internal.expression.runtime.EvaluationException;
import static com.google.common.base.Preconditions.checkNotNull;
public class ExpressionMask2D extends AbstractMask2D {
private final Expression expression;
/**
* Create a new instance.
*
* @param expression the expression
* @throws ExpressionException thrown if there is an error with the expression
*/
public ExpressionMask2D(String expression) throws ExpressionException {
checkNotNull(expression);
this.expression = Expression.compile(expression, "x", "z");
}
/**
* Create a new instance.
*
* @param expression the expression
*/
public ExpressionMask2D(Expression expression) {
checkNotNull(expression);
this.expression = expression;
}
@Override
public boolean test(Vector2D vector) {
try {
return expression.evaluate(vector.getX(), 0, vector.getZ()) > 0;
} catch (EvaluationException e) {
return false;
}
}
}

View File

@ -0,0 +1,47 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.Blocks;
import com.sk89q.worldedit.extent.Extent;
import java.util.Collection;
public class FuzzyBlockMask extends BlockMask {
public FuzzyBlockMask(Extent extent, Collection<BaseBlock> blocks) {
super(extent, blocks);
}
public FuzzyBlockMask(Extent extent, BaseBlock... block) {
super(extent, block);
}
@Override
public boolean test(Vector vector) {
Extent extent = getExtent();
Collection<BaseBlock> blocks = getBlocks();
BaseBlock lazyBlock = extent.getLazyBlock(vector);
BaseBlock compare = new BaseBlock(lazyBlock.getType(), lazyBlock.getData());
return Blocks.containsFuzzy(blocks, compare);
}
}

View File

@ -0,0 +1,47 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import javax.annotation.Nullable;
/**
* Tests whether a given vector meets a criteria.
*/
public interface Mask {
/**
* Returns true if the criteria is met.
*
* @param vector the vector to test
* @return true if the criteria is met
*/
boolean test(Vector vector);
/**
* Get the 2D version of this mask if one exists.
*
* @return a 2D mask version or {@code null} if this mask can't be 2D
*/
@Nullable
Mask2D toMask2D();
}

View File

@ -0,0 +1,37 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
/**
* Tests whether a given vector meets a criteria.
*/
public interface Mask2D {
/**
* Returns true if the criteria is met.
*
* @param vector the vector to test
* @return true if the criteria is met
*/
boolean test(Vector2D vector);
}

View File

@ -0,0 +1,120 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
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<Mask> masks = new HashSet<Mask>();
/**
* Create a new intersection.
*
* @param masks a list of masks
*/
public MaskIntersection(Collection<Mask> masks) {
checkNotNull(masks);
this.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<Mask> masks) {
checkNotNull(masks);
this.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<Mask> getMasks() {
return masks;
}
@Override
public boolean test(Vector vector) {
if (masks.isEmpty()) {
return false;
}
for (Mask mask : masks) {
if (!mask.test(vector)) {
return false;
}
}
return true;
}
@Nullable
@Override
public Mask2D toMask2D() {
List<Mask2D> mask2dList = new ArrayList<Mask2D>();
for (Mask mask : masks) {
Mask2D mask2d = mask.toMask2D();
if (mask2d != null) {
mask2dList.add(mask2d);
} else {
return null;
}
}
return new MaskIntersection2D(mask2dList);
}
}

View File

@ -0,0 +1,100 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Tests true if all contained masks test true.
*/
public class MaskIntersection2D implements Mask2D {
private final Set<Mask2D> masks = new HashSet<Mask2D>();
/**
* Create a new intersection.
*
* @param masks a list of masks
*/
public MaskIntersection2D(Collection<Mask2D> masks) {
checkNotNull(masks);
this.masks.addAll(masks);
}
/**
* Create a new intersection.
*
* @param mask a list of masks
*/
public MaskIntersection2D(Mask2D... mask) {
this(Arrays.asList(checkNotNull(mask)));
}
/**
* Add some masks to the list.
*
* @param masks the masks
*/
public void add(Collection<Mask2D> masks) {
checkNotNull(masks);
this.masks.addAll(masks);
}
/**
* Add some masks to the list.
*
* @param mask the masks
*/
public void add(Mask2D... mask) {
add(Arrays.asList(checkNotNull(mask)));
}
/**
* Get the masks that are tested with.
*
* @return the masks
*/
public Collection<Mask2D> getMasks() {
return masks;
}
@Override
public boolean test(Vector2D vector) {
if (masks.isEmpty()) {
return false;
}
for (Mask2D mask : masks) {
if (!mask.test(vector)) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,81 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* 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<Mask> 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<Mask> masks = getMasks();
for (Mask mask : masks) {
if (mask.test(vector)) {
return true;
}
}
return false;
}
@Nullable
@Override
public Mask2D toMask2D() {
List<Mask2D> mask2dList = new ArrayList<Mask2D>();
for (Mask mask : getMasks()) {
Mask2D mask2d = mask.toMask2D();
if (mask2d != null) {
mask2dList.add(mask2d);
} else {
return null;
}
}
return new MaskUnion2D(mask2dList);
}
}

View File

@ -0,0 +1,62 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
import java.util.Collection;
/**
* Tests true if any contained mask is true, even if it just one.
*/
public class MaskUnion2D extends MaskIntersection2D {
/**
* Create a new union.
*
* @param masks a list of masks
*/
public MaskUnion2D(Collection<Mask2D> masks) {
super(masks);
}
/**
* Create a new union.
*
* @param mask a list of masks
*/
public MaskUnion2D(Mask2D... mask) {
super(mask);
}
@Override
public boolean test(Vector2D vector) {
Collection<Mask2D> masks = getMasks();
for (Mask2D mask : masks) {
if (mask.test(vector)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,246 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.*;
import com.sk89q.worldedit.session.request.Request;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Various utility functions related to {@link Mask} and {@link Mask2D}.
*/
public final class Masks {
private static final AlwaysTrue ALWAYS_TRUE = new AlwaysTrue();
private static final AlwaysFalse ALWAYS_FALSE = new AlwaysFalse();
private Masks() {
}
/**
* Return a 3D mask that always returns true;
*
* @return a mask
*/
public static Mask alwaysTrue() {
return ALWAYS_TRUE;
}
/**
* Return a 2D mask that always returns true;
*
* @return a mask
*/
public static Mask2D alwaysTrue2D() {
return ALWAYS_TRUE;
}
/**
* Negate the given mask.
*
* @param mask the mask
* @return a new mask
*/
public static Mask negate(final Mask mask) {
if (mask instanceof AlwaysTrue) {
return ALWAYS_FALSE;
} else if (mask instanceof AlwaysFalse) {
return ALWAYS_TRUE;
}
checkNotNull(mask);
return new AbstractMask() {
@Override
public boolean test(Vector vector) {
return !mask.test(vector);
}
@Nullable
@Override
public Mask2D toMask2D() {
Mask2D mask2d = mask.toMask2D();
if (mask2d != null) {
return negate(mask2d);
} else {
return null;
}
}
};
}
/**
* Negate the given mask.
*
* @param mask the mask
* @return a new mask
*/
public static Mask2D negate(final Mask2D mask) {
if (mask instanceof AlwaysTrue) {
return ALWAYS_FALSE;
} else if (mask instanceof AlwaysFalse) {
return ALWAYS_TRUE;
}
checkNotNull(mask);
return new AbstractMask2D() {
@Override
public boolean test(Vector2D vector) {
return !mask.test(vector);
}
};
}
/**
* Return a 3-dimensional version of a 2D mask.
*
* @param mask the mask to make 3D
* @return a 3D mask
*/
public static Mask asMask(final Mask2D mask) {
return new AbstractMask() {
@Override
public boolean test(Vector vector) {
return mask.test(vector.toVector2D());
}
@Nullable
@Override
public Mask2D toMask2D() {
return mask;
}
};
}
/**
* Wrap an old-style mask and convert it to a new mask.
*
* <p>Note, however, that this is strongly not recommended because
* {@link com.sk89q.worldedit.masks.Mask#prepare(LocalSession, LocalPlayer, Vector)}
* is not called.</p>
*
* @param mask the old-style mask
* @param editSession the edit session to bind to
* @return a new-style mask
* @deprecated Please avoid if possible
*/
@Deprecated
@SuppressWarnings("deprecation")
public static Mask wrap(final com.sk89q.worldedit.masks.Mask mask, final EditSession editSession) {
checkNotNull(mask);
return new AbstractMask() {
@Override
public boolean test(Vector vector) {
return mask.matches(editSession, vector);
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
};
}
/**
* Wrap an old-style mask and convert it to a new mask.
*
* <p>As an {@link EditSession} is not provided in this case, one will be
* taken from the {@link Request}, if possible. If not possible, then the
* mask will return false.</p>
*
* @param mask the old-style mask
* @return a new-style mask
*/
@SuppressWarnings("deprecation")
public static Mask wrap(final com.sk89q.worldedit.masks.Mask mask) {
checkNotNull(mask);
return new AbstractMask() {
@Override
public boolean test(Vector vector) {
EditSession editSession = Request.request().getEditSession();
return editSession != null && mask.matches(editSession, vector);
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
};
}
/**
* Convert a new-style mask to an old-style mask.
*
* @param mask the new-style mask
* @return an old-style mask
*/
@SuppressWarnings("deprecation")
public static com.sk89q.worldedit.masks.Mask wrap(final Mask mask) {
checkNotNull(mask);
return new com.sk89q.worldedit.masks.AbstractMask() {
@Override
public boolean matches(EditSession editSession, Vector position) {
Request.request().setEditSession(editSession);
return mask.test(position);
}
};
}
private static class AlwaysTrue implements Mask, Mask2D {
@Override
public boolean test(Vector vector) {
return true;
}
@Override
public boolean test(Vector2D vector) {
return true;
}
@Nullable
@Override
public Mask2D toMask2D() {
return this;
}
}
private static class AlwaysFalse implements Mask, Mask2D {
@Override
public boolean test(Vector vector) {
return false;
}
@Override
public boolean test(Vector2D vector) {
return false;
}
@Nullable
@Override
public Mask2D toMask2D() {
return this;
}
}
}

View File

@ -0,0 +1,98 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.noise.NoiseGenerator;
import javax.annotation.Nullable;
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).
*/
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 test(Vector vector) {
return noiseGenerator.noise(vector) <= density;
}
@Nullable
@Override
public Mask2D toMask2D() {
return new NoiseFilter2D(getNoiseGenerator(), getDensity());
}
}

View File

@ -0,0 +1,90 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.math.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).
*/
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 test(Vector2D pos) {
return noiseGenerator.noise(pos) <= density;
}
}

View File

@ -0,0 +1,104 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Checks whether another mask tests true for a position that is offset
* a given vector.
*/
public class OffsetMask extends AbstractMask {
private Mask mask;
private Vector offset;
/**
* Create a new instance.
*
* @param mask the mask
* @param offset the offset
*/
public OffsetMask(Mask mask, Vector offset) {
checkNotNull(mask);
checkNotNull(offset);
this.mask = mask;
this.offset = offset;
}
/**
* Get the mask.
*
* @return the mask
*/
public Mask getMask() {
return mask;
}
/**
* Set the mask.
*
* @param mask the mask
*/
public void setMask(Mask mask) {
checkNotNull(mask);
this.mask = mask;
}
/**
* Get the offset.
*
* @return the offset
*/
public Vector getOffset() {
return offset;
}
/**
* Set the offset.
*
* @param offset the offset
*/
public void setOffset(Vector offset) {
checkNotNull(offset);
this.offset = offset;
}
@Override
public boolean test(Vector vector) {
return getMask().test(vector.add(offset));
}
@Nullable
@Override
public Mask2D toMask2D() {
Mask2D childMask = getMask().toMask2D();
if (childMask != null) {
return new OffsetMask2D(childMask, getOffset().toVector2D());
} else {
return null;
}
}
}

View File

@ -0,0 +1,91 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector2D;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Checks whether another mask tests true for a position that is offset
* a given vector.
*/
public class OffsetMask2D extends AbstractMask2D {
private Mask2D mask;
private Vector2D offset;
/**
* Create a new instance.
*
* @param mask the mask
* @param offset the offset
*/
public OffsetMask2D(Mask2D mask, Vector2D offset) {
checkNotNull(mask);
checkNotNull(offset);
this.mask = mask;
this.offset = offset;
}
/**
* Get the mask.
*
* @return the mask
*/
public Mask2D getMask() {
return mask;
}
/**
* Set the mask.
*
* @param mask the mask
*/
public void setMask(Mask2D mask) {
checkNotNull(mask);
this.mask = mask;
}
/**
* Get the offset.
*
* @return the offset
*/
public Vector2D getOffset() {
return offset;
}
/**
* Set the offset.
*
* @param offset the offset
*/
public void setOffset(Vector2D offset) {
checkNotNull(offset);
this.offset = offset;
}
@Override
public boolean test(Vector2D vector) {
return getMask().test(vector.add(offset));
}
}

View File

@ -0,0 +1,75 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.regions.Region;
import javax.annotation.Nullable;
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);
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -0,0 +1,48 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.mask;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockType;
import javax.annotation.Nullable;
public class SolidBlockMask extends AbstractExtentMask {
public SolidBlockMask(Extent extent) {
super(extent);
}
@Override
public boolean test(Vector vector) {
Extent extent = getExtent();
BaseBlock lazyBlock = extent.getLazyBlock(vector);
return !BlockType.canPassThrough(lazyBlock.getType(), lazyBlock.getData());
}
@Nullable
@Override
public Mask2D toMask2D() {
return null;
}
}

View File

@ -0,0 +1,67 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import java.util.Iterator;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Sets block from an iterator of {@link Map.Entry} containing a
* {@link BlockVector} as the key and a {@link BaseBlock} as the value.
*/
public class BlockMapEntryPlacer implements Operation {
private final Extent extent;
private final Iterator<Map.Entry<BlockVector, BaseBlock>> iterator;
/**
* Create a new instance.
*
* @param extent the extent to set the blocks on
* @param iterator the iterator
*/
public BlockMapEntryPlacer(Extent extent, Iterator<Map.Entry<BlockVector, BaseBlock>> iterator) {
checkNotNull(extent);
checkNotNull(iterator);
this.extent = extent;
this.iterator = iterator;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
while (iterator.hasNext()) {
Map.Entry<BlockVector, BaseBlock> entry = iterator.next();
extent.setBlock(entry.getKey(), entry.getValue());
}
return null;
}
@Override
public void cancel() {
}
}

View File

@ -0,0 +1,104 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.history.change.Change;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import com.sk89q.worldedit.history.UndoContext;
import java.util.Iterator;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Performs an undo or redo from a given {@link ChangeSet}.
*/
public class ChangeSetExecutor implements Operation {
public enum Type {UNDO, REDO}
private final Iterator<Change> iterator;
private final Type type;
private final UndoContext context;
/**
* Create a new instance.
*
* @param changeSet the change set
* @param type type of change
* @param context the undo context
*/
private ChangeSetExecutor(ChangeSet changeSet, Type type, UndoContext context) {
checkNotNull(changeSet);
checkNotNull(type);
checkNotNull(context);
this.type = type;
this.context = context;
if (type == Type.UNDO) {
iterator = changeSet.backwardIterator();
} else {
iterator = changeSet.forwardIterator();
}
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
while (iterator.hasNext()) {
Change change = iterator.next();
if (type == Type.UNDO) {
change.undo(context);
} else {
change.redo(context);
}
}
return null;
}
@Override
public void cancel() {
}
/**
* Create a new undo operation.
*
* @param changeSet the change set
* @param context an undo context
* @return an operation
*/
public static ChangeSetExecutor createUndo(ChangeSet changeSet, UndoContext context) {
return new ChangeSetExecutor(changeSet, Type.UNDO, context);
}
/**
* Create a new redo operation.
*
* @param changeSet the change set
* @param context an undo context
* @return an operation
*/
public static ChangeSetExecutor createRedo(ChangeSet changeSet, UndoContext context) {
return new ChangeSetExecutor(changeSet, Type.REDO, context);
}
}

View File

@ -0,0 +1,60 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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(RunContext run) throws WorldEditException {
delegate = delegate.resume(run);
return delegate != null ? this : original;
}
@Override
public void cancel() {
delegate.cancel();
original.cancel();
}
}

View File

@ -0,0 +1,249 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
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.entity.ExtentEntityCopy;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
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 java.util.List;
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.
*
* <p>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.</p>
*/
public class ForwardExtentCopy implements Operation {
private final Extent source;
private final Extent destination;
private final Region region;
private final Vector from;
private final Vector to;
private int repetitions = 1;
private Mask sourceMask = Masks.alwaysTrue();
private boolean removingEntities;
private RegionFunction sourceFunction = null;
private Transform transform = new Identity();
private Transform currentTransform = null;
private RegionVisitor lastVisitor;
private int affected;
/**
* Create a new copy using the region's lowest minimum point as the
* "from" position.
*
* @param source the source extent
* @param region the region to copy
* @param destination the destination extent
* @param to the destination position
* @see #ForwardExtentCopy(Extent, Region, Vector, Extent, Vector) the main constructor
*/
public ForwardExtentCopy(Extent source, Region region, Extent destination, Vector to) {
this(source, region, region.getMinimumPoint(), destination, to);
}
/**
* Create a new copy.
*
* @param source the source extent
* @param region the region to copy
* @param from the source position
* @param destination the destination extent
* @param to the destination position
*/
public ForwardExtentCopy(Extent source, Region region, Vector from, Extent destination, Vector to) {
checkNotNull(source);
checkNotNull(region);
checkNotNull(from);
checkNotNull(destination);
checkNotNull(to);
this.source = source;
this.destination = destination;
this.region = region;
this.from = from;
this.to = to;
}
/**
* Get the transformation that will occur on every point.
*
* <p>The transformation will stack with each repetition.</p>
*
* @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.
*
* <p>This mask can be used to filter what will be copied from the source.</p>
*
* @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 function that gets applied to all source blocks <em>after</em>
* 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 <em>after</em>
* 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.
*
* @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;
}
/**
* Return whether entities that are copied should be removed.
*
* @return true if removing
*/
public boolean isRemovingEntities() {
return removingEntities;
}
/**
* Set whether entities that are copied should be removed.
*
* @param removingEntities true if removing
*/
public void setRemovingEntities(boolean removingEntities) {
this.removingEntities = removingEntities;
}
/**
* Get the number of affected objects.
*
* @return the number of affected
*/
public int getAffected() {
return affected;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
if (lastVisitor != null) {
affected += lastVisitor.getAffected();
lastVisitor = null;
}
if (repetitions > 0) {
repetitions--;
if (currentTransform == null) {
currentTransform = transform;
}
ExtentBlockCopy blockCopy = new ExtentBlockCopy(source, from, destination, to, currentTransform);
RegionMaskingFilter filter = new RegionMaskingFilter(sourceMask, blockCopy);
RegionFunction function = sourceFunction != null ? new CombinedRegionFunction(filter, sourceFunction) : filter;
RegionVisitor blockVisitor = new RegionVisitor(region, function);
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
entityCopy.setRemoving(removingEntities);
List<? extends Entity> entities = source.getEntities(region);
EntityVisitor entityVisitor = new EntityVisitor(entities.iterator(), entityCopy);
lastVisitor = blockVisitor;
currentTransform = currentTransform.combine(transform);
return new DelegateOperation(this, new OperationQueue(blockVisitor, entityVisitor));
} else {
return null;
}
}
@Override
public void cancel() {
}
}

View File

@ -0,0 +1,52 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.WorldEditException;
/**
* An task that may be split into multiple steps to be run sequentially
* immediately or at a varying or fixed interval. Operations should attempt
* to break apart tasks into smaller tasks that can be completed in quicker
* successions.
*/
public interface Operation {
/**
* Complete the next step. If this method returns true, then the method may
* be called again in the future, or possibly never. If this method
* returns false, then this method should not be called again.
*
* @param run describes information about the current run
* @return another operation to run that operation again, or null to stop
* @throws WorldEditException an error
*/
Operation resume(RunContext run) throws WorldEditException;
/**
* Abort the current task. After the this method is called,
* {@link #resume(RunContext)} should not be called at any point in the
* future. This method should not be called after successful completion of
* the operation. This method must be called if the operation is
* interrupted before completion.
*/
void cancel();
}

View File

@ -0,0 +1,103 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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<Operation> queue = new ArrayDeque<Operation>();
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<Operation> 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(RunContext run) throws WorldEditException {
if (current == null && !queue.isEmpty()) {
current = queue.poll();
}
if (current != null) {
current = current.resume(run);
if (current == null) {
current = queue.poll();
}
}
return current != null ? this : null;
}
@Override
public void cancel() {
for (Operation operation : queue) {
operation.cancel();
}
queue.clear();
}
}

View File

@ -0,0 +1,81 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
/**
* Operation helper methods.
*/
public final class Operations {
private Operations() {
}
/**
* Complete a given operation synchronously until it completes.
*
* @param op operation to execute
* @throws WorldEditException WorldEdit exception
*/
public static void complete(Operation op) throws WorldEditException {
while (op != null) {
op = op.resume(new RunContext());
}
}
/**
* Complete a given operation synchronously until it completes. Catch all
* errors that is not {@link MaxChangedBlocksException} for legacy reasons.
*
* @param op operation to execute
* @throws MaxChangedBlocksException thrown when too many blocks have been changed
*/
public static void completeLegacy(Operation op) throws MaxChangedBlocksException {
while (op != null) {
try {
op = op.resume(new RunContext());
} catch (MaxChangedBlocksException e) {
throw e;
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
}
/**
* 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(new RunContext());
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@ -0,0 +1,38 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
/**
* Describes the current run.
*/
public class RunContext {
/**
* Return whether the current operation should still continue running.
*
* <p>This method can be called frequently.</p>
*
* @return true if the operation should continue running
*/
public boolean shouldContinue() {
return true;
}
}

View File

@ -0,0 +1,26 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.pattern;
/**
* An abstract implementation for {@link Pattern}s.
*/
public abstract class AbstractPattern implements Pattern {
}

View File

@ -0,0 +1,67 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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;
}
}

View File

@ -0,0 +1,56 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A pattern that reads from {@link Clipboard}.
*/
public class ClipboardPattern extends AbstractPattern {
private final Clipboard clipboard;
private final Vector size;
/**
* Create a new clipboard pattern.
*
* @param clipboard the clipboard
*/
public ClipboardPattern(Clipboard clipboard) {
checkNotNull(clipboard);
this.clipboard = clipboard;
this.size = clipboard.getMaximumPoint().subtract(clipboard.getMinimumPoint()).add(1, 1, 1);
}
@Override
public BaseBlock apply(Vector position) {
int xp = Math.abs(position.getBlockX()) % size.getBlockX();
int yp = Math.abs(position.getBlockY()) % size.getBlockY();
int zp = Math.abs(position.getBlockZ()) % size.getBlockZ();
return clipboard.getBlock(clipboard.getMinimumPoint().add(new Vector(xp, yp, zp)));
}
}

View File

@ -0,0 +1,38 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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);
}

View File

@ -0,0 +1,72 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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);
}
};
}
/**
* Wrap a new-style pattern and return an old-style pattern.
*
* @param pattern the pattern
* @return an old-style pattern
*/
public static com.sk89q.worldedit.patterns.Pattern wrap(final Pattern pattern) {
checkNotNull(pattern);
return new com.sk89q.worldedit.patterns.Pattern() {
@Override
public BaseBlock next(Vector position) {
return pattern.apply(position);
}
@Override
public BaseBlock next(int x, int y, int z) {
return next(new Vector(x, y, z));
}
};
}
}

View File

@ -0,0 +1,88 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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<Chance> patterns = new ArrayList<Chance>();
private double max = 0;
/**
* Add a pattern to the weight list of patterns.
*
* <p>The probability for the pattern added is chance / max where max is
* the sum of the probabilities of all added patterns.</p>
*
* @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;
}
}
}

View File

@ -0,0 +1,95 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.pattern;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Returns the blocks from {@link Extent}, repeating when out of bounds.
*/
public class RepeatingExtentPattern extends AbstractPattern {
private Extent extent;
private Vector offset;
/**
* Create a new instance.
*
* @param extent the extent
* @param offset the offset
*/
public RepeatingExtentPattern(Extent extent, Vector offset) {
setExtent(extent);
setOffset(offset);
}
/**
* 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;
}
/**
* Get the offset.
*
* @return the offset
*/
public Vector getOffset() {
return offset;
}
/**
* Set the offset.
*
* @param offset the offset
*/
public void setOffset(Vector offset) {
checkNotNull(offset);
this.offset = offset;
}
@Override
public BaseBlock apply(Vector position) {
Vector base = position.add(offset);
Vector size = extent.getMaximumPoint().subtract(extent.getMinimumPoint()).add(1, 1, 1);
int x = base.getBlockX() % size.getBlockX();
int y = base.getBlockY() % size.getBlockY();
int z = base.getBlockZ() % size.getBlockZ();
return extent.getBlock(new Vector(x, y, z));
}
}

View File

@ -0,0 +1,71 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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));
}
}

View File

@ -0,0 +1,72 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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));
}
}

View File

@ -0,0 +1,179 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.RunContext;
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
* to a certain adjacent point provided that the method
* {@link #isVisitable(com.sk89q.worldedit.Vector, com.sk89q.worldedit.Vector)}
* returns true for that point.
*
* <p>As an abstract implementation, this class can be used to implement
* functionality that starts at certain points and extends outward from
* those points.</p>
*/
public abstract class BreadthFirstSearch implements Operation {
private final RegionFunction function;
private final Queue<BlockVector> queue = new ArrayDeque<BlockVector>();
private final Set<BlockVector> visited = new HashSet<BlockVector>();
private final List<Vector> directions = new ArrayList<Vector>();
private int affected = 0;
/**
* Create a new instance.
*
* @param function the function to apply to visited blocks
*/
protected BreadthFirstSearch(RegionFunction function) {
checkNotNull(function);
this.function = function;
addAxes();
}
/**
* Get the list of directions will be visited.
*
* <p>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)}.</p>
*
* <p>The list of directions can be cleared.</p>
*
* @return the list of directions
*/
protected Collection<Vector> 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)}.
*
* <p>This method should be used before the search begins, because if
* the position <em>does</em> 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.</p>
*
* @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(RunContext run) 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() {
}
}

View File

@ -0,0 +1,68 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.Mask;
import java.util.Collection;
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
* function on the entire column.
*
* <p>This is used by {@code //fill}.</p>
*/
public class DownwardVisitor extends RecursiveVisitor {
private int baseY;
/**
* Create a new visitor.
*
* @param mask the mask
* @param function the function
* @param baseY the base Y
*/
public DownwardVisitor(Mask mask, RegionFunction function, int baseY) {
super(mask, function);
checkNotNull(mask);
this.baseY = baseY;
Collection<Vector> 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);
}
}

View File

@ -0,0 +1,78 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import java.util.Iterator;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Visits entities as provided by an {@code Iterator}.
*/
public class EntityVisitor implements Operation {
private final Iterator<? extends Entity> iterator;
private final EntityFunction function;
private int affected = 0;
/**
* Create a new instance.
*
* @param iterator the iterator
* @param function the function
*/
public EntityVisitor(Iterator<? extends Entity> iterator, EntityFunction function) {
checkNotNull(iterator);
checkNotNull(function);
this.iterator = iterator;
this.function = function;
}
/**
* Get the number of affected objects.
*
* @return the number of affected
*/
public int getAffected() {
return affected;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
while (iterator.hasNext()) {
if (function.apply(iterator.next())) {
affected++;
}
}
return null;
}
@Override
public void cancel() {
}
}

View File

@ -0,0 +1,79 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
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.function.operation.RunContext;
import com.sk89q.worldedit.regions.FlatRegion;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Applies region functions to columns in a {@link FlatRegion}.
*/
public class FlatRegionVisitor implements Operation {
private final FlatRegion flatRegion;
private final FlatRegionFunction function;
private int affected = 0;
/**
* 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);
this.flatRegion = flatRegion;
this.function = function;
}
/**
* Get the number of affected objects.
*
* @return the number of affected
*/
public int getAffected() {
return affected;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
for (Vector2D pt : flatRegion.asFlatRegion()) {
if (function.apply(pt)) {
affected++;
}
}
return null;
}
@Override
public void cancel() {
}
}

View File

@ -0,0 +1,128 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.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.mask.Mask2D;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
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.
*
* <p>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.</p>
*/
public class LayerVisitor implements Operation {
private final FlatRegion flatRegion;
private final LayerFunction function;
private Mask2D mask = Masks.alwaysTrue2D();
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(RunContext run) throws WorldEditException {
for (Vector2D column : flatRegion.asFlatRegion()) {
if (!mask.test(column)) {
continue;
}
// 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() {
}
}

View File

@ -0,0 +1,50 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.Mask;
import java.util.Collection;
/**
* A {@link RecursiveVisitor} that goes orthogonally to the side and down, but never up.
*/
public class NonRisingVisitor extends RecursiveVisitor {
/**
* Create a new recursive visitor.
*
* @param mask the mask
* @param function the function
*/
public NonRisingVisitor(Mask mask, RegionFunction function) {
super(mask, function);
Collection<Vector> 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));
}
}

View File

@ -0,0 +1,52 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
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.
*/
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;
}
@Override
protected boolean isVisitable(Vector from, Vector to) {
return mask.test(to);
}
}

View File

@ -0,0 +1,68 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.visitor;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.operation.RunContext;
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(RunContext run) throws WorldEditException {
for (Vector pt : region) {
if (function.apply(pt)) {
affected++;
}
}
return null;
}
@Override
public void cancel() {
}
}