From 8c29292badc462b752422ca066eeae9b0659a007 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 15 Mar 2018 00:54:47 +1100 Subject: [PATCH] Fix `//move -a` with overlapping regions --- core/src/main/java/com/boydti/fawe/Fawe.java | 2 + .../java/com/sk89q/worldedit/EditSession.java | 3 +- .../function/CombinedRegionFunction.java | 109 ++++++++++++++++++ .../function/operation/ForwardExtentCopy.java | 12 +- 4 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 13beece8..99e17ad6 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -37,6 +37,7 @@ import com.sk89q.worldedit.extent.clipboard.io.SchematicReader; import com.sk89q.worldedit.extent.clipboard.io.SchematicWriter; import com.sk89q.worldedit.extent.inventory.BlockBagExtent; import com.sk89q.worldedit.extent.transform.BlockTransformExtent; +import com.sk89q.worldedit.function.CombinedRegionFunction; import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.ExtentBlockCopy; import com.sk89q.worldedit.function.entity.ExtentEntityCopy; @@ -568,6 +569,7 @@ public class Fawe { ExtentBlockCopy.inject(); // Optimizations BlockReplace.inject(); // Optimizations + Features ForwardExtentCopy.inject(); // Fixes + optimizations + CombinedRegionFunction.inject(); // Optimizations ChangeSetExecutor.inject(); // Optimizations // Expression ExpressionEnvironment.inject(); // Optimizations + features diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index d3dc6b0e..520528c0 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2005,7 +2005,8 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, mutable.mutX((position.getX() - displace.getX())); mutable.mutY((position.getY() - displace.getY())); mutable.mutZ((position.getZ() - displace.getZ())); - if (region.contains(mutable)) { + + if (copyAir && region.contains(mutable)) { return false; } return super.apply(position); diff --git a/core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java b/core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java new file mode 100644 index 00000000..1c456af6 --- /dev/null +++ b/core/src/main/java/com/sk89q/worldedit/function/CombinedRegionFunction.java @@ -0,0 +1,109 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.function; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEditException; + +import java.util.*; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Executes several region functions in order. + */ +public class CombinedRegionFunction implements RegionFunction { + + private RegionFunction[] functions; + + /** + * Create a combined region function. + */ + public CombinedRegionFunction() { + } + + /** + * Create a combined region function. + * + * @param functions a list of functions to match + */ + public CombinedRegionFunction(Collection functions) { + checkNotNull(functions); + this.functions = functions.toArray(new RegionFunction[functions.size()]); + + } + + /** + * Create a combined region function. + * + * @param function an array of functions to match + */ + public CombinedRegionFunction(RegionFunction... function) { + this.functions = function; + } + + public static CombinedRegionFunction combine(RegionFunction function, RegionFunction add) { + CombinedRegionFunction combined; + if (function instanceof CombinedRegionFunction) { + combined = ((CombinedRegionFunction) function); + combined.add(add); + } else { + combined = new CombinedRegionFunction(function, add); + } + return combined; + } + + /** + * Add the given functions to the list of functions to call. + * + * @param functions a list of functions + */ + public void add(Collection functions) { + checkNotNull(functions); + ArrayList functionsList = new ArrayList<>(Arrays.asList(this.functions)); + functionsList.addAll(functions); + this.functions = functionsList.toArray(new RegionFunction[functionsList.size()]); + } + + /** + * Add the given functions to the list of functions to call. + * + * @param function an array of functions + */ + public void add(RegionFunction... function) { + add(Arrays.asList(checkNotNull(function))); + } + + @Override + public boolean apply(Vector position) throws WorldEditException { + boolean ret = false; + for (RegionFunction function : functions) { + if (function.apply(position)) { + ret = true; + } + } + return ret; + } + + + public static Class inject() { + return CombinedRegionFunction.class; + } +} diff --git a/core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java index 02560d84..61218008 100644 --- a/core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java +++ b/core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java @@ -275,15 +275,15 @@ public class ForwardExtentCopy implements Operation { if (this.filterFunction != null) { copy = new IntersectRegionFunction(filterFunction, copy); } + if (sourceFunction != null) { + copy = CombinedRegionFunction.combine(copy, sourceFunction); + } if (sourceMask != Masks.alwaysTrue()) { new MaskTraverser(sourceMask).reset(transExt); copy = new RegionMaskingFilter(sourceMask, copy); } - if (sourceFunction != null) { - copy = new CombinedRegionFunction(copy, sourceFunction); - } if (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) { - copy = new CombinedRegionFunction(copy, new BiomeCopy(source, finalDest)); + copy = CombinedRegionFunction.combine(copy, new BiomeCopy(source, finalDest)); } blockCopy = new BackwardsExtentBlockCopy(transExt, region, finalDest, from, transform, copy); } else { @@ -302,10 +302,10 @@ public class ForwardExtentCopy implements Operation { copy = new RegionMaskingFilter(sourceMask, copy); } if (sourceFunction != null) { - copy = new CombinedRegionFunction(copy, sourceFunction); + copy = CombinedRegionFunction.combine(copy, sourceFunction); } if (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) { - copy = new CombinedRegionFunction(copy, new BiomeCopy(source, finalDest)); + copy = CombinedRegionFunction.combine(copy, new BiomeCopy(source, finalDest)); } blockCopy = new RegionVisitor(region, copy, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null); }