From daa4d22c6be8c2431fc86032190e73fce5eedf85 Mon Sep 17 00:00:00 2001 From: Maddy Miller Date: Thu, 23 Dec 2021 21:28:25 +1000 Subject: [PATCH] Add a //pos command to set multiple positions at once - API-breaking so blocked --- .../regions/selector/ActorRegionSelector.java | 12 + .../regions/selector/FuzzyRegionSelector.java | 39 ++- .../worldedit/command/SelectionCommands.java | 254 +++++++++--------- .../command/argument/EnumConverter.java | 8 - .../command/argument/SelectorChoice.java | 105 +++++++- .../argument/SelectorChoiceConverter.java | 60 +++++ .../command/argument/SelectorChoiceList.java | 27 ++ .../argument/SelectorChoiceOrList.java | 23 ++ .../platform/PlatformCommandManager.java | 2 + .../src/main/resources/lang/strings.json | 1 + 10 files changed, 379 insertions(+), 152 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/ActorRegionSelector.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceConverter.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceList.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceOrList.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/ActorRegionSelector.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/ActorRegionSelector.java new file mode 100644 index 000000000..ee532e267 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/ActorRegionSelector.java @@ -0,0 +1,12 @@ +package com.fastasyncworldedit.core.regions.selector; + +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.regions.RegionSelector; + +import javax.annotation.Nullable; + +public interface ActorRegionSelector extends RegionSelector { + + void setActor(@Nullable Actor actor); + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/FuzzyRegionSelector.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/FuzzyRegionSelector.java index 0ea04e976..8851fcefc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/FuzzyRegionSelector.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/selector/FuzzyRegionSelector.java @@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.regions.selector; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.extent.PassthroughExtent; +import com.fastasyncworldedit.core.function.mask.IdMask; import com.fastasyncworldedit.core.regions.FuzzyRegion; import com.fastasyncworldedit.core.util.ExtentTraverser; import com.fastasyncworldedit.core.util.MaskTraverser; @@ -23,11 +24,13 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; -public class FuzzyRegionSelector extends PassthroughExtent implements RegionSelector { +import static com.google.common.base.Preconditions.checkNotNull; + +public class FuzzyRegionSelector extends PassthroughExtent implements ActorRegionSelector { - private final Actor actor; - private FuzzyRegion region; private final ArrayList positions; + private Actor actor; + private FuzzyRegion region; public FuzzyRegionSelector(Actor actor, @Nullable World world, Mask mask) { super(WorldEdit.getInstance().newEditSessionBuilder().world(world) @@ -41,6 +44,30 @@ public class FuzzyRegionSelector extends PassthroughExtent implements RegionSele new MaskTraverser(mask).reset(getExtent()); } + public FuzzyRegionSelector(World world) { + super(WorldEdit.getInstance().newEditSessionBuilder().world(checkNotNull(world)) + .changeSetNull() + .checkMemory(false) + .build()); + this.actor = null; + Mask mask = new IdMask(world); + this.region = new FuzzyRegion(world, getExtent(), mask); + this.positions = new ArrayList<>(); + new MaskTraverser(mask).reset(getExtent()); + } + + public FuzzyRegionSelector(RegionSelector oldSelector) { + super(WorldEdit.getInstance().newEditSessionBuilder().world(checkNotNull(oldSelector).getWorld()) + .changeSetNull() + .checkMemory(false) + .build()); + this.actor = null; + Mask mask = new IdMask(oldSelector.getWorld()); + this.region = new FuzzyRegion(oldSelector.getWorld(), getExtent(), mask); + this.positions = new ArrayList<>(); + new MaskTraverser(mask).reset(getExtent()); + } + @Nullable @Override public World getWorld() { @@ -153,4 +180,10 @@ public class FuzzyRegionSelector extends PassthroughExtent implements RegionSele return positions; } + @Override + public void setActor(@Nullable Actor actor) { + this.actor = actor; + setWorld(getWorld()); // "reset" with actor + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index a248fae3b..654e134ac 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -21,9 +21,7 @@ package com.sk89q.worldedit.command; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder; -import com.fastasyncworldedit.core.function.mask.IdMask; -import com.fastasyncworldedit.core.regions.selector.FuzzyRegionSelector; -import com.fastasyncworldedit.core.regions.selector.PolyhedralRegionSelector; +import com.fastasyncworldedit.core.regions.selector.ActorRegionSelector; import com.fastasyncworldedit.core.util.MaskTraverser; import com.google.common.base.Strings; import com.sk89q.worldedit.EditSession; @@ -32,6 +30,7 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.command.argument.SelectorChoice; +import com.sk89q.worldedit.command.argument.SelectorChoiceOrList; import com.sk89q.worldedit.command.tool.NavigationWand; import com.sk89q.worldedit.command.tool.SelectionWand; import com.sk89q.worldedit.command.util.CommandPermissions; @@ -52,14 +51,9 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.regions.RegionSelector; -import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; -import com.sk89q.worldedit.regions.selector.CylinderRegionSelector; -import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector; import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector; -import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector; import com.sk89q.worldedit.regions.selector.RegionSelectorType; -import com.sk89q.worldedit.regions.selector.SphereRegionSelector; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.Location; @@ -86,10 +80,10 @@ import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.Switch; import org.enginehub.piston.exception.StopExecutionException; +import javax.annotation.Nullable; import java.io.File; import java.net.URI; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import static com.sk89q.worldedit.command.util.Logging.LogMode.POSITION; @@ -109,6 +103,66 @@ public class SelectionCommands { this.we = we; } + @Nullable + private BlockVector3 getLocatablePosition(Actor actor) { + if (actor instanceof Locatable locatable) { + return locatable.getLocation().toVector().toBlockPoint(); + } + actor.printError(Caption.of("worldedit.pos.console-require-coords")); + return null; + } + + @Command( + name = "/pos", + desc = "Set positions" + ) + @Logging(POSITION) + @CommandPermissions("worldedit.selection.pos") + public void pos(Actor actor, World world, LocalSession session, + @Arg(desc = "Coordinates to set the primary position to. Defaults to the player position if not passed.", def = "") + BlockVector3 pos1, + @Arg(desc = "Coordinates to add as secondary positions. Defaults to the player position if not passed.", def = "", variable = true) + List pos2, + @ArgFlag(name = 's', desc = "Selector to switch to") + SelectorChoice selectorChoice) throws WorldEditException { + if (pos1 == null) { + pos1 = getLocatablePosition(actor); + if (pos1 == null) { + return; + } + } + + if (pos2.isEmpty()) { + var newPos2 = getLocatablePosition(actor); + if (newPos2 == null) { + return; + } + pos2 = List.of(newPos2); + } + + RegionSelector regionSelector = session.getRegionSelector(world); + + if (selectorChoice != null) { + var newSelector = selectorChoice.createNewSelector(world); + session.setRegionSelector(world, newSelector); + selectorChoice.explainNewSelector(actor); + regionSelector = newSelector; + } + + regionSelector.selectPrimary(pos1, ActorSelectorLimits.forActor(actor)); + + for (BlockVector3 vector : pos2) { + regionSelector.selectSecondary(vector, ActorSelectorLimits.forActor(actor)); + } + + session.dispatchCUISelection(actor); + + for (Component line : regionSelector.getSelectionInfoLines()) { + actor.printInfo(line); + } + actor.printInfo(Caption.of("worldedit.selection.updated")); + } + @Command( name = "/pos1", aliases = "/1", @@ -117,29 +171,29 @@ public class SelectionCommands { @Logging(POSITION) @CommandPermissions("worldedit.selection.pos") public void pos1( - Actor actor, World world, LocalSession session, - @Arg(desc = "Coordinates to set position 1 to", def = "") - BlockVector3 coordinates - ) throws WorldEditException { - Location pos; - //FAWE start - clamp - if (coordinates != null) { - pos = new Location(world, coordinates.toVector3().clampY(world.getMinY(), world.getMaxY())); - } else if (actor instanceof Locatable) { - pos = ((Locatable) actor).getBlockLocation().clampY(world.getMinY(), world.getMaxY()); + Actor actor, + World world, + LocalSession session, + @Arg(desc = "Coordinates to set position 1 to", def = "") BlockVector3 coordinates + ) { + if (coordinates == null) { + //FAWE start - clamp + coordinates = getLocatablePosition(actor).clampY(world.getMinY(), world.getMaxY()); //FAWE end + if (coordinates == null) { + return; + } + //FAWE start - clamp } else { - actor.print(Caption.of("worldedit.pos.console-require-coords")); - return; + coordinates = coordinates.clampY(world.getMinY(), world.getMaxY()); } - if (!session.getRegionSelector(world).selectPrimary(pos.toVector().toBlockPoint(), ActorSelectorLimits.forActor(actor))) { + if (!session.getRegionSelector(world).selectPrimary(coordinates, ActorSelectorLimits.forActor(actor))) { actor.print(Caption.of("worldedit.pos.already-set")); return; } - session.getRegionSelector(world) - .explainPrimarySelection(actor, session, pos.toVector().toBlockPoint()); + session.getRegionSelector(world).explainPrimarySelection(actor, session, coordinates); } @Command( @@ -150,32 +204,28 @@ public class SelectionCommands { @Logging(POSITION) @CommandPermissions("worldedit.selection.pos") public void pos2( - Actor actor, World world, LocalSession session, - @Arg(desc = "Coordinates to set position 2 to", def = "") - BlockVector3 coordinates - ) throws WorldEditException { - Location pos; - if (coordinates != null) { + Actor actor, World world, LocalSession session, @Arg(desc = "Coordinates to set position 2 to", def = "") + BlockVector3 coordinates + ) { + if (coordinates == null) { + //FAWE start - clamp + coordinates = getLocatablePosition(actor).clampY(world.getMinY(), world.getMaxY()); + //FAWE end + if (coordinates == null) { + return; + } //FAWE start - clamp - pos = new Location(world, coordinates.toVector3().clampY(world.getMinY(), world.getMaxY())); - } else if (actor instanceof Locatable) { - pos = ((Locatable) actor).getBlockLocation().clampY(world.getMinY(), world.getMaxY()); - //Fawe end } else { - actor.print(Caption.of("worldedit.pos.console-require-coords")); - return; + coordinates = coordinates.clampY(world.getMinY(), world.getMaxY()); } - if (!session.getRegionSelector(world).selectSecondary( - pos.toVector().toBlockPoint(), - ActorSelectorLimits.forActor(actor) - )) { + + if (!session.getRegionSelector(world).selectSecondary(coordinates, ActorSelectorLimits.forActor(actor))) { actor.print(Caption.of("worldedit.pos.already-set")); return; } - session.getRegionSelector(world) - .explainSecondarySelection(actor, session, pos.toVector().toBlockPoint()); + session.getRegionSelector(world).explainSecondarySelection(actor, session, coordinates); } @Command( @@ -183,7 +233,7 @@ public class SelectionCommands { desc = "Set position 1 to targeted block" ) @CommandPermissions("worldedit.selection.hpos") - public void hpos1(Player player, LocalSession session) throws WorldEditException { + public void hpos1(Player player, LocalSession session) { Location pos = player.getBlockTrace(300); @@ -208,7 +258,7 @@ public class SelectionCommands { desc = "Set position 2 to targeted block" ) @CommandPermissions("worldedit.selection.hpos") - public void hpos2(Player player, LocalSession session) throws WorldEditException { + public void hpos2(Player player, LocalSession session) { Location pos = player.getBlockTrace(300); @@ -647,102 +697,52 @@ public class SelectionCommands { public void select( Actor actor, World world, LocalSession session, @Arg(desc = "Selector to switch to", def = "") - SelectorChoice selector, + SelectorChoiceOrList selectorChoiceOrList, + //FAWE start - more selections than allowed per page + @Arg(desc = "Selection list page", def = "1") + int page, + //FAWE end @Switch(name = 'd', desc = "Set default selector") boolean setDefaultSelector ) throws WorldEditException { - if (selector == null) { + if (selectorChoiceOrList == null) { session.getRegionSelector(world).clear(); session.dispatchCUISelection(actor); actor.print(Caption.of("worldedit.select.cleared")); return; } + if (!(selectorChoiceOrList instanceof SelectorChoice selectorChoice)) { + CommandListBox box = new CommandListBox("Selection modes", null, null); + box.setHidingHelp(true); + TextComponentProducer contents = box.getContents(); + contents.append(SubtleFormat.wrap("Select one of the modes below:")).newline(); + box.appendCommand("cuboid", Caption.of("worldedit.select.cuboid.description"), "//sel cuboid"); + box.appendCommand("extend", Caption.of("worldedit.select.extend.description"), "//sel extend"); + box.appendCommand("poly", Caption.of("worldedit.select.poly.description"), "//sel poly"); + box.appendCommand("ellipsoid", Caption.of("worldedit.select.ellipsoid.description"), "//sel ellipsoid"); + box.appendCommand("sphere", Caption.of("worldedit.select.sphere.description"), "//sel sphere"); + box.appendCommand("cyl", Caption.of("worldedit.select.cyl.description"), "//sel cyl"); + box.appendCommand("convex", Caption.of("worldedit.select.convex.description"), "//sel convex"); + //FAWE start + box.appendCommand("magic", Caption.of("fawe.selection.sel.fuzzy-instruction"), "//sel magic"); + box.appendCommand("fuzzy", Caption.of("fawe.selection.sel.fuzzy-instruction"), "//sel fuzzy"); + box.appendCommand("polyhedral", Caption.of("worldedit.select.convex.description"), "//sel polyhedral"); + actor.print(box.create(page)); + //FAWE end + return; + } + final RegionSelector oldSelector = session.getRegionSelector(world); - final RegionSelector newSelector; - switch (selector) { - case CUBOID: - newSelector = new CuboidRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.cuboid.message")); - break; - case EXTEND: - newSelector = new ExtendingCuboidRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.extend.message")); - break; - case POLY: { - newSelector = new Polygonal2DRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.poly.message")); - Optional limit = ActorSelectorLimits.forActor(actor).getPolygonVertexLimit(); - limit.ifPresent(integer -> actor.print(Caption.of( - "worldedit.select.poly.limit-message", - TextComponent.of(integer) - ))); - break; - } - case ELLIPSOID: - newSelector = new EllipsoidRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.ellipsoid.message")); - break; - case SPHERE: - newSelector = new SphereRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.sphere.message")); - break; - case CYL: - newSelector = new CylinderRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.cyl.message")); - break; - case CONVEX: - case HULL: - case POLYHEDRON: { - newSelector = new ConvexPolyhedralRegionSelector(oldSelector); - actor.print(Caption.of("worldedit.select.convex.message")); - Optional limit = ActorSelectorLimits.forActor(actor).getPolyhedronVertexLimit(); - limit.ifPresent(integer -> actor.print(Caption.of( - "worldedit.select.convex.limit-message", - TextComponent.of(integer) - ))); - break; - } - //FAWE start - case POLYHEDRAL: - newSelector = new PolyhedralRegionSelector(world); - actor.print(Caption.of("fawe.selection.sel.convex.polyhedral")); - Optional limit = ActorSelectorLimits.forActor(actor).getPolyhedronVertexLimit(); - limit.ifPresent(integer -> actor.print(Caption.of("fawe.selection.sel.max", integer))); - actor.print(Caption.of("fawe.selection.sel.list")); - break; - case FUZZY: - case MAGIC: - Mask maskOpt = new IdMask(world); - newSelector = new FuzzyRegionSelector(actor, world, maskOpt); - actor.print(Caption.of("fawe.selection.sel.fuzzy")); - actor.print(Caption.of("fawe.selection.sel.list")); - break; - //FAWE end - case LIST: - default: - CommandListBox box = new CommandListBox("Selection modes", null, null); - box.setHidingHelp(true); - TextComponentProducer contents = box.getContents(); - contents.append(SubtleFormat.wrap("Select one of the modes below:")).newline(); + final RegionSelector newSelector = selectorChoice.createNewSelector(oldSelector); + selectorChoice.explainNewSelector(actor); - box.appendCommand("cuboid", Caption.of("worldedit.select.cuboid.description"), "//sel cuboid"); - box.appendCommand("extend", Caption.of("worldedit.select.extend.description"), "//sel extend"); - box.appendCommand("poly", Caption.of("worldedit.select.poly.description"), "//sel poly"); - box.appendCommand("ellipsoid", Caption.of("worldedit.select.ellipsoid.description"), "//sel ellipsoid"); - box.appendCommand("sphere", Caption.of("worldedit.select.sphere.description"), "//sel sphere"); - box.appendCommand("cyl", Caption.of("worldedit.select.cyl.description"), "//sel cyl"); - box.appendCommand("convex", Caption.of("worldedit.select.convex.description"), "//sel convex"); - //FAWE start - box.appendCommand("polyhedral", Caption.of("fawe.selection.sel.polyhedral"), "//sel polyhedral"); - box.appendCommand("fuzzy[=]", Caption.of("fawe.selection.sel.fuzzy-instruction"), "//sel fuzzy[=]"); - box.setComponentsPerPage(box.getComponentsSize()); - //FAWE end - - actor.print(box.create(1)); - return; + //FAWE start - simple way of adding actors where required + if (newSelector instanceof ActorRegionSelector) { + ((ActorRegionSelector) newSelector).setActor(actor); } + //FAWE end if (setDefaultSelector) { RegionSelectorType found = null; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java index 7efe31b4b..79c6545eb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/EnumConverter.java @@ -40,10 +40,6 @@ import java.util.function.Function; public final class EnumConverter { public static void register(CommandManager commandManager) { - commandManager.registerConverter( - Key.of(SelectorChoice.class), - basic(SelectorChoice.class) - ); commandManager.registerConverter( Key.of(TreeGenerator.TreeType.class), full( @@ -86,10 +82,6 @@ public final class EnumConverter { return full(enumClass, e -> ImmutableSet.of(e.name().toLowerCase(Locale.ROOT)), null); } - private static > ArgumentConverter basic(Class enumClass, @Nullable E unknownValue) { - return full(enumClass, e -> ImmutableSet.of(e.name().toLowerCase(Locale.ROOT)), unknownValue); - } - private static > ArgumentConverter full( Class enumClass, Function> lookupKeys, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoice.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoice.java index 2b1dfec72..aeb566432 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoice.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoice.java @@ -19,20 +19,97 @@ package com.sk89q.worldedit.command.argument; -public enum SelectorChoice { - CUBOID, - EXTEND, - POLY, - ELLIPSOID, - SPHERE, - CYL, - CONVEX, - HULL, - POLYHEDRON, - LIST, +import com.fastasyncworldedit.core.regions.selector.FuzzyRegionSelector; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits; +import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.regions.selector.ConvexPolyhedralRegionSelector; +import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; +import com.sk89q.worldedit.regions.selector.CylinderRegionSelector; +import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector; +import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector; +import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector; +import com.sk89q.worldedit.regions.selector.SphereRegionSelector; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; +import com.sk89q.worldedit.world.World; + +import java.util.Optional; +import java.util.function.Function; + +public enum SelectorChoice implements SelectorChoiceOrList { + CUBOID(CuboidRegionSelector::new, CuboidRegionSelector::new, "worldedit.select.cuboid.message"), + EXTEND(ExtendingCuboidRegionSelector::new, ExtendingCuboidRegionSelector::new, "worldedit.select.extend.message"), + POLY(Polygonal2DRegionSelector::new, Polygonal2DRegionSelector::new, "worldedit.select.poly.message") { + @Override + public void explainNewSelector(Actor actor) { + super.explainNewSelector(actor); + Optional limit = ActorSelectorLimits.forActor(actor).getPolygonVertexLimit(); + limit.ifPresent(integer -> actor.printInfo(TranslatableComponent.of( + "worldedit.select.poly.limit-message", TextComponent.of(integer) + ))); + } + }, + ELLIPSOID(EllipsoidRegionSelector::new, EllipsoidRegionSelector::new, "worldedit.select.ellipsoid.message"), + SPHERE(SphereRegionSelector::new, SphereRegionSelector::new, "worldedit.select.sphere.message"), + CYL(CylinderRegionSelector::new, CylinderRegionSelector::new, "worldedit.select.cyl.message"), + CONVEX(ConvexPolyhedralRegionSelector::new, ConvexPolyhedralRegionSelector::new, "worldedit.select.convex.message") { + @Override + public void explainNewSelector(Actor actor) { + super.explainNewSelector(actor); + Optional limit = ActorSelectorLimits.forActor(actor).getPolyhedronVertexLimit(); + limit.ifPresent(integer -> actor.printInfo(TranslatableComponent.of( + "worldedit.select.convex.limit-message", TextComponent.of(integer) + ))); + } + }, //FAWE start - FUZZY, - MAGIC, - POLYHEDRAL + FUZZY(FuzzyRegionSelector::new, FuzzyRegionSelector::new, "fawe.selection.sel.fuzzy") { + @Override + public void explainNewSelector(Actor actor) { + super.explainNewSelector(actor); + Optional limit = ActorSelectorLimits.forActor(actor).getPolyhedronVertexLimit(); + limit.ifPresent(integer -> actor.printInfo(TranslatableComponent.of( + "worldedit.select.convex.limit-message", TextComponent.of(integer) + ))); + } + }, + MAGIC(FuzzyRegionSelector::new, FuzzyRegionSelector::new, "fawe.selection.sel.fuzzy"), + POLYHEDRAL(Polygonal2DRegionSelector::new, Polygonal2DRegionSelector::new, "fawe.selection.sel.convex.polyhedral") { + @Override + public void explainNewSelector(Actor actor) { + super.explainNewSelector(actor); + Optional limit = ActorSelectorLimits.forActor(actor).getPolyhedronVertexLimit(); + limit.ifPresent(integer -> actor.printInfo(TranslatableComponent.of( + "fawe.selection.sel.max", TextComponent.of(integer) + ))); + } + } //FAWE end + ; + + private final Function newFromWorld; + private final Function newFromOld; + private final Component messageComponent; + + SelectorChoice(Function newFromWorld, + Function newFromOld, + String message) { + this.newFromWorld = newFromWorld; + this.newFromOld = newFromOld; + this.messageComponent = TranslatableComponent.of(message); + } + + public RegionSelector createNewSelector(World world) { + return this.newFromWorld.apply(world); + } + + public RegionSelector createNewSelector(RegionSelector oldSelector) { + return this.newFromOld.apply(oldSelector); + } + + public void explainNewSelector(Actor actor) { + actor.printInfo(messageComponent); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceConverter.java new file mode 100644 index 000000000..24dc885ab --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceConverter.java @@ -0,0 +1,60 @@ +/* + * 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 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command.argument; + +import com.google.common.collect.ImmutableSetMultimap; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.SetMultimap; +import org.enginehub.piston.CommandManager; +import org.enginehub.piston.converter.ArgumentConverter; +import org.enginehub.piston.converter.MultiKeyConverter; +import org.enginehub.piston.inject.Key; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public class SelectorChoiceConverter { + public static void register(CommandManager commandManager) { + commandManager.registerConverter(Key.of(SelectorChoice.class), MultiKeyConverter.from(getBasicItems())); + commandManager.registerConverter(Key.of(SelectorChoiceOrList.class), orListConverter()); + } + + private static ArgumentConverter orListConverter() { + SetMultimap items = LinkedHashMultimap.create(getBasicItems()); + + items.put(SelectorChoiceList.INSTANCE, "list"); + + return MultiKeyConverter.from( + ImmutableSetMultimap.copyOf(items), + SelectorChoiceList.INSTANCE + ); + } + + @NotNull + private static SetMultimap getBasicItems() { + SetMultimap items = LinkedHashMultimap.create(); + for (var item : SelectorChoice.values()) { + items.put(item, item.name().toLowerCase(Locale.ROOT)); + } + items.put(SelectorChoice.CONVEX, "hull"); + items.put(SelectorChoice.CONVEX, "polyhedron"); + return items; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceList.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceList.java new file mode 100644 index 000000000..cad38771f --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceList.java @@ -0,0 +1,27 @@ +/* + * 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 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command.argument; + +public final class SelectorChoiceList implements SelectorChoiceOrList { + public static final SelectorChoiceList INSTANCE = new SelectorChoiceList(); + + private SelectorChoiceList() { + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceOrList.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceOrList.java new file mode 100644 index 000000000..066f90401 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/SelectorChoiceOrList.java @@ -0,0 +1,23 @@ +/* + * 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 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command.argument; + +public sealed interface SelectorChoiceOrList permits SelectorChoice, SelectorChoiceList { +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index 4c23e353d..1a92f9e00 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -98,6 +98,7 @@ import com.sk89q.worldedit.command.argument.LocationConverter; import com.sk89q.worldedit.command.argument.OffsetConverter; import com.sk89q.worldedit.command.argument.RegionFactoryConverter; import com.sk89q.worldedit.command.argument.RegistryConverter; +import com.sk89q.worldedit.command.argument.SelectorChoiceConverter; import com.sk89q.worldedit.command.argument.SideEffectConverter; import com.sk89q.worldedit.command.argument.VectorConverter; import com.sk89q.worldedit.command.argument.WorldConverter; @@ -272,6 +273,7 @@ public final class PlatformCommandManager { SideEffectConverter.register(commandManager); HeightConverter.register(commandManager); OffsetConverter.register(worldEdit, commandManager); + SelectorChoiceConverter.register(commandManager); //FAWE start commandManager.registerConverter( Key.of(com.sk89q.worldedit.function.pattern.Pattern.class, Annotations.patternList()), diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 6f4c5a737..33f3e64fa 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -597,6 +597,7 @@ "worldedit.selection.polygon2d.explain.secondary": "Added point #{0} at {1}.", "worldedit.selection.sphere.explain.secondary": "Radius set to {0}.", "worldedit.selection.sphere.explain.secondary-defined": "Radius set to {0} ({1}).", + "worldedit.selection.updated": "Positions updated.", "worldedit.sideeffect.lighting": "Lighting", "worldedit.sideeffect.lighting.description": "Updates block lighting", "worldedit.sideeffect.neighbors": "Neighbors",