Skip to content

Commit 44f7b63

Browse files
dordsor21me4502
andauthored
Allow stacking by block units with //stack (#1539) (#2973)
- closes #2968 Co-authored-by: Matthew Miller <[email protected]>
1 parent c213dae commit 44f7b63

File tree

3 files changed

+59
-9
lines changed

3 files changed

+59
-9
lines changed

worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
import com.sk89q.worldedit.regions.NullRegion;
128128
import com.sk89q.worldedit.regions.Region;
129129
import com.sk89q.worldedit.regions.RegionIntersection;
130+
import com.sk89q.worldedit.regions.RegionOperationException;
130131
import com.sk89q.worldedit.regions.Regions;
131132
import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape;
132133
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
@@ -1804,18 +1805,59 @@ public int stackCuboidRegion(Region region, BlockVector3 dir, int count, boolean
18041805
* @throws MaxChangedBlocksException thrown if too many blocks are changed
18051806
*/
18061807
public int stackCuboidRegion(
1807-
Region region, BlockVector3 offset, int count,
1808-
boolean copyEntities, boolean copyBiomes, Mask mask
1808+
Region region,
1809+
BlockVector3 offset,
1810+
int count,
1811+
boolean copyEntities,
1812+
boolean copyBiomes,
1813+
Mask mask
18091814
) throws MaxChangedBlocksException {
18101815
checkNotNull(region);
18111816
checkNotNull(offset);
1817+
1818+
BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
1819+
try {
1820+
return stackRegionBlockUnits(region, offset.multiply(size), count, copyEntities, copyBiomes, mask);
1821+
} catch (RegionOperationException e) {
1822+
// Should never be able to happen
1823+
throw new AssertionError(e);
1824+
}
1825+
}
1826+
1827+
/**
1828+
* Stack a region using block units.
1829+
*
1830+
* @param region the region to stack
1831+
* @param offset how far to move the contents each stack in block units
1832+
* @param count the number of times to stack
1833+
* @param copyEntities true to copy entities
1834+
* @param copyBiomes true to copy biomes
1835+
* @param mask source mask for the operation (only matching blocks are copied)
1836+
* @return number of blocks affected
1837+
* @throws MaxChangedBlocksException thrown if too many blocks are changed
1838+
* @throws RegionOperationException thrown if the region operation is invalid
1839+
*/
1840+
public int stackRegionBlockUnits(
1841+
Region region,
1842+
BlockVector3 offset,
1843+
int count,
1844+
boolean copyEntities,
1845+
boolean copyBiomes,
1846+
Mask mask
1847+
) throws MaxChangedBlocksException, RegionOperationException {
1848+
checkNotNull(region);
1849+
checkNotNull(offset);
18121850
checkArgument(count >= 1, "count >= 1 required");
18131851

18141852
BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
1853+
BlockVector3 offsetAbs = offset.abs();
1854+
if (offsetAbs.x() < size.x() && offsetAbs.y() < size.y() && offsetAbs.z() < size.z()) {
1855+
throw new RegionOperationException(Caption.of("worldedit.stack.intersecting-region"));
1856+
}
18151857
BlockVector3 to = region.getMinimumPoint();
18161858
ForwardExtentCopy copy = new ForwardExtentCopy(this, region, this, to);
18171859
copy.setRepetitions(count);
1818-
copy.setTransform(new AffineTransform().translate(offset.multiply(size)));
1860+
copy.setTransform(new AffineTransform().translate(offset));
18191861
copy.setCopyingEntities(copyEntities);
18201862
copy.setCopyingBiomes(copyBiomes);
18211863
final Region allowedRegion;

worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ public int move(
594594
session.getRegionSelector(world).learnChanges();
595595
session.getRegionSelector(world).explainRegionAdjust(actor, session);
596596
} catch (RegionOperationException e) {
597-
actor.printError(TextComponent.of(e.getMessage()));
597+
actor.printError(e.getRichMessage());
598598
}
599599
}
600600

@@ -640,7 +640,7 @@ public int stack(
640640
int count,
641641
@Arg(desc = "How far to move the contents each stack", def = Offset.FORWARD)
642642
@Offset
643-
BlockVector3 direction,
643+
BlockVector3 offset,
644644
@Switch(name = 's', desc = "Shift the selection to the last stacked copy")
645645
boolean moveSelection,
646646
@Switch(name = 'a', desc = "Ignore air blocks")
@@ -649,6 +649,8 @@ public int stack(
649649
boolean copyEntities,
650650
@Switch(name = 'b', desc = "Also copy biomes")
651651
boolean copyBiomes,
652+
@Switch(name = 'r', desc = "Use block units")
653+
boolean blockUnits,
652654
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air")
653655
Mask mask
654656
) throws WorldEditException {
@@ -668,19 +670,24 @@ public int stack(
668670
combinedMask = mask;
669671
}
670672

671-
int affected = editSession.stackCuboidRegion(region, direction, count, copyEntities, copyBiomes, combinedMask);
673+
int affected;
674+
if (blockUnits) {
675+
affected = editSession.stackRegionBlockUnits(region, offset, count, copyEntities, copyBiomes, combinedMask);
676+
} else {
677+
affected = editSession.stackCuboidRegion(region, offset, count, copyEntities, copyBiomes, combinedMask);
678+
}
672679

673680
if (moveSelection) {
674681
try {
675682
final BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
676-
677-
final BlockVector3 shiftVector = direction.multiply(size).multiply(count);
683+
final BlockVector3 shiftSize = blockUnits ? offset : offset.multiply(size);
684+
final BlockVector3 shiftVector = shiftSize.multiply(count);
678685
region.shift(shiftVector);
679686

680687
session.getRegionSelector(world).learnChanges();
681688
session.getRegionSelector(world).explainRegionAdjust(actor, session);
682689
} catch (RegionOperationException e) {
683-
actor.printError(TextComponent.of(e.getMessage()));
690+
actor.printError(e.getRichMessage());
684691
}
685692
}
686693

worldedit-core/src/main/resources/lang/strings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@
478478
"worldedit.curve.convex-only": "//curve only works with convex polyhedral selections",
479479
"worldedit.replace.replaced": "{0} blocks have been replaced.",
480480
"worldedit.stack.changed": "{0} blocks changed. Undo with //undo",
481+
"worldedit.stack.intersecting-region": "Stack offset must not collide with the region when using block units",
481482
"worldedit.regen.regenerated": "Region regenerated.",
482483
"worldedit.regen.failed": "Unable to regenerate chunks. Check console for details.",
483484
"worldedit.walls.changed": "{0} blocks have been changed.",

0 commit comments

Comments
 (0)