diff --git a/build.gradle b/build.gradle index a3870aace..0a8de63fe 100644 --- a/build.gradle +++ b/build.gradle @@ -38,23 +38,26 @@ println """ ******************************************* """ -group = 'com.boydti.fawe' +allprojects { + group = 'com.boydti.fawe' -def rootVersion = "1.14" -def revision = "" -def buildNumber = "" -def date = "" -ext { - git = Grgit.open(dir: '.git') - date = git.head().getDate().format("yy.MM.dd") - revision = "-${git.head().abbreviatedId}" - parents = git.head().parentIds; - if (project.hasProperty('buildnumber')) { - buildNumber = "$buildnumber" - } else { - index = -2109; // Offset to match CI - for (; parents != null && !parents.isEmpty(); index++) { - parents = git.getResolve().toCommit(parents.get(0)).getParentIds() + def rootVersion = "1.13" + def revision = "" + def buildNumber = "" + def date = "" + ext { + git = Grgit.open(dir: '.git') + date = git.head().getDate().format("yy.MM.dd") + revision = "-${git.head().abbreviatedId}" + parents = git.head().parentIds; + if (project.hasProperty('buildnumber')) { + buildNumber = "$buildnumber" + } else { + index = -2109; // Offset to match CI + for (; parents != null && !parents.isEmpty(); index++) { + parents = git.getResolve().toCommit(parents.get(0)).getParentIds() + } + buildNumber = "${index}" } } diff --git a/favs/src/main/java/com/thevoxelbox/voxelsniper/util/VoxelList.java b/favs/src/main/java/com/thevoxelbox/voxelsniper/util/VoxelList.java index a360d5a0a..729683a71 100644 --- a/favs/src/main/java/com/thevoxelbox/voxelsniper/util/VoxelList.java +++ b/favs/src/main/java/com/thevoxelbox/voxelsniper/util/VoxelList.java @@ -23,7 +23,7 @@ public class VoxelList { } public void add(BlockMask mask) { - this.mask = (BlockMask) mask.and(mask); + this.mask = (BlockMask) mask.tryCombine(mask); } /** @@ -37,7 +37,7 @@ public class VoxelList { } public boolean removeValue(final BlockMask state) { - this.mask = (BlockMask) mask.and(state.inverse()); + this.mask = (BlockMask) mask.tryCombine(state.inverse()); return true; } diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle index 95d34d576..4004e00f1 100644 --- a/worldedit-bukkit/build.gradle +++ b/worldedit-bukkit/build.gradle @@ -18,6 +18,7 @@ configurations.all { Configuration it -> dependencies { compile ('net.milkbowl.vault:VaultAPI:1.7') api project(':worldedit-core') + api project(':worldedit-libs:core') // TODO remove once core can compile api project(':worldedit-libs:bukkit') compileOnly 'com.sk89q:dummypermscompat:1.10' testCompile 'org.mockito:mockito-core:1.9.0-rc1' diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 2a2563ccb..f04aac89f 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -318,13 +318,14 @@ public class BukkitWorld extends AbstractWorld { @Override public boolean equals(Object other) { - if (worldRef.get() == null) { + World ref = worldRef.get(); + if (ref == null) { return false; } else if (other == null) { return false; } else if ((other instanceof BukkitWorld)) { World otherWorld = ((BukkitWorld) other).worldRef.get(); - return otherWorld != null && otherWorld.equals(getWorld()); + return ref.equals(otherWorld); } else if (other instanceof com.sk89q.worldedit.world.World) { return ((com.sk89q.worldedit.world.World) other).getName().equals(getName()); } else { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java index f32ca1ac5..e3634a178 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.bukkit; +import com.bekvon.bukkit.residence.commands.command; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; @@ -36,12 +37,15 @@ import org.bukkit.event.player.PlayerCommandSendEvent; import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; +import org.enginehub.piston.Command; import org.enginehub.piston.CommandManager; import org.enginehub.piston.inject.InjectedValueStore; import org.enginehub.piston.inject.Key; import org.enginehub.piston.inject.MapBackedValueStore; +import java.util.Iterator; import java.util.Optional; +import java.util.function.Predicate; /** * Handles all events thrown in relation to a Player @@ -71,16 +75,22 @@ public class WorldEditListener implements Listener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onPlayerCommandSend(PlayerCommandSendEvent event) { - InjectedValueStore store = MapBackedValueStore.create(); - store.injectValue(Key.of(Actor.class), context -> - Optional.of(plugin.wrapCommandSender(event.getPlayer()))); + InjectedValueStore store = null; CommandManager commandManager = plugin.getWorldEdit().getPlatformManager().getPlatformCommandManager().getCommandManager(); - event.getCommands().removeIf(name -> - // remove if in the manager and not satisfied - commandManager.getCommand(name) - .filter(command -> !command.getCondition().satisfied(store)) - .isPresent() - ); + Iterator iter = event.getCommands().iterator(); + while (iter.hasNext()) { + String name = iter.next(); + Optional optional = commandManager.getCommand(name); + if (optional.isPresent()) { + if (store == null) { + store = MapBackedValueStore.create(); + store.injectValue(Key.of(Actor.class), context -> Optional.of(plugin.wrapCommandSender(event.getPlayer()))); + } + if (!optional.get().getCondition().satisfied(store)) { + iter.remove(); + } + } + } } /** diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/FawePlayer.java b/worldedit-core/src/main/java/com/boydti/fawe/object/FawePlayer.java index 919014d9c..9d32eb363 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/FawePlayer.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/FawePlayer.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.PlatformCommandManager; @@ -150,18 +151,22 @@ public abstract class FawePlayer extends Metadatable { return cancelled; } - private void setConfirmTask(@NotNull Runnable task, CommandContext context) { - Runnable newTask = () -> PlatformCommandManager.getInstance().handleCommandTask(() -> { - task.run(); - return null; - }, context.getLocals()); - setMeta("cmdConfirm", newTask); + private void setConfirmTask(@NotNull Runnable task, CommandContext context, String command) { + if (task != null) { + Runnable newTask = () -> PlatformCommandManager.getInstance().handleCommandTask(() -> { + task.run(); + return null; + }, context.getLocals()); + setMeta("cmdConfirm", newTask); + } else { + setMeta("cmdConfirm", new CommandEvent(getPlayer(), command)); + } } public void checkConfirmation(@NotNull Runnable task, String command, int times, int limit, CommandContext context) throws RegionOperationException { if (command != null && !getMeta("cmdConfirmRunning", false)) { if (times > limit) { - setConfirmTask(task, context); + setConfirmTask(task, context, command); String volume = ""; throw new RegionOperationException(BBC.WORLDEDIT_CANCEL_REASON_CONFIRM.f(0, times, command, volume)); } @@ -173,7 +178,7 @@ public abstract class FawePlayer extends Metadatable { if (command != null && !getMeta("cmdConfirmRunning", false)) { if (radius > 0) { if (radius > 448) { - setConfirmTask(task, context); + setConfirmTask(task, context, command); long volume = (long) (Math.PI * ((double) radius * radius)); throw new RegionOperationException(BBC.WORLDEDIT_CANCEL_REASON_CONFIRM.f(0, radius, command, NumberFormat.getNumberInstance().format(volume))); } @@ -189,7 +194,7 @@ public abstract class FawePlayer extends Metadatable { BlockVector3 max = region.getMaximumPoint(); long area = (long) ((max.getX() - min.getX()) * (max.getZ() - min.getZ() + 1)) * times; if (area > 2 << 18) { - setConfirmTask(task, context); + setConfirmTask(task, context, command); BlockVector3 base = max.subtract(min).add(BlockVector3.ONE); long volume = (long) base.getX() * base.getZ() * base.getY() * times; throw new RegionOperationException(BBC.WORLDEDIT_CANCEL_REASON_CONFIRM.f(min, max, command, NumberFormat.getNumberInstance().format(volume))); @@ -206,7 +211,7 @@ public abstract class FawePlayer extends Metadatable { BlockVector3 max = region.getMaximumPoint(); long area = (max.getX() - min.getX()) * (max.getZ() - min.getZ() + 1); if (area > 2 << 18) { - setConfirmTask(task, context); + setConfirmTask(task, context, command); BlockVector3 base = max.subtract(min).add(BlockVector3.ONE); long volume = (long) base.getX() * base.getZ() * base.getY(); throw new RegionOperationException(BBC.WORLDEDIT_CANCEL_REASON_CONFIRM.f(min, max, command, NumberFormat.getNumberInstance().format(volume))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index fd3697817..60dfd22b9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -25,41 +25,18 @@ import static com.sk89q.worldedit.regions.Regions.asFlatRegion; import static com.sk89q.worldedit.regions.Regions.maximumBlockY; import static com.sk89q.worldedit.regions.Regions.minimumBlockY; -import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweAPI; import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.example.MappedFaweQueue; -import com.boydti.fawe.jnbt.anvil.MCAQueue; -import com.boydti.fawe.jnbt.anvil.MCAWorld; -import com.boydti.fawe.logging.LoggingChangeSet; -import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory; import com.boydti.fawe.object.FaweLimit; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.HistoryExtent; -import com.boydti.fawe.object.NullChangeSet; import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal; -import com.boydti.fawe.object.brush.visualization.VirtualWorld; import com.boydti.fawe.object.changeset.BlockBagChangeSet; -import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet; -import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.FaweChangeSet; -import com.boydti.fawe.object.changeset.MemoryOptimizedHistory; import com.boydti.fawe.object.collection.LocalBlockVectorSet; import com.boydti.fawe.object.exception.FaweException; -import com.boydti.fawe.object.extent.FastWorldEditExtent; -import com.boydti.fawe.object.extent.FaweRegionExtent; -import com.boydti.fawe.object.extent.HeightBoundExtent; -import com.boydti.fawe.object.extent.MultiRegionExtent; -import com.boydti.fawe.object.extent.NullExtent; -import com.boydti.fawe.object.extent.ProcessedWEExtent; -import com.boydti.fawe.object.extent.ResettableExtent; -import com.boydti.fawe.object.extent.SingleRegionExtent; -import com.boydti.fawe.object.extent.SlowExtent; -import com.boydti.fawe.object.extent.SourceMaskExtent; -import com.boydti.fawe.object.extent.StripNBTExtent; import com.boydti.fawe.object.extent.FaweRegionExtent; import com.boydti.fawe.object.extent.NullExtent; import com.boydti.fawe.object.extent.ProcessedWEExtent; @@ -68,24 +45,17 @@ import com.boydti.fawe.object.extent.SourceMaskExtent; import com.boydti.fawe.object.function.SurfaceRegionFunction; import com.boydti.fawe.object.mask.ResettableMask; import com.boydti.fawe.object.pattern.ExistingPattern; -import com.boydti.fawe.object.progress.ChatProgressTracker; -import com.boydti.fawe.object.progress.DefaultProgressTracker; import com.boydti.fawe.util.EditSessionBuilder; import com.boydti.fawe.util.ExtentTraverser; import com.boydti.fawe.util.MaskTraverser; import com.boydti.fawe.util.MathMan; -import com.boydti.fawe.util.MemUtil; -import com.boydti.fawe.util.Perm; -import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; -import com.boydti.fawe.wrappers.WorldWrapper; import com.google.common.base.Supplier; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.event.extent.EditSessionEvent; -import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.ChangeSetExtent; import com.sk89q.worldedit.extent.Extent; @@ -95,12 +65,10 @@ import com.sk89q.worldedit.extent.inventory.BlockBagExtent; import com.sk89q.worldedit.extent.world.SurvivalModeExtent; import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.RegionFunction; -import com.sk89q.worldedit.function.RegionMaskingFilter; import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.block.Naturalizer; import com.sk89q.worldedit.function.generator.ForestGenerator; import com.sk89q.worldedit.function.generator.GardenPatchGenerator; -import com.sk89q.worldedit.function.mask.BlockMaskBuilder; import com.sk89q.worldedit.function.mask.BlockTypeMask; import com.sk89q.worldedit.function.mask.BoundedHeightMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask; @@ -116,7 +84,6 @@ import com.sk89q.worldedit.function.operation.ChangeSetExecutor; import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operations; -import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.WaterloggedRemover; import com.sk89q.worldedit.function.util.RegionOffset; @@ -137,7 +104,6 @@ import com.sk89q.worldedit.internal.expression.runtime.ExpressionTimeoutExceptio import com.sk89q.worldedit.internal.expression.runtime.RValue; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.math.MathUtils; import com.sk89q.worldedit.math.MutableBlockVector2; import com.sk89q.worldedit.math.MutableBlockVector3; import com.sk89q.worldedit.math.Vector2; @@ -161,7 +127,6 @@ import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.util.eventbus.EventBus; -import com.sk89q.worldedit.world.SimpleWorld; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; @@ -185,15 +150,12 @@ import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import org.jetbrains.annotations.NotNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static com.sk89q.worldedit.regions.Regions.asFlatRegion; -import static com.sk89q.worldedit.regions.Regions.maximumBlockY; -import static com.sk89q.worldedit.regions.Regions.minimumBlockY; /** * An {@link Extent} that handles history, {@link BlockBag}s, change limits, @@ -559,9 +521,6 @@ public class EditSession extends AbstractDelegateExtent SimpleWorld, AutoCloseab new MaskTraverser(mask).reset(this); } ExtentTraverser maskingExtent = new ExtentTraverser<>(getExtent()).find(SourceMaskExtent.class); -======= - ExtentTraverser maskingExtent = new ExtentTraverser<>(getExtent()).find(SourceMaskExtent.class); ->>>>>>> filter-pipeline if (maskingExtent != null && maskingExtent.get() != null) { Mask oldMask = maskingExtent.get().getMask(); if (oldMask instanceof ResettableMask) { @@ -2580,7 +2539,7 @@ public class EditSession extends AbstractDelegateExtent SimpleWorld, AutoCloseab final Vector3 scaled = current.subtract(zero).divide(unit); try { - if (expression.evaluate(new double[]{scaled.getX(), scaled.getY(), scaled.getZ(), defaultMaterial.getBlockType().getInternalId(), defaultMaterial.getInternalPropertiesId()}, timeout) <= 0) { + if (expression.evaluateTimeout(timeout, scaled.getX(), scaled.getY(), scaled.getZ(), defaultMaterial.getBlockType().getInternalId(), defaultMaterial.getInternalPropertiesId()) <= 0) { // TODO data return null; } @@ -2632,7 +2591,7 @@ public class EditSession extends AbstractDelegateExtent SimpleWorld, AutoCloseab final Vector3 scaled = position.toVector3().subtract(zero).divide(unit); // transform - expression.evaluate(new double[]{scaled.getX(), scaled.getY(), scaled.getZ()}, timeout); + expression.evaluateTimeout(timeout, scaled.getX(), scaled.getY(), scaled.getZ()); int xv = (int) (x.getValue() * unit.getX() + zero2.getX()); int yv = (int) (y.getValue() * unit.getY() + zero2.getY()); int zv = (int) (z.getValue() * unit.getZ() + zero2.getZ()); @@ -2993,7 +2952,7 @@ public class EditSession extends AbstractDelegateExtent SimpleWorld, AutoCloseab double scaledZ = (z - zero2D.getZ()) / unit2D.getZ(); try { - if (expression.evaluate(new double[]{scaledX, scaledZ}, timeout) <= 0) { + if (expression.evaluateTimeout(timeout, scaledX, scaledZ, timeout) <= 0) { return null; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 23cc8d029..5e4e36ece 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -660,8 +660,7 @@ public class UtilityCommands { return; } WorldEditAsyncCommandBuilder.createAndSendMessage(actor, () -> { - double result = expression.evaluate( - new double[]{}, WorldEdit.getInstance().getSessionManager().get(actor).getTimeout()); + double result = expression.evaluateTimeout(WorldEdit.getInstance().getSessionManager().get(actor).getTimeout()); String formatted = Double.isNaN(result) ? "NaN" : formatter.format(result); return SubtleFormat.wrap(input + " = ").append(TextComponent.of(formatted, TextColor.LIGHT_PURPLE)); }, null); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 736d0663d..7b46c3fc1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -20,19 +20,8 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.extension.factory.parser.mask.BiomeMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.BlockCategoryMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.BlockStateMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.BlocksMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.ExistingMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.ExpressionMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.LazyRegionMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.NegateMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser; -import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java index ac104e198..a7d55e990 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExpressionMaskParser.java @@ -62,7 +62,7 @@ public class ExpressionMaskParser extends InputParser { exp.setEnvironment(env); if (context.getActor() != null) { SessionOwner owner = context.getActor(); - IntSupplier timeout = () -> WorldEdit.getInstance().getSessionManager().get(owner).getTimeout(); + int timeout = WorldEdit.getInstance().getSessionManager().get(owner).getTimeout(); return new ExpressionMask(exp, timeout); } return new ExpressionMask(exp); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index b21744f97..cfa42f58a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -209,7 +209,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { public boolean descendLevel() { final Location pos = getBlockIn(); final int x = pos.getBlockX(); - int y = Math.max(0, pos.getBlockY() - 1); + int y = Math.max(0, pos.getBlockY()); final int z = pos.getBlockZ(); final Extent world = pos.getExtent(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ABlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ABlockMask.java index 5f26ef942..95fa6c4c1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ABlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ABlockMask.java @@ -2,14 +2,12 @@ package com.sk89q.worldedit.function.mask; import com.boydti.fawe.util.StringMan; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import java.util.ArrayList; import java.util.List; -import java.util.Set; public abstract class ABlockMask extends AbstractExtentMask { public ABlockMask(Extent extent) { @@ -45,7 +43,7 @@ public abstract class ABlockMask extends AbstractExtentMask { } @Override - public Mask and(Mask mask) { + public Mask tryCombine(Mask mask) { if (mask instanceof ABlockMask) { ABlockMask other = (ABlockMask) mask; BlockMask newMask = new BlockMask(getExtent()); @@ -56,7 +54,7 @@ public abstract class ABlockMask extends AbstractExtentMask { } } } - Mask tmp = newMask.optimize(); + Mask tmp = newMask.tryOptimize(); if (tmp == null) tmp = newMask; return tmp; } @@ -64,7 +62,7 @@ public abstract class ABlockMask extends AbstractExtentMask { } @Override - public Mask or(Mask mask) { + public Mask tryOr(Mask mask) { if (mask instanceof ABlockMask) { ABlockMask other = (ABlockMask) mask; BlockMask newMask = new BlockMask(getExtent()); @@ -75,7 +73,7 @@ public abstract class ABlockMask extends AbstractExtentMask { } } } - Mask tmp = newMask.optimize(); + Mask tmp = newMask.tryOptimize(); if (tmp == null) tmp = newMask; return tmp; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java index cb4d91fba..19d6c63fa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java @@ -129,7 +129,7 @@ public class BlockMask extends ABlockMask { } @Override - public Mask and(Mask mask) { + public Mask tryCombine(Mask mask) { if (mask instanceof ABlockMask) { ABlockMask other = (ABlockMask) mask; for (int i = 0; i < ordinals.length; i++) { @@ -143,7 +143,7 @@ public class BlockMask extends ABlockMask { } @Override - public Mask or(Mask mask) { + public Mask tryOr(Mask mask) { if (mask instanceof ABlockMask) { ABlockMask other = (ABlockMask) mask; for (int i = 0; i < ordinals.length; i++) { @@ -157,7 +157,7 @@ public class BlockMask extends ABlockMask { } @Override - public Mask optimize() { + public Mask tryOptimize() { int setStates = 0; BlockState setState = null; BlockState unsetState = null; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMaskBuilder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMaskBuilder.java index c580b3ecc..54ee24e23 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMaskBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMaskBuilder.java @@ -248,7 +248,10 @@ public class BlockMaskBuilder { private boolean optimizedStates = true; public boolean isEmpty() { - return Arrays.stream(bitSets).noneMatch(Objects::nonNull); + for (long[] bitSet : bitSets) { + if (bitSet != null) return false; + } + return true; } public BlockMaskBuilder() { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java index eba02d0a7..c43c98581 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask; import static com.google.common.base.Preconditions.checkNotNull; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; @@ -39,7 +40,7 @@ import java.util.function.IntSupplier; public class ExpressionMask extends AbstractMask { private final Expression expression; - private final IntSupplier timeout; + private final int timeout; /** * Create a new instance. @@ -57,10 +58,10 @@ public class ExpressionMask extends AbstractMask { * @param expression the expression */ public ExpressionMask(Expression expression) { - this(expression, null); + this(expression, WorldEdit.getInstance().getConfiguration().calculationTimeout); } - public ExpressionMask(Expression expression, @Nullable IntSupplier timeout) { + public ExpressionMask(Expression expression, int timeout) { checkNotNull(expression); this.expression = expression; this.timeout = timeout; @@ -72,12 +73,7 @@ public class ExpressionMask extends AbstractMask { if (expression.getEnvironment() instanceof WorldEditExpressionEnvironment) { ((WorldEditExpressionEnvironment) expression.getEnvironment()).setCurrentBlock(vector.toVector3()); } - if (timeout == null) { - return expression.evaluate(vector.getX(), vector.getY(), vector.getZ()) > 0; - } else { - return expression.evaluate(new double[]{vector.getX(), vector.getY(), vector.getZ()}, - timeout.getAsInt()) > 0; - } + return expression.evaluateTimeout(timeout, vector.getX(), vector.getY(), vector.getZ()) > 0; } catch (EvaluationException e) { return false; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java index a50c5e375..07debb717 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask; import static com.google.common.base.Preconditions.checkNotNull; +import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; @@ -32,7 +33,7 @@ import java.util.function.IntSupplier; public class ExpressionMask2D extends AbstractMask2D { private final Expression expression; - private final IntSupplier timeout; + private final int timeout; /** * Create a new instance. @@ -50,10 +51,10 @@ public class ExpressionMask2D extends AbstractMask2D { * @param expression the expression */ public ExpressionMask2D(Expression expression) { - this(expression, null); + this(expression, WorldEdit.getInstance().getConfiguration().calculationTimeout); } - public ExpressionMask2D(Expression expression, @Nullable IntSupplier timeout) { + public ExpressionMask2D(Expression expression, int timeout) { checkNotNull(expression); this.expression = expression; this.timeout = timeout; @@ -62,11 +63,7 @@ public class ExpressionMask2D extends AbstractMask2D { @Override public boolean test(BlockVector2 vector) { try { - if (timeout != null) { - return expression.evaluate(vector.getX(), 0, vector.getZ()) > 0; - } else { - return expression.evaluate(new double[]{vector.getX(), 0, vector.getZ()}, timeout.getAsInt()) > 0; - } + return expression.evaluateTimeout(timeout, vector.getX(), 0, vector.getZ()) > 0; } catch (EvaluationException e) { return false; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java index 359a38175..1818e7181 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java @@ -75,16 +75,36 @@ public interface Mask { return null; } - default Mask optimize() { + /** + * Returns null if no optimization took place + * otherwise a new/same mask + * @return + */ + default Mask tryOptimize() { return null; } + default Mask tryCombine(Mask other) { + return null; + } + + default Mask tryOr(Mask other) { + return null; + } + + default Mask optimize() { + Mask value = tryOptimize(); + return value == null ? this : value; + } + default Mask and(Mask other) { - return null; + Mask value = and(other); + return value == null ? new MaskIntersection(this, other) : value; } default Mask or(Mask other) { - return null; + Mask value = or(other); + return value == null ? new MaskUnion(this, other) : value; } default Mask inverse() { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java index dba2b6743..f71639485 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskIntersection.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.function.mask; import static com.google.common.base.Preconditions.checkNotNull; +import com.boydti.fawe.Fawe; import com.google.common.base.Function; import com.sk89q.worldedit.math.BlockVector3; @@ -58,6 +59,30 @@ public class MaskIntersection extends AbstractMask { formArray(); } + public static Mask of(Mask... masks) { + Set set = new LinkedHashSet<>(); + for (Mask mask : masks) { + if (mask == Masks.alwaysFalse()) { + return mask; + } + if (mask != null && mask != Masks.alwaysTrue()) { + if (mask.getClass() == MaskIntersection.class) { + set.addAll(((MaskIntersection) mask).getMasks()); + } else { + set.add(mask); + } + } + } + switch (set.size()) { + case 0: + return Masks.alwaysTrue(); + case 1: + return set.iterator().next(); + default: + return new MaskIntersection(masks).optimize(); + } + } + /** * Create a new intersection. * @@ -76,47 +101,68 @@ public class MaskIntersection extends AbstractMask { } public Function, Mask> pairingFunction() { - return input -> input.getKey().and(input.getValue()); + return input -> input.getKey().tryCombine(input.getValue()); } - private void optimizeMasks(Set ignore) { - LinkedHashSet newMasks = null; - for (Mask mask : masks) { + private boolean optimizeMasks(Set ignore) { + boolean changed = false; + // Optimize sub masks + for (int i = 0; i < masksArray.length; i++) { + Mask mask = masksArray[i]; if (ignore.contains(mask)) continue; - Mask newMask = mask.optimize(); + Mask newMask = mask.tryOptimize(); if (newMask != null) { - if (newMask != mask) { - if (newMasks == null) newMasks = new LinkedHashSet<>(); - newMasks.add(newMask); - } + changed = true; + masksArray[i] = newMask; } else { ignore.add(mask); } - if (newMasks != null) { - masks.clear(); - masks.addAll(newMasks); + } + if (changed) { + masks.clear(); + for (Mask mask : masksArray) masks.add(mask); + } + // Optimize this + boolean formArray = false; + for (int i = 0; i < masksArray.length; i++) { + Mask mask = masksArray[i]; + if (mask.getClass() == this.getClass()) { + this.masks.remove(mask); + this.masks.addAll(((MaskIntersection) mask).getMasks()); + formArray = true; + changed = true; } } + if (formArray) formArray(); + return changed; } @Override - public Mask optimize() { + public Mask tryOptimize() { + int maxIteration = 1000; Set optimized = new HashSet<>(); Set> failedCombines = new HashSet<>(); // Combine the masks - while (combine(pairingFunction(), failedCombines)) { - } + boolean changed = false; + while (changed |= combineMasks(pairingFunction(), failedCombines)); // Optimize / combine - do optimizeMasks(optimized); - while (combine(pairingFunction(), failedCombines)); + do changed |= optimizeMasks(optimized); + while (changed |= combineMasks(pairingFunction(), failedCombines) && --maxIteration > 0); + + if (maxIteration == 0) { + Fawe.debug("Failed optimize MaskIntersection"); + for (Mask mask : masks) { + System.out.println(mask.getClass() + " / " + mask); + } + } // Return result formArray(); if (masks.size() == 0) return Masks.alwaysTrue(); if (masks.size() == 1) return masks.iterator().next(); - return this; + return changed ? this : null; } - private boolean combine(Function, Mask> pairing, Set> failedCombines) { + private boolean combineMasks(Function, Mask> pairing, Set> failedCombines) { boolean hasOptimized = false; while (true) { Mask[] result = null; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java index 7c8bb0a61..690f14361 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/MaskUnion.java @@ -19,15 +19,16 @@ package com.sk89q.worldedit.function.mask; -import com.boydti.fawe.beta.FilterBlock; import com.google.common.base.Function; import com.sk89q.worldedit.math.BlockVector3; import java.util.ArrayList; import java.util.Collection; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; /** @@ -55,9 +56,33 @@ public class MaskUnion extends MaskIntersection { super(mask); } + public static Mask of(Mask... masks) { + Set set = new LinkedHashSet<>(); + for (Mask mask : masks) { + if (mask == Masks.alwaysTrue()) { + return mask; + } + if (mask != null) { + if (mask.getClass() == MaskUnion.class) { + set.addAll(((MaskUnion) mask).getMasks()); + } else { + set.add(mask); + } + } + } + switch (set.size()) { + case 0: + return Masks.alwaysTrue(); + case 1: + return set.iterator().next(); + default: + return new MaskUnion(masks).optimize(); + } + } + @Override public Function, Mask> pairingFunction() { - return input -> input.getKey().or(input.getValue()); + return input -> input.getKey().tryOr(input.getValue()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java index dd85587c7..ade00728c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java @@ -135,12 +135,12 @@ public final class Masks { } @Override - public Mask and(Mask other) { + public Mask tryCombine(Mask other) { return other; } @Override - public Mask or(Mask other) { + public Mask tryOr(Mask other) { return this; } } @@ -163,12 +163,12 @@ public final class Masks { } @Override - public Mask and(Mask other) { + public Mask tryCombine(Mask other) { return this; } @Override - public Mask or(Mask other) { + public Mask tryOr(Mask other) { return other; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockStateMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockStateMask.java index 3507571e8..fa3655ccc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockStateMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SingleBlockStateMask.java @@ -37,7 +37,7 @@ public class SingleBlockStateMask extends ABlockMask { } @Override - public Mask and(Mask mask) { + public Mask tryCombine(Mask mask) { if (mask instanceof ABlockMask) { ABlockMask other = (ABlockMask) mask; if (other.test(BlockState.getFromOrdinal(ordinal))) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java index 9e3ea34d3..67b0ce75b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/SolidBlockMask.java @@ -20,32 +20,13 @@ package com.sk89q.worldedit.function.mask; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; import javax.annotation.Nullable; public class SolidBlockMask extends BlockMask { public SolidBlockMask(Extent extent) { super(extent); - add(state -> state.getMaterial().isSolid()); - } - - @Override - public boolean test(BlockVector3 vector) { - Extent extent = getExtent(); - BlockState block = extent.getBlock(vector); - return block.getBlockType().getMaterial().isMovementBlocker(); - } - - public static boolean[] getTypes() { - boolean[] types = new boolean[BlockTypes.size()]; - for (BlockType type : BlockTypes.values) { - types[type.getInternalId()] = type.getMaterial().isSolid(); - } - return types; + add(state -> state.getMaterial().isMovementBlocker()); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java index c2e4af23c..59c1abe9b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java @@ -163,6 +163,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 after * the copy has been made. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java index bb46b8d73..2656039ce 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/WorldEditBinding.java @@ -357,7 +357,7 @@ public class WorldEditBinding { String input = context.next(); if (input != null) { - if (MathMan.isInteger(input)) return BiomeTypes.register(Integer.parseInt(input)); + if (MathMan.isInteger(input)) return BiomeTypes.get(Integer.parseInt(input)); BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager() .queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java index 476a00fae..424908f08 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java @@ -127,7 +127,48 @@ public class Expression { root = Parser.parse(tokens, this); } + public double evaluate(double x, double y, double z) throws EvaluationException { + return evaluateTimeout(WorldEdit.getInstance().getConfiguration().calculationTimeout, x, y, z); + } + + public double evaluate() throws EvaluationException { + return evaluateFinal(WorldEdit.getInstance().getConfiguration().calculationTimeout); + } + public double evaluate(double... values) throws EvaluationException { + return evaluateTimeout(WorldEdit.getInstance().getConfiguration().calculationTimeout, values); + } + + public double evaluateTimeout(int timeout) throws EvaluationException { + if (root instanceof Constant) return root.getValue(); + return evaluateFinal(timeout); + } + + public double evaluateTimeout(int timeout, double x, double y) throws EvaluationException { + if (root instanceof Constant) return root.getValue(); + variableArray[0].value = x; + variableArray[1].value = y; + return evaluateFinal(timeout); + } + + public double evaluateTimeout(int timeout, double x, double y, double z) throws EvaluationException { + if (root instanceof Constant) return root.getValue(); + variableArray[0].value = x; + variableArray[1].value = y; + variableArray[2].value = z; + return evaluateFinal(timeout); + } + + public double evaluateTimeout(int timeout, double... values) throws EvaluationException { + if (root instanceof Constant) return root.getValue(); + for (int i = 0; i < values.length; i++) { + Variable var = variableArray[i]; + var.value = values[i]; + } + return evaluateFinal(timeout); + } + + public double evaluate(double[] values, int timeout) throws EvaluationException { if (root instanceof Constant) { return root.getValue(); } @@ -135,21 +176,10 @@ public class Expression { Variable var = variableArray[i]; var.value = values[i]; } - pushInstance(); - return evaluate(values, WorldEdit.getInstance().getConfiguration().calculationTimeout); + return evaluateFinal(timeout); } - public double evaluate(double[] values, int timeout) throws EvaluationException { - for (int i = 0; i < values.length; ++i) { - final String variableName = variableNames[i]; - final RValue invokable = variables.get(variableName); - if (!(invokable instanceof Variable)) { - throw new EvaluationException(invokable.getPosition(), "Tried to assign constant " + variableName + "."); - } - - ((Variable) invokable).value = values[i]; - } - + private double evaluateFinal(int timeout) throws EvaluationException { try { if (timeout < 0) { return evaluateRoot(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java index 84b60021b..c5b2b27f0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/runtime/ReturnException.java @@ -38,4 +38,4 @@ public class ReturnException extends EvaluationException { return value; } -} +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index bd2658da6..f125d3672 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -392,7 +392,7 @@ public abstract class BlockVector3 { * @return a new vector */ public BlockVector3 shr(int x, int y, int z) { - return at(this.x >> x, this.y >> y, this.z >> z); + return at(this.getX() >> x, this.getY() >> y, this.getZ() >> z); } /** @@ -414,7 +414,7 @@ public abstract class BlockVector3 { * @return a new vector */ public BlockVector3 shl(int x, int y, int z) { - return at(this.x << x, this.y << y, this.z << z); + return at(this.getX() << x, this.getY() << y, this.getZ() << z); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/MutableVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/MutableVector3.java index dca366ce8..215411e25 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/MutableVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/MutableVector3.java @@ -3,7 +3,7 @@ package com.sk89q.worldedit.math; import com.boydti.fawe.FaweCache; public class MutableVector3 extends Vector3 { - + private double x,y,z; public MutableVector3() { } public static MutableVector3 get(int x, int y, int z) { @@ -15,22 +15,39 @@ public class MutableVector3 extends Vector3 { } public MutableVector3(double x, double y, double z) { - super(x, y, z); + this.x = x; + this.y = y; + this.z = z; } public MutableVector3(float x, float y, float z) { - super(x, y, z); + this((double) x, (double) y, (double) z); } public MutableVector3(Vector3 other) { - super(other); + this(other.getX(), other.getY(), other.getZ()); + } + + @Override + public double getX() { + return x; + } + + @Override + public double getY() { + return y; + } + + @Override + public double getZ() { + return z; } @Override public MutableVector3 setComponents(Vector3 other) { - this.x = other.x; - this.y = other.y; - this.z = other.z; + this.x = other.getX(); + this.y = other.getY(); + this.z = other.getZ(); return this; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java index cee4b8c56..79d4dd9e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java @@ -30,25 +30,25 @@ import java.util.Comparator; /** * An immutable 3-dimensional vector. */ -public class Vector3 { +public abstract class Vector3 { - public static final Vector3 ZERO = new Vector3(0, 0, 0); - public static final Vector3 UNIT_X = new Vector3(1, 0, 0); - public static final Vector3 UNIT_Y = new Vector3(0, 1, 0); - public static final Vector3 UNIT_Z = new Vector3(0, 0, 1); - public static final Vector3 ONE = new Vector3(1, 1, 1); + public static final Vector3 ZERO = Vector3.at(0, 0, 0); + public static final Vector3 UNIT_X = Vector3.at(1, 0, 0); + public static final Vector3 UNIT_Y = Vector3.at(0, 1, 0); + public static final Vector3 UNIT_Z = Vector3.at(0, 0, 1); + public static final Vector3 ONE = Vector3.at(1, 1, 1); public static Vector3 at(double x, double y, double z) { - return new Vector3(x, y, z); + return new Vector3Impl(x, y, z); } // thread-safe initialization idiom private static final class YzxOrderComparator { private static final Comparator YZX_ORDER = (a, b) -> { return ComparisonChain.start() - .compare(a.y, b.y) - .compare(a.z, b.z) - .compare(a.x, b.x) + .compare(a.getY(), b.getY()) + .compare(a.getZ(), b.getZ()) + .compare(a.getX(), b.getX()) .result(); }; } @@ -63,29 +63,6 @@ public class Vector3 { return YzxOrderComparator.YZX_ORDER; } - protected double x, y, z; - - /** - * Construct an instance. - * - * @param x the X coordinate - * @param y the Y coordinate - * @param z the Z coordinate - */ - protected Vector3(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; - } - - protected Vector3() {} - - protected Vector3(Vector3 other) { - this.x = other.x; - this.y = other.y; - this.z = other.z; - } - public int getBlockX() { return MathMan.roundInt(getX()); } @@ -111,11 +88,11 @@ public class Vector3 { } public MutableVector3 mutX(int x) { - return new MutableVector3(x, y, getZ()); + return new MutableVector3(x, getY(), getZ()); } public MutableVector3 mutX(double x) { - return new MutableVector3(x, y, getZ()); + return new MutableVector3(x, getY(), getZ()); } public MutableVector3 mutY(int y) { @@ -127,11 +104,11 @@ public class Vector3 { } public MutableVector3 mutZ(int z) { - return new MutableVector3(getX(), y, z); + return new MutableVector3(getX(), getY(), z); } public MutableVector3 mutZ(double z) { - return new MutableVector3(getX(), y, z); + return new MutableVector3(getX(), getY(), z); } /** @@ -139,9 +116,7 @@ public class Vector3 { * * @return the x coordinate */ - public double getX() { - return x; - } + public abstract double getX(); /** * Set the X coordinate. @@ -150,7 +125,7 @@ public class Vector3 { * @return a new vector */ public Vector3 withX(double x) { - return Vector3.at(x, y, z); + return Vector3.at(x, getY(), getZ()); } /** @@ -158,9 +133,7 @@ public class Vector3 { * * @return the y coordinate */ - public double getY() { - return y; - } + public abstract double getY(); /** * Set the Y coordinate. @@ -169,7 +142,7 @@ public class Vector3 { * @return a new vector */ public Vector3 withY(double y) { - return Vector3.at(x, y, z); + return Vector3.at(getX(), y, getZ()); } /** @@ -177,9 +150,7 @@ public class Vector3 { * * @return the z coordinate */ - public double getZ() { - return z; - } + public abstract double getZ(); /** * Set the Z coordinate. @@ -188,7 +159,7 @@ public class Vector3 { * @return a new vector */ public Vector3 withZ(double z) { - return Vector3.at(x, y, z); + return Vector3.at(getX(), getY(), z); } /** @@ -198,7 +169,7 @@ public class Vector3 { * @return a new vector */ public Vector3 add(Vector3 other) { - return add(other.x, other.y, other.z); + return add(other.getX(), other.getY(), other.getZ()); } /** @@ -210,7 +181,7 @@ public class Vector3 { * @return a new vector */ public Vector3 add(double x, double y, double z) { - return Vector3.at(this.x + x, this.y + y, this.z + z); + return Vector3.at(this.getX() + x, this.getY() + y, this.getZ() + z); } /** @@ -221,12 +192,12 @@ public class Vector3 { * @return a new vector */ public Vector3 add(Vector3... others) { - double newX = x, newY = y, newZ = z; + double newX = getX(), newY = getY(), newZ = getZ(); for (Vector3 other : others) { - newX += other.x; - newY += other.y; - newZ += other.z; + newX += other.getX(); + newY += other.getY(); + newZ += other.getZ(); } return Vector3.at(newX, newY, newZ); @@ -240,7 +211,7 @@ public class Vector3 { * @return a new vector */ public Vector3 subtract(Vector3 other) { - return subtract(other.x, other.y, other.z); + return subtract(other.getX(), other.getY(), other.getZ()); } /** @@ -253,7 +224,7 @@ public class Vector3 { * @return a new vector */ public Vector3 subtract(double x, double y, double z) { - return Vector3.at(this.x - x, this.y - y, this.z - z); + return Vector3.at(this.getX() - x, this.getY() - y, this.getZ() - z); } /** @@ -264,12 +235,12 @@ public class Vector3 { * @return a new vector */ public Vector3 subtract(Vector3... others) { - double newX = x, newY = y, newZ = z; + double newX = getX(), newY = getY(), newZ = getZ(); for (Vector3 other : others) { - newX -= other.x; - newY -= other.y; - newZ -= other.z; + newX -= other.getX(); + newY -= other.getY(); + newZ -= other.getZ(); } return Vector3.at(newX, newY, newZ); @@ -282,7 +253,7 @@ public class Vector3 { * @return a new vector */ public Vector3 multiply(Vector3 other) { - return multiply(other.x, other.y, other.z); + return multiply(other.getX(), other.getY(), other.getZ()); } /** @@ -294,7 +265,7 @@ public class Vector3 { * @return a new vector */ public Vector3 multiply(double x, double y, double z) { - return Vector3.at(this.x * x, this.y * y, this.z * z); + return Vector3.at(this.getX() * x, this.getY() * y, this.getZ() * z); } /** @@ -304,12 +275,12 @@ public class Vector3 { * @return a new vector */ public Vector3 multiply(Vector3... others) { - double newX = x, newY = y, newZ = z; + double newX = getX(), newY = getY(), newZ = getZ(); for (Vector3 other : others) { - newX *= other.x; - newY *= other.y; - newZ *= other.z; + newX *= other.getX(); + newY *= other.getY(); + newZ *= other.getZ(); } return Vector3.at(newX, newY, newZ); @@ -332,7 +303,7 @@ public class Vector3 { * @return a new vector */ public Vector3 divide(Vector3 other) { - return divide(other.x, other.y, other.z); + return divide(other.getX(), other.getY(), other.getZ()); } /** @@ -344,7 +315,7 @@ public class Vector3 { * @return a new vector */ public Vector3 divide(double x, double y, double z) { - return Vector3.at(this.x / x, this.y / y, this.z / z); + return Vector3.at(this.getX() / x, this.getY() / y, this.getZ() / z); } /** @@ -372,7 +343,7 @@ public class Vector3 { * @return length, squared */ public double lengthSq() { - return x * x + y * y + z * z; + return getX() * getX() + getY() * getY() + getZ() * getZ(); } /** @@ -392,9 +363,9 @@ public class Vector3 { * @return distance */ public double distanceSq(Vector3 other) { - double dx = other.x - x; - double dy = other.y - y; - double dz = other.z - z; + double dx = other.getX() - getX(); + double dy = other.getY() - getY(); + double dz = other.getZ() - getZ(); return dx * dx + dy * dy + dz * dz; } @@ -415,7 +386,7 @@ public class Vector3 { * @return the dot product of this and the other vector */ public double dot(Vector3 other) { - return x * other.x + y * other.y + z * other.z; + return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ(); } /** @@ -425,10 +396,10 @@ public class Vector3 { * @return the cross product of this and the other vector */ public Vector3 cross(Vector3 other) { - return new Vector3( - y * other.z - z * other.y, - z * other.x - x * other.z, - x * other.y - y * other.x + return Vector3.at( + getY() * other.getZ() - getZ() * other.getY(), + getZ() * other.getX() - getX() * other.getZ(), + getX() * other.getY() - getY() * other.getX() ); } @@ -440,7 +411,7 @@ public class Vector3 { * @return true if the vector is contained */ public boolean containedWithin(Vector3 min, Vector3 max) { - return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z; + return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max.getY() && getZ() >= min.getZ() && getZ() <= max.getZ(); } /** @@ -452,11 +423,11 @@ public class Vector3 { */ public Vector3 clampY(int min, int max) { checkArgument(min <= max, "minimum cannot be greater than maximum"); - if (y < min) { - return Vector3.at(x, min, z); + if (getY() < min) { + return Vector3.at(getX(), min, getZ()); } - if (y > max) { - return Vector3.at(x, max, z); + if (getY() > max) { + return Vector3.at(getX(), max, getZ()); } return this; } @@ -467,7 +438,7 @@ public class Vector3 { * @return a new vector */ public Vector3 floor() { - return Vector3.at(Math.floor(x), Math.floor(y), Math.floor(z)); + return Vector3.at(Math.floor(getX()), Math.floor(getY()), Math.floor(getZ())); } /** @@ -476,7 +447,7 @@ public class Vector3 { * @return a new vector */ public Vector3 ceil() { - return Vector3.at(Math.ceil(x), Math.ceil(y), Math.ceil(z)); + return Vector3.at(Math.ceil(getX()), Math.ceil(getY()), Math.ceil(getZ())); } /** @@ -487,7 +458,7 @@ public class Vector3 { * @return a new vector */ public Vector3 round() { - return Vector3.at(Math.floor(x + 0.5), Math.floor(y + 0.5), Math.floor(z + 0.5)); + return Vector3.at(Math.floor(getX() + 0.5), Math.floor(getY() + 0.5), Math.floor(getZ() + 0.5)); } /** @@ -497,7 +468,7 @@ public class Vector3 { * @return a new vector */ public Vector3 abs() { - return Vector3.at(Math.abs(x), Math.abs(y), Math.abs(z)); + return Vector3.at(Math.abs(getX()), Math.abs(getY()), Math.abs(getZ())); } /** @@ -513,16 +484,16 @@ public class Vector3 { */ public Vector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) { angle = Math.toRadians(angle); - double x = this.x - aboutX; - double z = this.z - aboutZ; + double x = this.getX() - aboutX; + double z = this.getZ() - aboutZ; double cos = Math.cos(angle); double sin = Math.sin(angle); double x2 = x * cos - z * sin; double z2 = x * sin + z * cos; - return new Vector3( + return Vector3.at( x2 + aboutX + translateX, - y, + getY(), z2 + aboutZ + translateZ ); } @@ -568,10 +539,10 @@ public class Vector3 { * @return minimum */ public Vector3 getMinimum(Vector3 v2) { - return new Vector3( - Math.min(x, v2.x), - Math.min(y, v2.y), - Math.min(z, v2.z) + return Vector3.at( + Math.min(getX(), v2.getX()), + Math.min(getY(), v2.getY()), + Math.min(getZ(), v2.getZ()) ); } @@ -582,10 +553,10 @@ public class Vector3 { * @return maximum */ public Vector3 getMaximum(Vector3 v2) { - return new Vector3( - Math.max(x, v2.x), - Math.max(y, v2.y), - Math.max(z, v2.z) + return Vector3.at( + Math.max(getX(), v2.getX()), + Math.max(getY(), v2.getY()), + Math.max(getZ(), v2.getZ()) ); } @@ -607,7 +578,7 @@ public class Vector3 { * @return a new {@code BlockVector} */ public BlockVector3 toBlockPoint() { - return toBlockPoint(x, y, z); + return toBlockPoint(getX(), getY(), getZ()); } /** @@ -616,7 +587,7 @@ public class Vector3 { * @return a new {@link Vector2} */ public Vector2 toVector2() { - return Vector2.at(x, z); + return Vector2.at(getX(), getZ()); } @Override @@ -626,12 +597,12 @@ public class Vector3 { } Vector3 other = (Vector3) obj; - return other.x == this.x && other.y == this.y && other.z == this.z; + return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ(); } @Override public int hashCode() { - return (int) x ^ (int) z << 12 ^ (int) y << 24; + return (int) getX() ^ (int) getZ() << 12 ^ (int) getY() << 24; } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3Impl.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3Impl.java new file mode 100644 index 000000000..d2e81c185 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3Impl.java @@ -0,0 +1,30 @@ +package com.sk89q.worldedit.math; + +public class Vector3Impl extends Vector3 { + private final double x,y,z; + + public Vector3Impl(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3Impl(Vector3 other) { + this(other.getX(), other.getY(), other.getZ()); + } + + @Override + public final double getX() { + return x; + } + + @Override + public final double getY() { + return y; + } + + @Override + public final double getZ() { + return z; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java index d0de02102..d9d15008c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java @@ -42,6 +42,7 @@ public class KochanekBartelsInterpolation implements Interpolation { private Vector3[] coeffC; private Vector3[] coeffD; private double scaling; + private MutableBlockVector3 mutable = new MutableBlockVector3(); public KochanekBartelsInterpolation() { setNodes(Collections.emptyList()); @@ -136,8 +137,6 @@ public class KochanekBartelsInterpolation implements Interpolation { return nodes.get(index).getPosition(); } - private MutableBlockVector3 mutable = new MutableBlockVector3(); - @Override public Vector3 getPosition(double position) { if (coeffA == null) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 4c5800217..dcb3a469e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -546,7 +546,12 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { @Override public BlockVector2 next() { - if (!hasNext()) throw new NoSuchElementException(); + if (!hasNext()) throw new NoSuchElementException() { + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + }; BlockVector2 answer = BlockVector2.at(nextX, nextZ); if (++nextX > max.getBlockX()) { nextX = min.getBlockX(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/PasteBuilder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/PasteBuilder.java index f04810f45..0b08e7485 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/session/PasteBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/PasteBuilder.java @@ -21,7 +21,10 @@ package com.sk89q.worldedit.session; import static com.google.common.base.Preconditions.checkNotNull; +import com.boydti.fawe.util.MaskTraverser; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.transform.BlockTransformExtent; import com.sk89q.worldedit.function.RegionFunction; @@ -49,6 +52,7 @@ public class PasteBuilder { private boolean ignoreAirBlocks; private boolean copyEntities = true; // default because it used to be this way private boolean copyBiomes; + private RegionFunction canApply; /** * Create a new instance. @@ -125,6 +129,7 @@ public class PasteBuilder { return this; } public PasteBuilder filter(RegionFunction function) { + this.canApply = function; return this; } @@ -134,13 +139,33 @@ public class PasteBuilder { * @return the operation */ public Operation build() { - BlockTransformExtent extent = new BlockTransformExtent(clipboard, transform); + Extent extent = clipboard; + if (!transform.isIdentity()) { + extent = new BlockTransformExtent(extent, transform); + } ForwardExtentCopy copy = new ForwardExtentCopy(extent, clipboard.getRegion(), clipboard.getOrigin(), targetExtent, to); copy.setTransform(transform); + + copy.setCopyingEntities(copyEntities); + copy.setCopyingBiomes(copyBiomes && clipboard.hasBiomes()); + if (this.canApply != null) { + copy.setFilterFunction(this.canApply); + } if (ignoreAirBlocks) { - copy.setSourceMask(sourceMask == Masks.alwaysTrue() ? new ExistingBlockMask(clipboard) - : new MaskIntersection(sourceMask, new ExistingBlockMask(clipboard))); - } else { + sourceMask = MaskIntersection.of(sourceMask, new ExistingBlockMask(clipboard)); + } + if (targetExtent instanceof EditSession) { + Mask esSourceMask = ((EditSession) targetExtent).getSourceMask(); + if (esSourceMask == Masks.alwaysFalse()) { + return null; + } + if (esSourceMask != null) { + new MaskTraverser(esSourceMask).reset(extent); + ((EditSession) targetExtent).setSourceMask(null); + sourceMask = MaskIntersection.of(sourceMask, esSourceMask); + } + } + if (sourceMask != null && sourceMask != Masks.alwaysTrue()) { copy.setSourceMask(sourceMask); } copy.setCopyingEntities(copyEntities); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java index d7a4e2bc5..8088f8cfd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java @@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.Vector3; +import com.sk89q.worldedit.math.Vector3Impl; /** * Represents a location in a world with has a direction. @@ -35,7 +36,7 @@ import com.sk89q.worldedit.math.Vector3; * {@link #equals(Object)} are subject to minor differences caused by * floating point errors.

*/ -public class Location extends Vector3 { +public class Location extends Vector3Impl { private final Extent extent; private final float pitch; @@ -294,11 +295,11 @@ public class Location extends Vector3 { @Override public Location clampY(int min, int max) { checkArgument(min <= max, "minimum cannot be greater than maximum"); - if (y < min) { - return new Location(extent, x, min, z); + if (getY() < min) { + return new Location(extent, getX(), min, getZ()); } - if (y > max) { - return new Location(extent, x, max, z); + if (getY() > max) { + return new Location(extent, getX(), max, getZ()); } return this; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index d35c640d4..3c6073e11 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -137,7 +137,7 @@ public class BlockType implements FawePattern, Keyed { * @return the properties */ public List> getProperties() { - return ImmutableList.copyOf(this.getPropertyMap().values()); + return this.settings.propertiesList; // stop changing this } @Deprecated