|
21 | 21 |
|
22 | 22 | import com.fastasyncworldedit.core.configuration.Caption; |
23 | 23 | import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder; |
| 24 | +import com.fastasyncworldedit.core.extent.filter.ForkedFilter; |
| 25 | +import com.fastasyncworldedit.core.extent.filter.MaskFilter; |
| 26 | +import com.fastasyncworldedit.core.extent.filter.block.FilterBlock; |
24 | 27 | import com.fastasyncworldedit.core.function.mask.IdMask; |
| 28 | +import com.fastasyncworldedit.core.queue.Filter; |
25 | 29 | import com.fastasyncworldedit.core.regions.selector.FuzzyRegionSelector; |
26 | 30 | import com.fastasyncworldedit.core.regions.selector.PolyhedralRegionSelector; |
27 | 31 | import com.fastasyncworldedit.core.util.MaskTraverser; |
|
48 | 52 | import com.sk89q.worldedit.function.block.BlockDistributionCounter; |
49 | 53 | import com.sk89q.worldedit.function.mask.Mask; |
50 | 54 | import com.sk89q.worldedit.function.mask.MaskIntersection; |
51 | | -import com.sk89q.worldedit.function.mask.Masks; |
52 | 55 | import com.sk89q.worldedit.function.mask.RegionMask; |
53 | 56 | import com.sk89q.worldedit.function.operation.Operations; |
54 | 57 | import com.sk89q.worldedit.function.visitor.RegionVisitor; |
@@ -518,125 +521,99 @@ private BlockVector3[] getChangesForEachDir(int amount, boolean onlyHorizontal, |
518 | 521 | ) |
519 | 522 | @Logging(REGION) |
520 | 523 | @CommandPermissions("worldedit.selection.trim") |
521 | | - public void trim(Actor actor, World world, LocalSession session, |
| 524 | + public void trim(Actor actor, World world, LocalSession session, EditSession editSession, |
522 | 525 | @Arg(desc = "Mask of blocks to keep within the selection", def = "#existing") |
523 | 526 | Mask mask) throws WorldEditException { |
| 527 | + //FAWE start |
524 | 528 | // Avoid checking blocks outside the original region but within the cuboid region |
525 | 529 | Region originalRegion = session.getSelection(world); |
526 | | - if (!(originalRegion instanceof CuboidRegion)) { |
527 | | - mask = new MaskIntersection(new RegionMask(originalRegion), mask); |
528 | | - } |
| 530 | + new MaskTraverser(mask).setNewExtent(editSession); |
529 | 531 |
|
530 | 532 | // Result region will be cuboid |
531 | | - CuboidRegion region = originalRegion.getBoundingBox(); |
532 | | - |
533 | | - BlockVector3 min = region.getMinimumPoint(); |
534 | | - BlockVector3 max = region.getMaximumPoint(); |
535 | | - |
536 | | - int minY = 0; |
537 | | - boolean found = false; |
538 | | - |
539 | | - outer: for (int y = min.y(); y <= max.y(); y++) { |
540 | | - for (int x = min.x(); x <= max.x(); x++) { |
541 | | - for (int z = min.z(); z <= max.z(); z++) { |
542 | | - BlockVector3 vec = BlockVector3.at(x, y, z); |
543 | | - |
544 | | - if (mask.test(vec)) { |
545 | | - found = true; |
546 | | - minY = y; |
547 | | - |
548 | | - break outer; |
549 | | - } |
550 | | - } |
| 533 | + final CuboidRegion region = originalRegion.getBoundingBox(); |
| 534 | + |
| 535 | + // subtract offset to determine if there was any change later |
| 536 | + final BlockVector3 min = region.getMinimumPoint().subtract(BlockVector3.ONE); |
| 537 | + final BlockVector3 max = region.getMaximumPoint(); |
| 538 | + |
| 539 | + class TrimFilter extends ForkedFilter<TrimFilter> { |
| 540 | + private int minX; |
| 541 | + private int minY; |
| 542 | + private int minZ; |
| 543 | + private int maxX; |
| 544 | + private int maxY; |
| 545 | + private int maxZ; |
| 546 | + |
| 547 | + public TrimFilter(final BlockVector3 min, final BlockVector3 max) { |
| 548 | + super(null); |
| 549 | + this.minX = max.x(); |
| 550 | + this.minY = max.y(); |
| 551 | + this.minZ = max.z(); |
| 552 | + this.maxX = min.x(); |
| 553 | + this.maxY = min.y(); |
| 554 | + this.maxZ = min.z(); |
551 | 555 | } |
552 | | - } |
553 | 556 |
|
554 | | - // If anything was found in the first pass, then the remaining variables are guaranteed to be set |
555 | | - if (!found) { |
556 | | - throw new StopExecutionException(Caption.of("worldedit.trim.no-blocks")); |
557 | | - } |
558 | | - |
559 | | - int maxY = minY; |
560 | | - |
561 | | - outer: for (int y = max.y(); y > minY; y--) { |
562 | | - for (int x = min.x(); x <= max.x(); x++) { |
563 | | - for (int z = min.z(); z <= max.z(); z++) { |
564 | | - BlockVector3 vec = BlockVector3.at(x, y, z); |
565 | | - |
566 | | - if (mask.test(vec)) { |
567 | | - maxY = y; |
568 | | - break outer; |
569 | | - } |
570 | | - } |
| 557 | + public TrimFilter( |
| 558 | + final TrimFilter root, |
| 559 | + final int minX, |
| 560 | + final int minY, |
| 561 | + final int minZ, |
| 562 | + final int maxX, |
| 563 | + final int maxY, |
| 564 | + final int maxZ |
| 565 | + ) { |
| 566 | + super(root); |
| 567 | + this.minX = minX; |
| 568 | + this.minY = minY; |
| 569 | + this.minZ = minZ; |
| 570 | + this.maxX = maxX; |
| 571 | + this.maxY = maxY; |
| 572 | + this.maxZ = maxZ; |
571 | 573 | } |
572 | | - } |
573 | | - |
574 | | - int minX = 0; |
575 | 574 |
|
576 | | - outer: for (int x = min.x(); x <= max.x(); x++) { |
577 | | - for (int z = min.z(); z <= max.z(); z++) { |
578 | | - for (int y = minY; y <= maxY; y++) { |
579 | | - BlockVector3 vec = BlockVector3.at(x, y, z); |
580 | | - |
581 | | - if (mask.test(vec)) { |
582 | | - minX = x; |
583 | | - break outer; |
584 | | - } |
585 | | - } |
| 575 | + @Override |
| 576 | + public void applyBlock(final FilterBlock block) { |
| 577 | + this.minX = Math.min(this.minX, block.x()); |
| 578 | + this.maxX = Math.max(this.maxX, block.x()); |
| 579 | + this.minY = Math.min(this.minY, block.y()); |
| 580 | + this.maxY = Math.max(this.maxY, block.y()); |
| 581 | + this.minZ = Math.min(this.minZ, block.z()); |
| 582 | + this.maxZ = Math.max(this.maxZ, block.z()); |
586 | 583 | } |
587 | | - } |
588 | | - |
589 | | - int maxX = minX; |
590 | 584 |
|
591 | | - outer: for (int x = max.x(); x > minX; x--) { |
592 | | - for (int z = min.z(); z <= max.z(); z++) { |
593 | | - for (int y = minY; y <= maxY; y++) { |
594 | | - BlockVector3 vec = BlockVector3.at(x, y, z); |
595 | | - |
596 | | - if (mask.test(vec)) { |
597 | | - maxX = x; |
598 | | - break outer; |
599 | | - } |
600 | | - } |
| 585 | + @Override |
| 586 | + public TrimFilter init() { |
| 587 | + return new TrimFilter(this, this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ); |
601 | 588 | } |
602 | | - } |
603 | | - |
604 | | - int minZ = 0; |
605 | | - |
606 | | - outer: for (int z = min.z(); z <= max.z(); z++) { |
607 | | - for (int x = minX; x <= maxX; x++) { |
608 | | - for (int y = minY; y <= maxY; y++) { |
609 | | - BlockVector3 vec = BlockVector3.at(x, y, z); |
610 | 589 |
|
611 | | - if (mask.test(vec)) { |
612 | | - minZ = z; |
613 | | - break outer; |
614 | | - } |
615 | | - } |
| 590 | + @Override |
| 591 | + public void join(final TrimFilter filter) { |
| 592 | + this.minX = Math.min(this.minX, filter.minX); |
| 593 | + this.maxX = Math.max(this.maxX, filter.maxX); |
| 594 | + this.minY = Math.min(this.minY, filter.minY); |
| 595 | + this.maxY = Math.max(this.maxY, filter.maxY); |
| 596 | + this.minZ = Math.min(this.minZ, filter.minZ); |
| 597 | + this.maxZ = Math.max(this.maxZ, filter.maxZ); |
616 | 598 | } |
617 | | - } |
618 | | - |
619 | | - int maxZ = minZ; |
620 | | - |
621 | | - outer: for (int z = max.z(); z > minZ; z--) { |
622 | | - for (int x = minX; x <= maxX; x++) { |
623 | | - for (int y = minY; y <= maxY; y++) { |
624 | | - BlockVector3 vec = BlockVector3.at(x, y, z); |
625 | 599 |
|
626 | | - if (mask.test(vec)) { |
627 | | - maxZ = z; |
628 | | - break outer; |
629 | | - } |
630 | | - } |
631 | | - } |
632 | 600 | } |
| 601 | + TrimFilter result = editSession.apply(region, new MaskFilter<>(new TrimFilter(min, max), mask), true).getParent(); |
633 | 602 |
|
634 | 603 | final CuboidRegionSelector selector; |
| 604 | + final BlockVector3 newMin = BlockVector3.at(result.minX, result.minY, result.minZ); |
| 605 | + final BlockVector3 newMax = BlockVector3.at(result.maxX, result.maxY, result.maxZ); |
| 606 | + |
| 607 | + // If anything was found, then all variables are guaranteed to be set to something inside the region |
| 608 | + if (newMax.equals(min)) { |
| 609 | + throw new StopExecutionException(Caption.of("worldedit.trim.no-blocks")); |
| 610 | + } |
635 | 611 | if (session.getRegionSelector(world) instanceof ExtendingCuboidRegionSelector) { |
636 | | - selector = new ExtendingCuboidRegionSelector(world, BlockVector3.at(minX, minY, minZ), BlockVector3.at(maxX, maxY, maxZ)); |
| 612 | + selector = new ExtendingCuboidRegionSelector(world, newMin, newMax); |
637 | 613 | } else { |
638 | | - selector = new CuboidRegionSelector(world, BlockVector3.at(minX, minY, minZ), BlockVector3.at(maxX, maxY, maxZ)); |
| 614 | + selector = new CuboidRegionSelector(world, newMin, newMax); |
639 | 615 | } |
| 616 | + //FAWE end |
640 | 617 | session.setRegionSelector(world, selector); |
641 | 618 |
|
642 | 619 | session.getRegionSelector(world).learnChanges(); |
|
0 commit comments