use of com.sk89q.worldedit.function.visitor.RecursiveVisitor in project FastAsyncWorldEdit by IntellectualSites.
the class ScatterBrush method build.
@Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException {
this.mask = editSession.getMask();
if (this.mask == null) {
this.mask = Masks.alwaysTrue();
}
surface = new SurfaceMask(editSession);
final RadiusMask radius = new RadiusMask(0, (int) size);
final int distance = Math.min((int) size, this.distance);
RecursiveVisitor visitor = new RecursiveVisitor(new MaskIntersection(radius, surface), function -> true, Integer.MAX_VALUE, editSession.getMinY(), editSession.getMaxY());
visitor.visit(position);
visitor.setDirections(Arrays.asList(BreadthFirstSearch.DIAGONAL_DIRECTIONS));
Operations.completeBlindly(visitor);
BlockVectorSet visited = visitor.getVisited();
int length = visited.size();
if (size == 0) {
length = 1;
visited.add(position);
}
LocalBlockVectorSet placed = new LocalBlockVectorSet();
placed.setOffset(position.getX(), position.getZ());
int maxFails = 1000;
for (int i = 0; i < count; i++) {
int index = ThreadLocalRandom.current().nextInt(length);
BlockVector3 pos = visited.get(index);
if (pos != null && canApply(pos)) {
int x = pos.getBlockX();
int y = pos.getBlockY();
int z = pos.getBlockZ();
if (placed.containsRadius(x, y, z, distance)) {
if (maxFails-- <= 0) {
break;
}
i--;
continue;
}
placed.add(x, y, z);
apply(editSession, placed, pos, pattern, size);
}
}
finish(editSession, placed, position, pattern, size);
}
use of com.sk89q.worldedit.function.visitor.RecursiveVisitor in project FastAsyncWorldEdit by IntellectualSites.
the class FloodFillTool method actPrimary.
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
World world = (World) clicked.getExtent();
BlockVector3 origin = clicked.toVector().toBlockPoint();
BlockType initialType = world.getBlock(origin).getBlockType();
if (initialType.getMaterial().isAir()) {
return true;
}
if (initialType == BlockTypes.BEDROCK && !player.canDestroyBedrock()) {
return true;
}
try (EditSession editSession = session.createEditSession(player, "FloodFillTool")) {
try {
// FAWE start - Respect masks
Mask mask = initialType.toMask(editSession);
BlockReplace function = new BlockReplace(editSession, pattern);
RecursiveVisitor visitor = new RecursiveVisitor(mask, function, range, editSession.getMinY(), editSession.getMaxY(), editSession);
visitor.visit(origin);
Operations.completeLegacy(visitor);
// FAWE end
} catch (MaxChangedBlocksException e) {
player.print(Caption.of("worldedit.tool.max-block-changes"));
} finally {
session.remember(editSession);
}
}
return true;
}
use of com.sk89q.worldedit.function.visitor.RecursiveVisitor in project FastAsyncWorldEdit by IntellectualSites.
the class RecursivePickaxe method actPrimary.
@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
World world = (World) clicked.getExtent();
final BlockVector3 pos = clicked.toBlockPoint();
BlockVector3 origin = clicked.toVector().toBlockPoint();
BlockType initialType = world.getBlock(origin).getBlockType();
if (initialType.getMaterial().isAir()) {
return false;
}
if (initialType == BlockTypes.BEDROCK && !player.canDestroyBedrock()) {
return false;
}
try (EditSession editSession = session.createEditSession(player, "RecursivePickaxe")) {
editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop);
// FAWE start
final int radius = (int) range;
final BlockReplace replace = new BlockReplace(editSession, (BlockTypes.AIR.getDefaultState()));
editSession.setMask(null);
RecursiveVisitor visitor = new RecursiveVisitor(new IdMask(editSession), replace, radius, editSession.getMinY(), editSession.getMaxY(), editSession);
// TODO: Fix below
// visitor.visit(pos);
// Operations.completeBlindly(visitor);
recurse(server, editSession, world, pos, origin, radius, initialType, visitor.getVisited());
// FAWE end
editSession.flushQueue();
session.remember(editSession);
}
return true;
}
use of com.sk89q.worldedit.function.visitor.RecursiveVisitor in project FastAsyncWorldEdit by IntellectualSites.
the class EditSession method fillDirection.
/**
* Fills an area recursively in the X/Z directions.
*
* @param origin the location to start from
* @param pattern the block to fill with
* @param radius the radius of the spherical area to fill
* @param depth the maximum depth, starting from the origin
* @param direction the direction to fill
* @return the number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int fillDirection(final BlockVector3 origin, final Pattern pattern, final double radius, final int depth, BlockVector3 direction) throws MaxChangedBlocksException {
checkNotNull(origin);
checkNotNull(pattern);
checkArgument(radius >= 0, "radius >= 0");
checkArgument(depth >= 1, "depth >= 1");
if (direction.equals(BlockVector3.UNIT_MINUS_Y)) {
return fillXZ(origin, pattern, radius, depth, false);
}
Mask mask = new MaskIntersection(new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), Masks.negate(new ExistingBlockMask(EditSession.this)));
// Want to replace blocks
final BlockReplace replace = new BlockReplace(EditSession.this, pattern);
// Pick how we're going to visit blocks
RecursiveVisitor visitor = new DirectionalVisitor(mask, replace, origin, direction, (int) (radius * 2 + 1), minY, maxY);
// Start at the origin
visitor.visit(origin);
// Execute
Operations.completeBlindly(visitor);
return this.changes = visitor.getAffected();
}
use of com.sk89q.worldedit.function.visitor.RecursiveVisitor in project FastAsyncWorldEdit by IntellectualSites.
the class EditSession method drainArea.
/**
* Drain nearby pools of water or lava, optionally removed waterlogged states from blocks.
*
* @param origin the origin to drain from, which will search a 3x3 area
* @param radius the radius of the removal, where a value should be 0 or greater
* @param waterlogged true to make waterlogged blocks non-waterlogged as well
* @param plants true to remove underwater plants
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drainArea(BlockVector3 origin, double radius, boolean waterlogged, boolean plants) throws MaxChangedBlocksException {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
// FAWE start - liquidmask
Mask liquidMask;
if (plants) {
liquidMask = new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER, BlockTypes.BUBBLE_COLUMN, BlockTypes.KELP_PLANT, BlockTypes.KELP, BlockTypes.SEAGRASS, BlockTypes.TALL_SEAGRASS);
} else {
liquidMask = new BlockMaskBuilder().addTypes(BlockTypes.WATER, BlockTypes.LAVA, BlockTypes.BUBBLE_COLUMN).build(this);
}
// FAWE end
if (waterlogged) {
Map<String, String> stateMap = new HashMap<>();
stateMap.put("waterlogged", "true");
// FAWE start
liquidMask = new MaskUnion(liquidMask, new BlockStateMask(this, stateMap, true));
// FAWE end
}
Mask mask = new MaskIntersection(new BoundedHeightMask(minY, maxY), new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), // FAWE start
liquidMask);
// FAWE end
BlockReplace replace;
if (waterlogged) {
replace = new BlockReplace(this, new WaterloggedRemover(this));
} else {
replace = new BlockReplace(this, BlockTypes.AIR.getDefaultState());
}
// FAWE start - provide extent for preloading, min/max y
RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), minY, maxY, this);
// Around the origin in a 3x3 block
for (BlockVector3 position : CuboidRegion.fromCenter(origin, 1)) {
if (mask.test(position)) {
visitor.visit(position);
}
}
Operations.completeLegacy(visitor);
// FAWE start
return this.changes = visitor.getAffected();
// FAWE end
}
Aggregations