Set source masks that include the editsession's allowed regions to ForwardExtentCopies

Fixes #710
This commit is contained in:
dordsor21 2021-01-10 14:59:21 +00:00
parent edc7e9028b
commit 278e9d5991
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
5 changed files with 75 additions and 18 deletions

View File

@ -457,4 +457,8 @@ public class EditSessionBuilder {
return wnaMode; return wnaMode;
} }
public Region[] getAllowedRegions() {
return allowedRegions;
}
} }

View File

@ -109,7 +109,9 @@ import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.CylinderRegion;
import com.sk89q.worldedit.regions.EllipsoidRegion; import com.sk89q.worldedit.regions.EllipsoidRegion;
import com.sk89q.worldedit.regions.FlatRegion; import com.sk89q.worldedit.regions.FlatRegion;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionIntersection;
import com.sk89q.worldedit.regions.Regions; import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape; import com.sk89q.worldedit.regions.shape.ArbitraryBiomeShape;
import com.sk89q.worldedit.regions.shape.ArbitraryShape; import com.sk89q.worldedit.regions.shape.ArbitraryShape;
@ -224,6 +226,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
private final boolean wnaMode; private final boolean wnaMode;
@Nullable
private final Region[] allowedRegions;
@Deprecated @Deprecated
public EditSession(@NotNull EventBus bus, World world, @Nullable Player player, public EditSession(@NotNull EventBus bus, World world, @Nullable Player player,
@ -260,6 +265,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
this.blockBag = builder.getBlockBag(); this.blockBag = builder.getBlockBag();
this.history = changeSet != null; this.history = changeSet != null;
this.wnaMode = builder.isWNAMode(); this.wnaMode = builder.isWNAMode();
this.allowedRegions = builder.getAllowedRegions().clone();
} }
/** /**
@ -307,8 +313,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
} }
/** /**
* The region extent restricts block placements to allow max Y regions. * Returns the RegionExtent that will restrict an edit, or null.
* TODO This doc needs to be rewritten because it may not actually describe what it does.
* *
* @return FaweRegionExtent (may be null) * @return FaweRegionExtent (may be null)
*/ */
@ -483,6 +488,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return maskingExtent != null ? maskingExtent.get().getMask() : null; return maskingExtent != null ? maskingExtent.get().getMask() : null;
} }
@Nullable
public Region[] getAllowedRegions() {
return allowedRegions;
}
public void addTransform(ResettableExtent transform) { public void addTransform(ResettableExtent transform) {
checkNotNull(transform); checkNotNull(transform);
transform.setExtent(getExtent()); transform.setExtent(getExtent());
@ -1530,7 +1540,13 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
copy.setTransform(new AffineTransform().translate(dir.multiply(size))); copy.setTransform(new AffineTransform().translate(dir.multiply(size)));
copy.setCopyingEntities(copyEntities); copy.setCopyingEntities(copyEntities);
copy.setCopyingBiomes(copyBiomes); copy.setCopyingBiomes(copyBiomes);
mask = MaskIntersection.of(getSourceMask(), mask).optimize(); final Region allowedRegion;
if (allowedRegions == null || allowedRegions.length == 0) {
allowedRegion = new NullRegion();
} else {
allowedRegion = new RegionIntersection(allowedRegions);
}
mask = MaskIntersection.of(getSourceMask(), mask, new RegionMask(allowedRegion)).optimize();
if (mask != Masks.alwaysTrue()) { if (mask != Masks.alwaysTrue()) {
setSourceMask(null); setSourceMask(null);
copy.setSourceMask(mask); copy.setSourceMask(mask);
@ -1605,14 +1621,19 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
copy.setRemovingEntities(moveEntities); copy.setRemovingEntities(moveEntities);
copy.setCopyingBiomes(copyBiomes); copy.setCopyingBiomes(copyBiomes);
copy.setRepetitions(1); copy.setRepetitions(1);
if (mask != null) { final Region allowedRegion;
new MaskTraverser(mask).reset(this); if (allowedRegions == null || allowedRegions.length == 0) {
allowedRegion = new NullRegion();
} else {
allowedRegion = new RegionIntersection(allowedRegions);
}
mask = MaskIntersection.of(getSourceMask(), mask, new RegionMask(allowedRegion)).optimize();
if (mask != Masks.alwaysTrue()) {
copy.setSourceMask(mask); copy.setSourceMask(mask);
if (this.getSourceMask() == mask) { if (this.getSourceMask().equals(mask)) {
setSourceMask(null); setSourceMask(null);
} }
} }
Operations.completeBlindly(copy); Operations.completeBlindly(copy);
return this.changes = copy.getAffected(); return this.changes = copy.getAffected();
} }

View File

@ -55,6 +55,9 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.BlockReplace;
import com.sk89q.worldedit.function.mask.Mask; 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.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.operation.Operations;
@ -66,7 +69,9 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.NullRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.RegionIntersection;
import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.session.ClipboardHolder;
@ -140,14 +145,24 @@ public class ClipboardCommands {
copy.setCopyingBiomes(copyBiomes); copy.setCopyingBiomes(copyBiomes);
Mask sourceMask = editSession.getSourceMask(); Mask sourceMask = editSession.getSourceMask();
Region[] regions = editSession.getAllowedRegions();
Region allowedRegion;
if (regions == null || regions.length == 0) {
allowedRegion = new NullRegion();
} else {
allowedRegion = new RegionIntersection(regions);
}
final Mask firstSourceMask = mask != null ? mask : sourceMask;
final Mask finalMask = MaskIntersection.of(firstSourceMask, new RegionMask(allowedRegion)).optimize();
if (finalMask != Masks.alwaysTrue()) {
copy.setSourceMask(finalMask);
}
if (sourceMask != null) { if (sourceMask != null) {
editSession.setSourceMask(null);
new MaskTraverser(sourceMask).reset(editSession); new MaskTraverser(sourceMask).reset(editSession);
copy.setSourceMask(sourceMask);
editSession.setSourceMask(null); editSession.setSourceMask(null);
} }
if (mask != null) {
copy.setSourceMask(mask);
}
Operations.completeLegacy(copy); Operations.completeLegacy(copy);
saveDiskClipboard(clipboard); saveDiskClipboard(clipboard);
session.setClipboard(new ClipboardHolder(clipboard)); session.setClipboard(new ClipboardHolder(clipboard));
@ -252,13 +267,22 @@ public class ClipboardCommands {
copy.setRemovingEntities(true); copy.setRemovingEntities(true);
copy.setCopyingBiomes(copyBiomes); copy.setCopyingBiomes(copyBiomes);
Mask sourceMask = editSession.getSourceMask(); Mask sourceMask = editSession.getSourceMask();
if (sourceMask != null) { Region[] regions = editSession.getAllowedRegions();
new MaskTraverser(sourceMask).reset(editSession); Region allowedRegion;
copy.setSourceMask(sourceMask); if (regions == null || regions.length == 0) {
editSession.setSourceMask(null); allowedRegion = new NullRegion();
} else {
allowedRegion = new RegionIntersection(regions);
} }
if (mask != null) { final Mask firstSourceMask = mask != null ? mask : sourceMask;
copy.setSourceMask(mask); final Mask finalMask = MaskIntersection.of(firstSourceMask, new RegionMask(allowedRegion)).optimize();
if (finalMask != Masks.alwaysTrue()) {
copy.setSourceMask(finalMask);
}
if (sourceMask != null) {
editSession.setSourceMask(null);
new MaskTraverser(sourceMask).reset(editSession);
editSession.setSourceMask(null);
} }
Operations.completeLegacy(copy); Operations.completeLegacy(copy);
saveDiskClipboard(clipboard); saveDiskClipboard(clipboard);

View File

@ -81,7 +81,7 @@ public class MaskIntersection extends AbstractMask {
case 1: case 1:
return set.iterator().next(); return set.iterator().next();
default: default:
return new MaskIntersection(masks).optimize(); return new MaskIntersection(set).optimize();
} }
} }

View File

@ -77,4 +77,12 @@ public class RegionMask extends AbstractMask {
return new RegionMask(region.clone()); return new RegionMask(region.clone());
} }
@Override
public Mask optimize() {
if (region.isGlobal()) {
return Masks.alwaysTrue();
}
return this;
}
} }