Copy paste/merge FAWE classes to this WorldEdit fork

- so certain people can look at the diff and complain about my sloppy code :(

Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
This commit is contained in:
Jesse Boyd
2018-08-13 00:03:07 +10:00
parent a920c77cb8
commit a629d15c74
994 changed files with 117583 additions and 10745 deletions

View File

@ -0,0 +1,82 @@
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import java.util.List;
public class BackwardsExtentBlockCopy implements Operation {
private final Region region;
private final Transform transform;
private final Extent destination;
private final Extent source;
private final RegionFunction function;
private final Vector origin;
private Vector mutable = new MutableBlockVector();
public BackwardsExtentBlockCopy(Extent source, Region region, Extent destination, Vector origin, Transform transform, RegionFunction function) {
this.source = source;
this.region = region;
this.destination = destination;
this.transform = transform;
this.function = function;
this.origin = origin;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
CuboidRegion destRegion = transform(this.transform, this.region);
Transform inverse = this.transform.inverse();
for (Vector pt : destRegion) {
Vector copyFrom = transform(inverse, pt);
if (region.contains(copyFrom)) {
function.apply(pt);
}
}
return null;
}
private CuboidRegion transform(Transform transform, Region region) {
Vector min = new MutableBlockVector(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
Vector max = new MutableBlockVector(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
Vector pos1 = region.getMinimumPoint();
Vector pos2 = region.getMaximumPoint();
for (int x : new int[] { pos1.getBlockX(), pos2.getBlockX() }) {
for (int y : new int[] { pos1.getBlockY(), pos2.getBlockY() }) {
for (int z : new int[] { pos1.getBlockZ(), pos2.getBlockZ() }) {
Vector pt = transform(transform, new Vector(x, y, z)).toBlockVector();
min = Vector.getMinimum(min, pt);
max = Vector.getMaximum(max, pt);
}
}
}
return new CuboidRegion(min, max);
}
private Vector transform(Transform transform, Vector pt) {
mutable.mutX(((pt.getBlockX() - origin.getBlockX())));
mutable.mutY(((pt.getBlockY() - origin.getBlockY())));
mutable.mutZ(((pt.getBlockZ() - origin.getBlockZ())));
Vector tmp = transform.apply(mutable);
tmp.mutX((tmp.getBlockX() + origin.getBlockX()));
tmp.mutY((tmp.getBlockY() + origin.getBlockY()));
tmp.mutZ((tmp.getBlockZ() + origin.getBlockZ()));
return tmp;
}
@Override
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
}

View File

@ -19,18 +19,20 @@
package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.extent.Extent;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Sets block from an iterator of {@link Map.Entry} containing a
* {@link BlockVector} as the key and a {@link BaseBlock} as the value.

View File

@ -19,16 +19,18 @@
package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.object.changeset.FaweChangeSet;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.history.UndoContext;
import com.sk89q.worldedit.history.change.Change;
import com.sk89q.worldedit.history.changeset.ChangeSet;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Performs an undo or redo from a given {@link ChangeSet}.
*/
@ -44,18 +46,18 @@ public class ChangeSetExecutor implements Operation {
* Create a new instance.
*
* @param changeSet the change set
* @param type type of change
* @param context the undo context
* @param type type of change
* @param context the undo context
*/
private ChangeSetExecutor(ChangeSet changeSet, Type type, UndoContext context) {
private ChangeSetExecutor(ChangeSet changeSet, Type type, UndoContext context, BlockBag blockBag, int inventory) {
checkNotNull(changeSet);
checkNotNull(type);
checkNotNull(context);
this.type = type;
this.context = context;
if (type == Type.UNDO) {
if (changeSet instanceof FaweChangeSet) {
iterator = ((FaweChangeSet) changeSet).getIterator(blockBag, inventory, type == Type.REDO);
} else if (type == Type.UNDO) {
iterator = changeSet.backwardIterator();
} else {
iterator = changeSet.forwardIterator();
@ -64,15 +66,15 @@ public class ChangeSetExecutor implements Operation {
@Override
public Operation resume(RunContext run) throws WorldEditException {
while (iterator.hasNext()) {
Change change = iterator.next();
if (type == Type.UNDO) {
change.undo(context);
} else {
change.redo(context);
if (type == Type.UNDO) {
while (iterator.hasNext()) {
iterator.next().undo(context);
}
} else {
while (iterator.hasNext()) {
iterator.next().redo(context);
}
}
return null;
}
@ -84,26 +86,35 @@ public class ChangeSetExecutor implements Operation {
public void addStatusMessages(List<String> messages) {
}
public static ChangeSetExecutor create(ChangeSet changeSet, UndoContext context, Type type, BlockBag blockBag, int inventory) {
return new ChangeSetExecutor(changeSet, type, context, blockBag, inventory);
}
/**
* Create a new undo operation.
*
* @param changeSet the change set
* @param context an undo context
* @param context an undo context
* @return an operation
*/
@Deprecated
public static ChangeSetExecutor createUndo(ChangeSet changeSet, UndoContext context) {
return new ChangeSetExecutor(changeSet, Type.UNDO, context);
return new ChangeSetExecutor(changeSet, Type.UNDO, context, null, 0);
}
/**
* Create a new redo operation.
*
* @param changeSet the change set
* @param context an undo context
* @param context an undo context
* @return an operation
*/
@Deprecated
public static ChangeSetExecutor createRedo(ChangeSet changeSet, UndoContext context) {
return new ChangeSetExecutor(changeSet, Type.REDO, context);
return new ChangeSetExecutor(changeSet, Type.REDO, context, null, 0);
}
public static Class<?> inject() {
return ChangeSetExecutor.class;
}
}

View File

@ -19,12 +19,12 @@
package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEditException;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Executes a delegete operation, but returns to another operation upon
* completing the delegate.

View File

@ -19,33 +19,45 @@
package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Lists;
import com.boydti.fawe.example.MappedFaweQueue;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.extent.BlockTranslateExtent;
import com.boydti.fawe.object.extent.PositionTransformExtent;
import com.boydti.fawe.object.function.block.BiomeCopy;
import com.boydti.fawe.object.function.block.CombinedBlockCopy;
import com.boydti.fawe.object.function.block.SimpleBlockCopy;
import com.boydti.fawe.util.MaskTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MutableBlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.function.CombinedRegionFunction;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.RegionMaskTestFunction;
import com.sk89q.worldedit.function.RegionMaskingFilter;
import com.sk89q.worldedit.function.block.ExtentBlockCopy;
import com.sk89q.worldedit.function.entity.ExtentEntityCopy;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.visitor.EntityVisitor;
import com.sk89q.worldedit.function.visitor.IntersectRegionFunction;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Identity;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.Region;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Makes a copy of a portion of one extent to another extent or another point.
*
* <p>
* <p>This is a forward extent copy, meaning that it iterates over the blocks
* in the source extent, and will copy as many blocks as there are in the
* source. Therefore, interpolation will not occur to fill in the gaps.</p>
@ -60,21 +72,22 @@ public class ForwardExtentCopy implements Operation {
private int repetitions = 1;
private Mask sourceMask = Masks.alwaysTrue();
private boolean removingEntities;
private boolean copyingEntities = true; // default to true for backwards compatibility, sort of
private RegionFunction sourceFunction = null;
private Transform transform = new Identity();
private Transform currentTransform = null;
private RegionVisitor lastVisitor;
private int affected;
private boolean copyEntities = true;
private boolean copyBiomes = false;
private RegionFunction filterFunction;
/**
* Create a new copy using the region's lowest minimum point as the
* "from" position.
*
* @param source the source extent
* @param region the region to copy
* @param source the source extent
* @param region the region to copy
* @param destination the destination extent
* @param to the destination position
* @param to the destination position
* @see #ForwardExtentCopy(Extent, Region, Vector, Extent, Vector) the main constructor
*/
public ForwardExtentCopy(Extent source, Region region, Extent destination, Vector to) {
@ -84,11 +97,11 @@ public class ForwardExtentCopy implements Operation {
/**
* Create a new copy.
*
* @param source the source extent
* @param region the region to copy
* @param from the source position
* @param source the source extent
* @param region the region to copy
* @param from the source position
* @param destination the destination extent
* @param to the destination position
* @param to the destination position
*/
public ForwardExtentCopy(Extent source, Region region, Vector from, Extent destination, Vector to) {
checkNotNull(source);
@ -105,7 +118,7 @@ public class ForwardExtentCopy implements Operation {
/**
* Get the transformation that will occur on every point.
*
* <p>
* <p>The transformation will stack with each repetition.</p>
*
* @return a transformation
@ -127,7 +140,7 @@ public class ForwardExtentCopy implements Operation {
/**
* Get the mask that gets applied to the source extent.
*
* <p>
* <p>This mask can be used to filter what will be copied from the source.</p>
*
* @return a source mask
@ -136,6 +149,22 @@ public class ForwardExtentCopy implements Operation {
return sourceMask;
}
public void setCopyEntities(boolean copyEntities) {
this.copyEntities = copyEntities;
}
public boolean isCopyEntities() {
return copyEntities;
}
public void setCopyBiomes(boolean copyBiomes) {
this.copyBiomes = copyBiomes;
}
public boolean isCopyBiomes() {
return copyBiomes;
}
/**
* Set a mask that gets applied to the source extent.
*
@ -147,6 +176,10 @@ public class ForwardExtentCopy implements Operation {
this.sourceMask = sourceMask;
}
public void setFilterFunction(RegionFunction filterFunction) {
this.filterFunction = filterFunction;
}
/**
* Get the function that gets applied to all source blocks <em>after</em>
* the copy has been made.
@ -163,6 +196,7 @@ public class ForwardExtentCopy implements Operation {
*
* @param function a source function, or null if none is to be applied
*/
@Deprecated
public void setSourceFunction(RegionFunction function) {
this.sourceFunction = function;
}
@ -186,24 +220,6 @@ public class ForwardExtentCopy implements Operation {
this.repetitions = repetitions;
}
/**
* Return whether entities should be copied along with blocks.
*
* @return true if copying
*/
public boolean isCopyingEntities() {
return copyingEntities;
}
/**
* Set whether entities should be copied along with blocks.
*
* @param copyingEntities true if copying
*/
public void setCopyingEntities(boolean copyingEntities) {
this.copyingEntities = copyingEntities;
}
/**
* Return whether entities that are copied should be removed.
*
@ -233,43 +249,124 @@ public class ForwardExtentCopy implements Operation {
@Override
public Operation resume(RunContext run) throws WorldEditException {
if (lastVisitor != null) {
affected += lastVisitor.getAffected();
lastVisitor = null;
if (currentTransform == null) {
currentTransform = transform;
}
FaweQueue queue;
if (source instanceof EditSession) {
queue = ((EditSession) source).getQueue();
} else if (destination instanceof EditSession) {
queue = ((EditSession) destination).getQueue();
} else {
queue = null;
}
if (repetitions > 0) {
repetitions--;
Extent finalDest = destination;
Vector translation = to.subtract(from);
if (currentTransform == null) {
currentTransform = transform;
if (!translation.equals(Vector.ZERO)) {
finalDest = new BlockTranslateExtent(finalDest, translation.getBlockX(), translation.getBlockY(), translation.getBlockZ());
}
RegionFunction copy;
Operation blockCopy = null;
PositionTransformExtent transExt = null;
if (!currentTransform.isIdentity()) {
if (!(currentTransform instanceof AffineTransform) || ((AffineTransform) currentTransform).isOffAxis()) {
transExt = new PositionTransformExtent(source, currentTransform.inverse());
transExt.setOrigin(from);
copy = new SimpleBlockCopy(transExt, finalDest);
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 (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) {
copy = CombinedRegionFunction.combine(copy, new BiomeCopy(source, finalDest));
}
blockCopy = new BackwardsExtentBlockCopy(transExt, region, finalDest, from, transform, copy);
} else {
currentTransform = currentTransform.combine(transform);
transExt = new PositionTransformExtent(finalDest, currentTransform);
transExt.setOrigin(from);
finalDest = transExt;
}
}
ExtentBlockCopy blockCopy = new ExtentBlockCopy(source, from, destination, to, currentTransform);
RegionMaskingFilter filter = new RegionMaskingFilter(sourceMask, blockCopy);
RegionFunction function = sourceFunction != null ? new CombinedRegionFunction(filter, sourceFunction) : filter;
RegionVisitor blockVisitor = new RegionVisitor(region, function);
if (blockCopy == null) {
RegionFunction maskFunc = null;
lastVisitor = blockVisitor;
if (sourceFunction != null) {
Vector disAbs = translation.positive();
Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
boolean overlap = (disAbs.getBlockX() < size.getBlockX() && disAbs.getBlockY() < size.getBlockY() && disAbs.getBlockZ() < size.getBlockZ());
if (copyingEntities) {
RegionFunction copySrcFunc = sourceFunction;
if (overlap && translation.length() != 0) {
MutableBlockVector mutable = new MutableBlockVector();
int x = translation.getBlockX();
int y = translation.getBlockY();
int z = translation.getBlockZ();
maskFunc = position -> {
mutable.setComponents(position.getBlockX() + x, position.getBlockY() + y, position.getBlockZ() + z);
if (region.contains(mutable)) {
return sourceFunction.apply(mutable);
}
return false;
};
copySrcFunc = position -> {
mutable.setComponents(position.getBlockX() - x, position.getBlockY() - y, position.getBlockZ() - z);
if (!region.contains(mutable)) {
return sourceFunction.apply(position);
}
return false;
};
}
copy = new CombinedBlockCopy(source, finalDest, copySrcFunc);
}
else {
copy = new SimpleBlockCopy(source, finalDest);
}
if (this.filterFunction != null) {
copy = new IntersectRegionFunction(filterFunction, copy);
}
if (sourceMask != Masks.alwaysTrue()) {
if (maskFunc != null) copy = new RegionMaskTestFunction(sourceMask, copy, maskFunc);
else copy = new RegionMaskingFilter(sourceMask, copy);
}
if (copyBiomes && (!(source instanceof BlockArrayClipboard) || ((BlockArrayClipboard) source).IMP.hasBiomes())) {
copy = CombinedRegionFunction.combine(copy, new BiomeCopy(source, finalDest));
}
blockCopy = new RegionVisitor(region, copy, queue instanceof MappedFaweQueue ? (MappedFaweQueue) queue : null);
}
List<? extends Entity> entities = isCopyEntities() ? source.getEntities(region) : new ArrayList<>();
for (int i = 0; i < repetitions; i++) {
Operations.completeBlindly(blockCopy);
if (!entities.isEmpty()) {
ExtentEntityCopy entityCopy = new ExtentEntityCopy(from, destination, to, currentTransform);
entityCopy.setRemoving(removingEntities);
List<? extends Entity> entities = Lists.newArrayList(source.getEntities(region));
entities.removeIf(entity -> {
EntityProperties properties = entity.getFacet(EntityProperties.class);
return properties != null && !properties.isPasteable();
});
EntityVisitor entityVisitor = new EntityVisitor(entities.iterator(), entityCopy);
return new DelegateOperation(this, new OperationQueue(blockVisitor, entityVisitor));
} else {
return new DelegateOperation(this, blockVisitor);
Operations.completeBlindly(entityVisitor);
}
} else {
return null;
if (transExt != null) {
currentTransform = currentTransform.combine(transform);
transExt.setTransform(currentTransform);
}
}
affected = region.getArea();
return null;
}
@Override
@ -280,4 +377,7 @@ public class ForwardExtentCopy implements Operation {
public void addStatusMessages(List<String> messages) {
}
public static Class<?> inject() {
return ForwardExtentCopy.class;
}
}

View File

@ -19,8 +19,6 @@
package com.sk89q.worldedit.function.operation;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.WorldEditException;
@ -29,6 +27,8 @@ import java.util.Collection;
import java.util.Deque;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Executes multiple queues in order.
*/

View File

@ -30,15 +30,17 @@ public final class Operations {
private Operations() {
}
private static RunContext context = new RunContext();
/**
* Complete a given operation synchronously until it completes.
*
* @param op operation to execute
* @param operation operation to execute
* @throws WorldEditException WorldEdit exception
*/
public static void complete(Operation op) throws WorldEditException {
while (op != null) {
op = op.resume(new RunContext());
public static void complete(Operation operation) throws WorldEditException {
while (operation != null) {
operation = operation.resume(context);
}
}
@ -46,19 +48,11 @@ public final class Operations {
* Complete a given operation synchronously until it completes. Catch all
* errors that is not {@link MaxChangedBlocksException} for legacy reasons.
*
* @param op operation to execute
* @param operation operation to execute
* @throws MaxChangedBlocksException thrown when too many blocks have been changed
*/
public static void completeLegacy(Operation op) throws MaxChangedBlocksException {
while (op != null) {
try {
op = op.resume(new RunContext());
} catch (MaxChangedBlocksException e) {
throw e;
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
public static void completeLegacy(Operation operation) throws MaxChangedBlocksException {
completeBlindly(operation);
}
/**
@ -66,16 +60,27 @@ public final class Operations {
* {@link com.sk89q.worldedit.WorldEditException} exceptions as
* {@link java.lang.RuntimeException}s.
*
* @param op operation to execute
* @param operation operation to execute
*/
public static void completeBlindly(Operation op) {
while (op != null) {
try {
op = op.resume(new RunContext());
} catch (WorldEditException e) {
throw new RuntimeException(e);
public static void completeBlindly(Operation operation) {
try {
while (operation != null) {
operation = operation.resume(context);
}
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
public static void completeSmart(final Operation op, final Runnable whenDone, final boolean threadsafe) {
completeBlindly(op);
if (whenDone != null) {
whenDone.run();
}
return;
}
public static Class<?> inject() {
return Operations.class;
}
}