Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow stacking by block units with //stack (#1539) #2973

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
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 @@ -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
Loading