Skip to content

Commit

Permalink
Make the selection wand and navigation wand normal tools.
Browse files Browse the repository at this point in the history
This means users can bind and unbind them to any item, like other tools.
By default, the items in config will be automatically bound. After
setting a different item via `//selwand` or `//navwand`, that item will
subsequently be used for that user.

Also various other tool-related cleanup.
  • Loading branch information
wizjany committed Jun 27, 2019
1 parent 2347fdf commit 1598e97
Show file tree
Hide file tree
Showing 21 changed files with 378 additions and 186 deletions.
51 changes: 35 additions & 16 deletions worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
Expand Up @@ -28,6 +28,8 @@
import com.sk89q.worldedit.command.tool.BlockTool;
import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.command.tool.InvalidToolBindException;
import com.sk89q.worldedit.command.tool.NavigationWand;
import com.sk89q.worldedit.command.tool.SelectionWand;
import com.sk89q.worldedit.command.tool.SinglePickaxe;
import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.entity.Player;
Expand All @@ -48,7 +50,6 @@
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.snapshot.Snapshot;

import javax.annotation.Nullable;
Expand All @@ -67,11 +68,11 @@
*/
public class LocalSession {

public transient static int MAX_HISTORY_SIZE = 15;
public static transient int MAX_HISTORY_SIZE = 15;

// Non-session related fields
private transient LocalConfiguration config;
private transient final AtomicBoolean dirty = new AtomicBoolean();
private final transient AtomicBoolean dirty = new AtomicBoolean();
private transient int failedCuiAttempts = 0;

// Session related
Expand All @@ -80,7 +81,6 @@ public class LocalSession {
private transient LinkedList<EditSession> history = new LinkedList<>();
private transient int historyPointer = 0;
private transient ClipboardHolder clipboard;
private transient boolean toolControl = true;
private transient boolean superPickaxe = false;
private transient BlockTool pickaxeMode = new SinglePickaxe();
private transient Map<ItemType, Tool> tools = new HashMap<>();
Expand All @@ -100,6 +100,8 @@ public class LocalSession {
private String lastScript;
private RegionSelectorType defaultSelector;
private boolean useServerCUI = false; // Save this to not annoy players.
private String wandItem;
private String navWandItem;

/**
* Construct the object.
Expand Down Expand Up @@ -387,21 +389,20 @@ public void setClipboard(@Nullable ClipboardHolder clipboard) {
}

/**
* See if tool control is enabled.
*
* @return true if enabled
* @return true always - see deprecation notice
* @deprecated The wand is now a tool that can be bound/unbound.
*/
@Deprecated
public boolean isToolControlEnabled() {
return toolControl;
return true;
}

/**
* Change tool control setting.
*
* @param toolControl true to enable tool control
* @param toolControl unused - see deprecation notice
* @deprecated The wand is now a tool that can be bound/unbound.
*/
@Deprecated
public void setToolControl(boolean toolControl) {
this.toolControl = toolControl;
}

/**
Expand Down Expand Up @@ -594,10 +595,13 @@ public BrushTool getBrushTool(ItemType item) throws InvalidToolBindException {
public void setTool(ItemType item, @Nullable Tool tool) throws InvalidToolBindException {
if (item.hasBlockType()) {
throw new InvalidToolBindException(item, "Blocks can't be used");
} else if (item == ItemTypes.get(config.wandItem)) {
throw new InvalidToolBindException(item, "Already used for the wand");
} else if (item == ItemTypes.get(config.navigationWand)) {
throw new InvalidToolBindException(item, "Already used for the navigation wand");
}
if (tool instanceof SelectionWand) {
this.wandItem = item.getId();
setDirty();
} else if (tool instanceof NavigationWand) {
this.navWandItem = item.getId();
setDirty();
}

this.tools.put(item, tool);
Expand Down Expand Up @@ -954,4 +958,19 @@ public void setMask(Mask mask) {
this.mask = mask;
}

/**
* Get the preferred wand item for this user, or {@code null} to use the default
* @return item id of wand item, or {@code null}
*/
public String getWandItem() {
return wandItem;
}

/**
* Get the preferred navigation wand item for this user, or {@code null} to use the default
* @return item id of nav wand item, or {@code null}
*/
public String getNavWandItem() {
return navWandItem;
}
}
Expand Up @@ -25,6 +25,7 @@
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.command.argument.SelectorChoice;
import com.sk89q.worldedit.command.tool.SelectionWand;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
import com.sk89q.worldedit.command.util.Logging;
Expand Down Expand Up @@ -56,9 +57,13 @@
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
import com.sk89q.worldedit.util.formatting.component.SubtleFormat;
import com.sk89q.worldedit.util.formatting.component.TextComponentProducer;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.storage.ChunkStore;
import org.enginehub.piston.annotation.Command;
Expand Down Expand Up @@ -246,24 +251,36 @@ public void chunk(Player player, LocalSession session,
desc = "Get the wand object"
)
@CommandPermissions("worldedit.wand")
public void wand(Player player) throws WorldEditException {
player.giveItem(new BaseItemStack(ItemTypes.get(we.getConfiguration().wandItem), 1));
public void wand(Player player, LocalSession session) throws WorldEditException {
String wandId = session.getWandItem();
if (wandId == null) {
wandId = we.getConfiguration().wandItem;
}
ItemType itemType = ItemTypes.get(wandId);
if (itemType == null) {
player.printError("Wand item is mis-configured or disabled.");
return;
}
session.setTool(itemType, new SelectionWand());
player.giveItem(new BaseItemStack(itemType, 1));
player.print("Left click: select pos #1; Right click: select pos #2");
}

@Command(
name = "toggleeditwand",
desc = "Toggle functionality of the edit wand"
desc = "Remind the user that the wand is now a tool and can be unbound with /none."
)
@CommandPermissions("worldedit.wand.toggle")
public void toggleWand(Player player, LocalSession session) throws WorldEditException {
session.setToolControl(!session.isToolControlEnabled());

if (session.isToolControlEnabled()) {
player.print("Edit wand enabled.");
} else {
player.print("Edit wand disabled.");
}
public void toggleWand(Player player) {
player.print(TextComponent.of("The selection wand is now a normal tool. You can disable it with ")
.append(TextComponent.of("/none", TextColor.AQUA).clickEvent(
ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "/none")))
.append(TextComponent.of(" and rebind it to any item with "))
.append(TextComponent.of("//selwand", TextColor.AQUA).clickEvent(
ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "//selwand")))
.append(TextComponent.of(" or get a new wand with "))
.append(TextComponent.of("//wand", TextColor.AQUA).clickEvent(
ClickEvent.of(ClickEvent.Action.RUN_COMMAND, "//wand"))));
}

@Command(
Expand Down
Expand Up @@ -30,7 +30,9 @@
import com.sk89q.worldedit.command.tool.FloatingTreeRemover;
import com.sk89q.worldedit.command.tool.FloodFillTool;
import com.sk89q.worldedit.command.tool.LongRangeBuildTool;
import com.sk89q.worldedit.command.tool.NavigationWand;
import com.sk89q.worldedit.command.tool.QueryTool;
import com.sk89q.worldedit.command.tool.SelectionWand;
import com.sk89q.worldedit.command.tool.TreePlanter;
import com.sk89q.worldedit.command.util.CommandPermissions;
import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator;
Expand All @@ -39,6 +41,7 @@
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.item.ItemType;
import org.enginehub.piston.annotation.Command;
import org.enginehub.piston.annotation.CommandContainer;
import org.enginehub.piston.annotation.param.Arg;
Expand All @@ -61,6 +64,32 @@ public void none(Player player, LocalSession session) throws WorldEditException
player.print("Tool unbound from your current item.");
}

@Command(
name = "/selwand",
aliases = "selwand",
desc = "Selection wand tool"
)
@CommandPermissions("worldedit.selection.pos")
public void selwand(Player player, LocalSession session) throws WorldEditException {

final ItemType itemType = player.getItemInHand(HandSide.MAIN_HAND).getType();
session.setTool(itemType, new SelectionWand());
player.print("Selection wand bound to " + itemType.getName() + ".");
}

@Command(
name = "/navwand",
aliases = "navwand",
desc = "Navigation wand tool"
)
@CommandPermissions({"worldedit.command.jumpto.tool", "worldedit.command.thru.tool"})
public void navwand(Player player, LocalSession session) throws WorldEditException {

BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new NavigationWand());
player.print("Navigation wand bound to " + itemStack.getType().getName() + ".");
}

@Command(
name = "info",
desc = "Block information tool"
Expand All @@ -82,6 +111,7 @@ public void info(Player player, LocalSession session) throws WorldEditException
public void tree(Player player, LocalSession session,
@Arg(desc = "Type of tree to generate", def = "tree")
TreeGenerator.TreeType type) throws WorldEditException {

BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new TreePlanter(type));
player.print("Tree tool bound to " + itemStack.getType().getName() + ".");
Expand All @@ -95,6 +125,7 @@ public void tree(Player player, LocalSession session,
public void repl(Player player, LocalSession session,
@Arg(desc = "The pattern of blocks to place")
Pattern pattern) throws WorldEditException {

BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND);
session.setTool(itemStack.getType(), new BlockReplacer(pattern));
player.print("Block replacer tool bound to " + itemStack.getType().getName() + ".");
Expand Down
Expand Up @@ -27,6 +27,7 @@
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
Expand All @@ -48,18 +49,18 @@ public boolean canUse(Actor player) {
}

@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
int ox = clicked.getBlockX();
int oy = clicked.getBlockY();
int oz = clicked.getBlockZ();
BlockType initialType = clicked.getExtent().getBlock(clicked.toVector().toBlockPoint()).getBlockType();

if (initialType.getMaterial().isAir()) {
return true;
return false;
}

if (initialType == BlockTypes.BEDROCK && !player.canDestroyBedrock()) {
return true;
return false;
}

try (EditSession editSession = session.createEditSession(player)) {
Expand All @@ -74,9 +75,10 @@ public boolean actPrimary(Platform server, LocalConfiguration config, Player pla
continue;
}

((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType, clicked.toVector().toBlockPoint().distanceSq(pos));

editSession.setBlock(pos, BlockTypes.AIR.getDefaultState());

((World) clicked.getExtent()).queueBlockBreakEffect(server, pos, initialType,
clicked.toVector().toBlockPoint().distanceSq(pos));
}
}
}
Expand Down
Expand Up @@ -50,8 +50,8 @@ public boolean canUse(Actor player) {

private Map<UUID, Property<?>> selectedProperties = new HashMap<>();

private boolean handleCycle(Platform server, LocalConfiguration config,
Player player, LocalSession session, Location clicked, boolean forward) {
private boolean handleCycle(LocalConfiguration config, Player player, LocalSession session,
Location clicked, boolean forward) {

World world = (World) clicked.getExtent();

Expand Down Expand Up @@ -88,7 +88,7 @@ private boolean handleCycle(Platform server, LocalConfiguration config,

try {
editSession.setBlock(blockPoint, newBlock);
player.print("Value of " + currentProperty.getName() + " is now " + currentProperty.getValues().get(index).toString());
player.print("Value of " + currentProperty.getName() + " is now " + currentProperty.getValues().get(index));
} catch (MaxChangedBlocksException e) {
player.printError("Max blocks change limit reached.");
} finally {
Expand All @@ -110,12 +110,12 @@ private boolean handleCycle(Platform server, LocalConfiguration config,

@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
return handleCycle(server, config, player, session, clicked, true);
return handleCycle(config, player, session, clicked, true);
}

@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
return handleCycle(server, config, player, session, clicked, false);
return handleCycle(config, player, session, clicked, false);
}

}
Expand Up @@ -30,6 +30,7 @@
import com.sk89q.worldedit.function.pattern.BlockPattern;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.block.BlockState;

/**
Expand All @@ -49,7 +50,7 @@ public boolean canUse(Actor player) {
}

@Override
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
BlockBag bag = session.getBlockBag(player);

try (EditSession editSession = session.createEditSession(player)) {
Expand All @@ -72,7 +73,7 @@ public boolean actPrimary(Platform server, LocalConfiguration config, Player pla


@Override
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, com.sk89q.worldedit.util.Location clicked) {
public boolean actSecondary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked) {
BlockState targetBlock = player.getWorld().getBlock(clicked.toVector().toBlockPoint());

if (targetBlock != null) {
Expand Down
Expand Up @@ -27,5 +27,15 @@

public interface BlockTool extends Tool {

/**
* Perform the primary action of this tool.
*
* @param server
* @param config
* @param player
* @param session
* @param clicked
* @return true to cancel the original event which triggered this action (if possible)
*/
boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked);
}

0 comments on commit 1598e97

Please sign in to comment.