Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@

import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder;
import com.fastasyncworldedit.core.extent.filter.ForkedFilter;
import com.fastasyncworldedit.core.extent.filter.MaskFilter;
import com.fastasyncworldedit.core.extent.filter.block.FilterBlock;
import com.fastasyncworldedit.core.function.mask.IdMask;
import com.fastasyncworldedit.core.queue.Filter;
import com.fastasyncworldedit.core.regions.selector.FuzzyRegionSelector;
import com.fastasyncworldedit.core.regions.selector.PolyhedralRegionSelector;
import com.fastasyncworldedit.core.util.MaskTraverser;
Expand All @@ -48,7 +52,6 @@
import com.sk89q.worldedit.function.block.BlockDistributionCounter;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.RegionMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
Expand Down Expand Up @@ -518,125 +521,99 @@ private BlockVector3[] getChangesForEachDir(int amount, boolean onlyHorizontal,
)
@Logging(REGION)
@CommandPermissions("worldedit.selection.trim")
public void trim(Actor actor, World world, LocalSession session,
public void trim(Actor actor, World world, LocalSession session, EditSession editSession,
@Arg(desc = "Mask of blocks to keep within the selection", def = "#existing")
Mask mask) throws WorldEditException {
//FAWE start
// Avoid checking blocks outside the original region but within the cuboid region
Region originalRegion = session.getSelection(world);
if (!(originalRegion instanceof CuboidRegion)) {
mask = new MaskIntersection(new RegionMask(originalRegion), mask);
}
new MaskTraverser(mask).setNewExtent(editSession);

// Result region will be cuboid
CuboidRegion region = originalRegion.getBoundingBox();

BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();

int minY = 0;
boolean found = false;

outer: for (int y = min.y(); y <= max.y(); y++) {
for (int x = min.x(); x <= max.x(); x++) {
for (int z = min.z(); z <= max.z(); z++) {
BlockVector3 vec = BlockVector3.at(x, y, z);

if (mask.test(vec)) {
found = true;
minY = y;

break outer;
}
}
final CuboidRegion region = originalRegion.getBoundingBox();

// subtract offset to determine if there was any change later
final BlockVector3 min = region.getMinimumPoint().subtract(BlockVector3.ONE);
final BlockVector3 max = region.getMaximumPoint();

class TrimFilter extends ForkedFilter<TrimFilter> {
private int minX;
private int minY;
private int minZ;
private int maxX;
private int maxY;
private int maxZ;

public TrimFilter(final BlockVector3 min, final BlockVector3 max) {
super(null);
this.minX = max.x();
this.minY = max.y();
this.minZ = max.z();
this.maxX = min.x();
this.maxY = min.y();
this.maxZ = min.z();
}
}

// If anything was found in the first pass, then the remaining variables are guaranteed to be set
if (!found) {
throw new StopExecutionException(Caption.of("worldedit.trim.no-blocks"));
}

int maxY = minY;

outer: for (int y = max.y(); y > minY; y--) {
for (int x = min.x(); x <= max.x(); x++) {
for (int z = min.z(); z <= max.z(); z++) {
BlockVector3 vec = BlockVector3.at(x, y, z);

if (mask.test(vec)) {
maxY = y;
break outer;
}
}
public TrimFilter(
final TrimFilter root,
final int minX,
final int minY,
final int minZ,
final int maxX,
final int maxY,
final int maxZ
) {
super(root);
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.maxX = maxX;
this.maxY = maxY;
this.maxZ = maxZ;
}
}

int minX = 0;

outer: for (int x = min.x(); x <= max.x(); x++) {
for (int z = min.z(); z <= max.z(); z++) {
for (int y = minY; y <= maxY; y++) {
BlockVector3 vec = BlockVector3.at(x, y, z);

if (mask.test(vec)) {
minX = x;
break outer;
}
}
@Override
public void applyBlock(final FilterBlock block) {
this.minX = Math.min(this.minX, block.x());
this.maxX = Math.max(this.maxX, block.x());
this.minY = Math.min(this.minY, block.y());
this.maxY = Math.max(this.maxY, block.y());
this.minZ = Math.min(this.minZ, block.z());
this.maxZ = Math.max(this.maxZ, block.z());
}
}

int maxX = minX;

outer: for (int x = max.x(); x > minX; x--) {
for (int z = min.z(); z <= max.z(); z++) {
for (int y = minY; y <= maxY; y++) {
BlockVector3 vec = BlockVector3.at(x, y, z);

if (mask.test(vec)) {
maxX = x;
break outer;
}
}
@Override
public TrimFilter init() {
return new TrimFilter(this, this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ);
}
}

int minZ = 0;

outer: for (int z = min.z(); z <= max.z(); z++) {
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
BlockVector3 vec = BlockVector3.at(x, y, z);

if (mask.test(vec)) {
minZ = z;
break outer;
}
}
@Override
public void join(final TrimFilter filter) {
this.minX = Math.min(this.minX, filter.minX);
this.maxX = Math.max(this.maxX, filter.maxX);
this.minY = Math.min(this.minY, filter.minY);
this.maxY = Math.max(this.maxY, filter.maxY);
this.minZ = Math.min(this.minZ, filter.minZ);
this.maxZ = Math.max(this.maxZ, filter.maxZ);
}
}

int maxZ = minZ;

outer: for (int z = max.z(); z > minZ; z--) {
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
BlockVector3 vec = BlockVector3.at(x, y, z);

if (mask.test(vec)) {
maxZ = z;
break outer;
}
}
}
}
TrimFilter result = editSession.apply(region, new MaskFilter<>(new TrimFilter(min, max), mask), true).getParent();

final CuboidRegionSelector selector;
final BlockVector3 newMin = BlockVector3.at(result.minX, result.minY, result.minZ);
final BlockVector3 newMax = BlockVector3.at(result.maxX, result.maxY, result.maxZ);

// If anything was found, then all variables are guaranteed to be set to something inside the region
if (newMax.equals(min)) {
throw new StopExecutionException(Caption.of("worldedit.trim.no-blocks"));
}
if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) {
selector = new ExtendingCuboidRegionSelector(world, BlockVector3.at(minX, minY, minZ), BlockVector3.at(maxX, maxY, maxZ));
selector = new ExtendingCuboidRegionSelector(world, newMin, newMax);
} else {
selector = new CuboidRegionSelector(world, BlockVector3.at(minX, minY, minZ), BlockVector3.at(maxX, maxY, maxZ));
selector = new CuboidRegionSelector(world, newMin, newMax);
}
//FAWE end
session.setRegionSelector(world, selector);

session.getRegionSelector(world).learnChanges();
Expand Down
Loading