Skip to content

Commit

Permalink
Allow stacking by block units with //stack (#1539)
Browse files Browse the repository at this point in the history
 - closes #2968
  • Loading branch information
me4502 authored and dordsor21 committed Nov 1, 2024
1 parent d959778 commit e957349
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
48 changes: 45 additions & 3 deletions worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionIntersection;
import com.sk89q.worldedit.regions.RegionOperationException;
import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape;
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
Expand Down Expand Up @@ -1804,18 +1805,59 @@ public int stackCuboidRegion(Region region, BlockVector3 dir, int count, boolean
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int stackCuboidRegion(
Region region, BlockVector3 offset, int count,
boolean copyEntities, boolean copyBiomes, Mask mask
Region region,
BlockVector3 offset,
int count,
boolean copyEntities,
boolean copyBiomes,
Mask mask
) throws MaxChangedBlocksException {
checkNotNull(region);
checkNotNull(offset);

BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
try {
return stackRegionBlockUnits(region, offset.multiply(size), count, copyEntities, copyBiomes, mask);
} catch (RegionOperationException e) {
// Should never be able to happen
throw new AssertionError(e);
}
}

/**
* Stack a region using block units.
*
* @param region the region to stack
* @param offset how far to move the contents each stack in block units
* @param count the number of times to stack
* @param copyEntities true to copy entities
* @param copyBiomes true to copy biomes
* @param mask source mask for the operation (only matching blocks are copied)
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
* @throws RegionOperationException thrown if the region operation is invalid
*/
public int stackRegionBlockUnits(
Region region,
BlockVector3 offset,
int count,
boolean copyEntities,
boolean copyBiomes,
Mask mask
) throws MaxChangedBlocksException, RegionOperationException {
checkNotNull(region);
checkNotNull(offset);
checkArgument(count >= 1, "count >= 1 required");

BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
BlockVector3 offsetAbs = offset.abs();
if (offsetAbs.x() < size.x() && offsetAbs.y() < size.y() && offsetAbs.z() < size.z()) {
throw new RegionOperationException(Caption.of("worldedit.stack.intersecting-region"));
}
BlockVector3 to = region.getMinimumPoint();
ForwardExtentCopy copy = new ForwardExtentCopy(this, region, this, to);
copy.setRepetitions(count);
copy.setTransform(new AffineTransform().translate(offset.multiply(size)));
copy.setTransform(new AffineTransform().translate(offset));
copy.setCopyingEntities(copyEntities);
copy.setCopyingBiomes(copyBiomes);
final Region allowedRegion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ public int move(
session.getRegionSelector(world).learnChanges();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
} catch (RegionOperationException e) {
actor.printError(TextComponent.of(e.getMessage()));
actor.printError(e.getRichMessage());
}
}

Expand Down Expand Up @@ -640,7 +640,7 @@ public int stack(
int count,
@Arg(desc = "How far to move the contents each stack", def = Offset.FORWARD)
@Offset
BlockVector3 direction,
BlockVector3 offset,
@Switch(name = 's', desc = "Shift the selection to the last stacked copy")
boolean moveSelection,
@Switch(name = 'a', desc = "Ignore air blocks")
Expand All @@ -649,6 +649,8 @@ public int stack(
boolean copyEntities,
@Switch(name = 'b', desc = "Also copy biomes")
boolean copyBiomes,
@Switch(name = 'r', desc = "Use block units")
boolean blockUnits,
@ArgFlag(name = 'm', desc = "Set the include mask, non-matching blocks become air")
Mask mask
) throws WorldEditException {
Expand All @@ -668,19 +670,24 @@ public int stack(
combinedMask = mask;
}

int affected = editSession.stackCuboidRegion(region, direction, count, copyEntities, copyBiomes, combinedMask);
int affected;
if (blockUnits) {
affected = editSession.stackRegionBlockUnits(region, offset, count, copyEntities, copyBiomes, combinedMask);
} else {
affected = editSession.stackCuboidRegion(region, offset, count, copyEntities, copyBiomes, combinedMask);
}

if (moveSelection) {
try {
final BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);

final BlockVector3 shiftVector = direction.multiply(size).multiply(count);
final BlockVector3 shiftSize = blockUnits ? offset : offset.multiply(size);
final BlockVector3 shiftVector = shiftSize.multiply(count);
region.shift(shiftVector);

session.getRegionSelector(world).learnChanges();
session.getRegionSelector(world).explainRegionAdjust(actor, session);
} catch (RegionOperationException e) {
actor.printError(TextComponent.of(e.getMessage()));
actor.printError(e.getRichMessage());
}
}

Expand Down
1 change: 1 addition & 0 deletions worldedit-core/src/main/resources/lang/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@
"worldedit.curve.convex-only": "//curve only works with convex polyhedral selections",
"worldedit.replace.replaced": "{0} blocks have been replaced.",
"worldedit.stack.changed": "{0} blocks changed. Undo with //undo",
"worldedit.stack.intersecting-region": "Stack offset must not collide with the region when using block units",
"worldedit.regen.regenerated": "Region regenerated.",
"worldedit.regen.failed": "Unable to regenerate chunks. Check console for details.",
"worldedit.walls.changed": "{0} blocks have been changed.",
Expand Down

0 comments on commit e957349

Please sign in to comment.