diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditListener.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditListener.java
index fbb335543..50e7f9e37 100644
--- a/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditListener.java
+++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/WorldEditListener.java
@@ -125,7 +125,7 @@ public class WorldEditListener implements Listener {
Action action = event.getAction();
if (action == Action.LEFT_CLICK_BLOCK) {
final Block clickedBlock = event.getClickedBlock();
- final WorldVector pos = new WorldVector(LocalWorldAdapter.wrap(world), clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
+ final WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
if (we.handleBlockLeftClick(player, pos)) {
event.setCancelled(true);
@@ -159,7 +159,7 @@ public class WorldEditListener implements Listener {
} else if (action == Action.RIGHT_CLICK_BLOCK) {
final Block clickedBlock = event.getClickedBlock();
- final WorldVector pos = new WorldVector(LocalWorldAdapter.wrap(world), clickedBlock.getX(),
+ final WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), clickedBlock.getX(),
clickedBlock.getY(), clickedBlock.getZ());
if (we.handleBlockRightClick(player, pos)) {
diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java
index 01e178f71..a3d441385 100644
--- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java
+++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java
@@ -59,7 +59,7 @@ public class ForgePlayer extends LocalPlayer {
}
public WorldVector getPosition() {
- return new WorldVector(LocalWorldAdapter.wrap(ForgeWorldEdit.inst.getWorld(this.player.worldObj)), this.player.posX, this.player.posY, this.player.posZ);
+ return new WorldVector(LocalWorldAdapter.adapt(ForgeWorldEdit.inst.getWorld(this.player.worldObj)), this.player.posX, this.player.posY, this.player.posZ);
}
public com.sk89q.worldedit.world.World getWorld() {
diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java
index 283e99a97..1b1b7f621 100644
--- a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java
+++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java
@@ -137,7 +137,7 @@ public class ForgeWorldEdit {
Action action = event.action;
switch (action) {
case LEFT_CLICK_BLOCK: {
- WorldVector pos = new WorldVector(LocalWorldAdapter.wrap(world), event.x, event.y, event.z);
+ WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), event.x, event.y, event.z);
if (we.handleBlockLeftClick(player, pos)) {
event.setCanceled(true);
@@ -148,7 +148,7 @@ public class ForgeWorldEdit {
}
}
case RIGHT_CLICK_BLOCK: {
- WorldVector pos = new WorldVector(LocalWorldAdapter.wrap(world), event.x, event.y, event.z);
+ WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), event.x, event.y, event.z);
if (we.handleBlockRightClick(player, pos)) {
event.setCanceled(true);
diff --git a/src/main/java/com/sk89q/worldedit/WorldEdit.java b/src/main/java/com/sk89q/worldedit/WorldEdit.java
index cf137bb4d..f38966c90 100644
--- a/src/main/java/com/sk89q/worldedit/WorldEdit.java
+++ b/src/main/java/com/sk89q/worldedit/WorldEdit.java
@@ -24,6 +24,7 @@ import com.sk89q.worldedit.CuboidClipboard.FlipDirection;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.command.tool.*;
+import com.sk89q.worldedit.event.actor.BlockInteractEvent;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.extension.input.ParserContext;
@@ -55,6 +56,7 @@ import java.util.Set;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.sk89q.worldedit.event.actor.InteractionType.PRIMARY_INPUT;
/**
* The entry point and container for a working implementation of WorldEdit.
@@ -831,41 +833,9 @@ public class WorldEdit {
* @return false if you want the action to go through
*/
public boolean handleBlockLeftClick(LocalPlayer player, WorldVector clicked) {
- LocalSession session = getSession(player);
-
- if (player.getItemInHand() == getConfiguration().wandItem) {
- if (!session.isToolControlEnabled()) {
- return false;
- }
-
- if (!player.hasPermission("worldedit.selection.pos")) {
- return false;
- }
-
- RegionSelector selector = session.getRegionSelector(player.getWorld());
- if (selector.selectPrimary(clicked)) {
- selector.explainPrimarySelection(player, session, clicked);
- }
-
- return true;
- }
-
- if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
- final BlockTool superPickaxe = session.getSuperPickaxe();
- if (superPickaxe != null && superPickaxe.canUse(player)) {
- return superPickaxe.actPrimary(getServer(), getConfiguration(), player, session, clicked);
- }
- }
-
- Tool tool = session.getTool(player.getItemInHand());
- if (tool != null && tool instanceof DoubleActionBlockTool) {
- if (tool.canUse(player)) {
- ((DoubleActionBlockTool) tool).actSecondary(getServer(), getConfiguration(), player, session, clicked);
- return true;
- }
- }
-
- return false;
+ BlockInteractEvent event = new BlockInteractEvent(player, clicked.toLocation(), PRIMARY_INPUT);
+ getEventBus().post(event);
+ return event.isCancelled();
}
/**
diff --git a/src/main/java/com/sk89q/worldedit/WorldVector.java b/src/main/java/com/sk89q/worldedit/WorldVector.java
index 2e901f823..5e3d12b2e 100644
--- a/src/main/java/com/sk89q/worldedit/WorldVector.java
+++ b/src/main/java/com/sk89q/worldedit/WorldVector.java
@@ -19,6 +19,8 @@
package com.sk89q.worldedit;
+import com.sk89q.worldedit.internal.LocalWorldAdapter;
+
/**
* @deprecated Use {@link com.sk89q.worldedit.util.Location} wherever possible
*/
@@ -81,14 +83,23 @@ public class WorldVector extends Vector {
/**
* Construct the Vector object.
- *
- * @param world
+ *
+ * @param world
*/
public WorldVector(LocalWorld world) {
super();
this.world = world;
}
+ /**
+ * Construct the Vector object.
+ *
+ * @param location the location
+ */
+ public WorldVector(com.sk89q.worldedit.util.Location location) {
+ this(LocalWorldAdapter.adapt(location.getWorld()), location.getX(), location.getY(), location.getZ());
+ }
+
/**
* Get the world.
*
@@ -122,4 +133,15 @@ public class WorldVector extends Vector {
public BlockWorldVector toWorldBlockVector() {
return new BlockWorldVector(this);
}
+
+ /**
+ * Return this object as a new preferred Location
+ * object.
+ *
+ * @return a new location object
+ */
+ public com.sk89q.worldedit.util.Location toLocation() {
+ return new com.sk89q.worldedit.util.Location(getWorld(), this);
+ }
+
}
diff --git a/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java
index fe1811c02..d72dc333b 100644
--- a/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java
+++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/SmoothBrush.java
@@ -46,7 +46,7 @@ public class SmoothBrush implements Brush {
public void build(EditSession editSession, Vector pos, Pattern mat, double size) throws MaxChangedBlocksException {
double rad = size;
- WorldVector min = new WorldVector(LocalWorldAdapter.wrap(editSession.getWorld()), pos.subtract(rad, rad, rad));
+ WorldVector min = new WorldVector(LocalWorldAdapter.adapt(editSession.getWorld()), pos.subtract(rad, rad, rad));
Vector max = pos.add(rad, rad + 10, rad);
Region region = new CuboidRegion(editSession.getWorld(), min, max);
HeightMap heightMap = new HeightMap(editSession, region, naturalOnly);
diff --git a/src/main/java/com/sk89q/worldedit/event/actor/BlockInteractEvent.java b/src/main/java/com/sk89q/worldedit/event/actor/BlockInteractEvent.java
new file mode 100644
index 000000000..cec761cdd
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/event/actor/BlockInteractEvent.java
@@ -0,0 +1,91 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.event.actor;
+
+import com.sk89q.worldedit.event.Cancellable;
+import com.sk89q.worldedit.event.Event;
+import com.sk89q.worldedit.extension.platform.Actor;
+import com.sk89q.worldedit.util.Location;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Called when a block is interacted with.
+ */
+public class BlockInteractEvent extends Event implements Cancellable {
+
+ private final Actor cause;
+ private final Location location;
+ private final InteractionType type;
+ private boolean cancelled;
+
+ /**
+ * Create a new event.
+ *
+ * @param cause the causing actor
+ * @param location the location of the block
+ * @param type the type of interaction
+ */
+ public BlockInteractEvent(Actor cause, Location location, InteractionType type) {
+ checkNotNull(cause);
+ checkNotNull(location);
+ checkNotNull(type);
+ this.cause = cause;
+ this.location = location;
+ this.type = type;
+ }
+
+ /**
+ * Get the cause of this event.
+ *
+ * @return the cause
+ */
+ public Actor getCause() {
+ return cause;
+ }
+
+ /**
+ * Get the location of the block that was interacted with.
+ *
+ * @return the location
+ */
+ public Location getLocation() {
+ return location;
+ }
+
+ /**
+ * Get the type of interaction.
+ *
+ * @return the type of interaction
+ */
+ public InteractionType getType() {
+ return type;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+}
diff --git a/src/main/java/com/sk89q/worldedit/event/actor/InteractionType.java b/src/main/java/com/sk89q/worldedit/event/actor/InteractionType.java
new file mode 100644
index 000000000..f965de7c1
--- /dev/null
+++ b/src/main/java/com/sk89q/worldedit/event/actor/InteractionType.java
@@ -0,0 +1,36 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.event.actor;
+
+/**
+ * The type of interaction.
+ */
+public enum InteractionType {
+
+ /**
+ * Refers to primary input usage (left click).
+ */
+ PRIMARY_INPUT,
+
+ /**
+ * Refers to secondary input usage (right click).
+ */
+ SECONDARY_INPUT
+}
diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
index 5f10187ee..e6843853e 100644
--- a/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
+++ b/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
@@ -19,9 +19,16 @@
package com.sk89q.worldedit.extension.platform;
-import com.sk89q.worldedit.LocalConfiguration;
-import com.sk89q.worldedit.ServerInterface;
-import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.command.tool.BlockTool;
+import com.sk89q.worldedit.command.tool.DoubleActionBlockTool;
+import com.sk89q.worldedit.command.tool.Tool;
+import com.sk89q.worldedit.entity.Player;
+import com.sk89q.worldedit.event.actor.BlockInteractEvent;
+import com.sk89q.worldedit.internal.ServerInterfaceAdapter;
+import com.sk89q.worldedit.regions.RegionSelector;
+import com.sk89q.worldedit.util.Location;
+import com.sk89q.worldedit.util.eventbus.Subscribe;
import javax.annotation.Nullable;
import java.util.ArrayList;
@@ -43,6 +50,7 @@ public class PlatformManager {
private final LocalConfiguration defaultConfig = new DefaultConfiguration();
private final List platforms = new ArrayList();
+ private final WorldEdit worldEdit;
private final CommandManager commandManager;
private @Nullable Platform primary = null;
@@ -53,7 +61,11 @@ public class PlatformManager {
*/
public PlatformManager(WorldEdit worldEdit) {
checkNotNull(worldEdit);
+ this.worldEdit = worldEdit;
this.commandManager = new CommandManager(worldEdit);
+
+ // Register this instance for events
+ worldEdit.getEventBus().register(this);
}
/**
@@ -182,13 +194,66 @@ public class PlatformManager {
if (platform instanceof ServerInterface) {
return (ServerInterface) platform;
} else {
- return new ServerInterfaceAdapter(platform);
+ return ServerInterfaceAdapter.adapt(platform);
}
} else {
throw new IllegalStateException("No platform has been registered");
}
}
+ @Subscribe
+ public void handleBlockInteract(BlockInteractEvent event) {
+ Actor actor = event.getCause();
+ Location location = event.getLocation();
+ Vector vector = location.toVector();
+
+ // At this time, only handle interaction from players
+ if (actor instanceof Player) {
+ Player player = (Player) actor;
+ LocalSession session = worldEdit.getSessionManager().get(actor);
+
+ if (player.getItemInHand() == getConfiguration().wandItem) {
+ if (!session.isToolControlEnabled()) {
+ return;
+ }
+
+ if (!actor.hasPermission("worldedit.selection.pos")) {
+ return;
+ }
+
+ RegionSelector selector = session.getRegionSelector(player.getWorld());
+
+ if (selector.selectPrimary(location.toVector())) {
+ selector.explainPrimarySelection(actor, session, vector);
+ }
+
+ event.setCancelled(true);
+ return;
+ }
+
+ if (player instanceof LocalPlayer) { // Temporary workaround
+ LocalPlayer localPlayer = (LocalPlayer) player;
+ WorldVector worldVector = new WorldVector(location);
+
+ if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
+ final BlockTool superPickaxe = session.getSuperPickaxe();
+ if (superPickaxe != null && superPickaxe.canUse(localPlayer)) {
+ event.setCancelled(superPickaxe.actPrimary(getServerInterface(), getConfiguration(), localPlayer, session, worldVector));
+ return;
+ }
+ }
+
+ Tool tool = session.getTool(player.getItemInHand());
+ if (tool != null && tool instanceof DoubleActionBlockTool) {
+ if (tool.canUse(localPlayer)) {
+ ((DoubleActionBlockTool) tool).actSecondary(getServerInterface(), getConfiguration(), localPlayer, session, worldVector);
+ event.setCancelled(true);
+ }
+ }
+ }
+ }
+ }
+
/**
* A default configuration for when none is set.
*/
diff --git a/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java b/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java
index 3e061de36..ea509acc3 100644
--- a/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java
+++ b/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java
@@ -309,7 +309,7 @@ public class LocalWorldAdapter extends LocalWorld {
return world.commit();
}
- public static LocalWorldAdapter wrap(World world) {
+ public static LocalWorldAdapter adapt(World world) {
return new LocalWorldAdapter(world);
}
diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/ServerInterfaceAdapter.java b/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java
similarity index 84%
rename from src/main/java/com/sk89q/worldedit/extension/platform/ServerInterfaceAdapter.java
rename to src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java
index 5f1bd80f4..fa71a403a 100644
--- a/src/main/java/com/sk89q/worldedit/extension/platform/ServerInterfaceAdapter.java
+++ b/src/main/java/com/sk89q/worldedit/internal/ServerInterfaceAdapter.java
@@ -17,11 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.extension.platform;
+package com.sk89q.worldedit.internal;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandsManager;
import com.sk89q.worldedit.*;
+import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.world.World;
import java.util.List;
@@ -31,7 +32,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* Adapts {@link Platform}s into the legacy {@link ServerInterface}.
*/
-class ServerInterfaceAdapter extends ServerInterface {
+public class ServerInterfaceAdapter extends ServerInterface {
private final Platform platform;
@@ -40,7 +41,7 @@ class ServerInterfaceAdapter extends ServerInterface {
*
* @param platform the platform
*/
- ServerInterfaceAdapter(Platform platform) {
+ private ServerInterfaceAdapter(Platform platform) {
checkNotNull(platform);
this.platform = platform;
}
@@ -106,4 +107,14 @@ class ServerInterfaceAdapter extends ServerInterface {
return platform.getPlatformVersion();
}
+ /**
+ * Adapt an {@link Platform} instance into a {@link ServerInterface}.
+ *
+ * @param platform the platform
+ * @return the server interface
+ */
+ public static ServerInterface adapt(Platform platform) {
+ return new ServerInterfaceAdapter(platform);
+ }
+
}
diff --git a/src/main/java/com/sk89q/worldedit/util/TargetBlock.java b/src/main/java/com/sk89q/worldedit/util/TargetBlock.java
index 700dce3f8..2d62e8b37 100644
--- a/src/main/java/com/sk89q/worldedit/util/TargetBlock.java
+++ b/src/main/java/com/sk89q/worldedit/util/TargetBlock.java
@@ -49,7 +49,7 @@ public class TargetBlock {
* @param player player to work with
*/
public TargetBlock(LocalPlayer player) {
- this.world = LocalWorldAdapter.wrap(player.getWorld());
+ this.world = LocalWorldAdapter.adapt(player.getWorld());
this.setValues(player.getPosition(), player.getYaw(), player.getPitch(),
300, 1.65, 0.2);
}
@@ -73,7 +73,7 @@ public class TargetBlock {
* @param checkDistance how often to check for blocks, the smaller the more precise
*/
public TargetBlock(Entity player, int maxDistance, double checkDistance) {
- this.world = LocalWorldAdapter.wrap(player.getWorld());
+ this.world = LocalWorldAdapter.adapt(player.getWorld());
this.setValues(player.getPosition(), player.getYaw(), player.getPitch(),
maxDistance, 1.65, checkDistance);
}