summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/bukkit/event/inventory/ClickType.java115
-rw-r--r--src/main/java/org/bukkit/event/inventory/CraftItemEvent.java12
-rw-r--r--src/main/java/org/bukkit/event/inventory/DragType.java18
-rw-r--r--src/main/java/org/bukkit/event/inventory/InventoryAction.java90
-rw-r--r--src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java204
-rw-r--r--src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java27
-rw-r--r--src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java164
-rw-r--r--src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java78
8 files changed, 648 insertions, 60 deletions
diff --git a/src/main/java/org/bukkit/event/inventory/ClickType.java b/src/main/java/org/bukkit/event/inventory/ClickType.java
new file mode 100644
index 00000000..dc2928cc
--- /dev/null
+++ b/src/main/java/org/bukkit/event/inventory/ClickType.java
@@ -0,0 +1,115 @@
+package org.bukkit.event.inventory;
+
+/**
+ * What the client did to trigger this action (not the result).
+ */
+public enum ClickType {
+ /**
+ * The left (or primary) mouse button.
+ */
+ LEFT,
+ /**
+ * Holding shift while pressing the left mouse button.
+ */
+ SHIFT_LEFT,
+ /**
+ * The right mouse button.
+ */
+ RIGHT,
+ /**
+ * Holding shift while pressing the right mouse button.
+ */
+ SHIFT_RIGHT,
+ /**
+ * Clicking the left mouse button on the grey area around the
+ * inventory.
+ */
+ WINDOW_BORDER_LEFT,
+ /**
+ * Clicking the right mouse button on the grey area around the
+ * inventory.
+ */
+ WINDOW_BORDER_RIGHT,
+ /**
+ * The middle mouse button, or a "scrollwheel click".
+ */
+ MIDDLE,
+ /**
+ * One of the number keys 1-9, correspond to slots on the hotbar.
+ */
+ NUMBER_KEY,
+ /**
+ * Pressing the left mouse button twice in quick succession.
+ */
+ DOUBLE_CLICK,
+ /**
+ * The "Drop" key (defaults to Q).
+ */
+ DROP,
+ /**
+ * Holding Ctrl while pressing the "Drop" key (defaults to Q).
+ */
+ CONTROL_DROP,
+ /**
+ * Any action done with the Creative inventory open.
+ */
+ CREATIVE,
+ /**
+ * A type of inventory manipulation not yet recognized by Bukkit.
+ * This is only for transitional purposes on a new Minecraft update,
+ * and should never be relied upon.
+ * <p>
+ * Any ClickType.UNKNOWN is called on a best-effort basis.
+ */
+ UNKNOWN,
+ ;
+
+ /**
+ * Gets whether this ClickType represents the pressing of a key on a
+ * keyboard.
+ *
+ * @return true if this ClickType represents the pressing of a key
+ */
+ public boolean isKeyboardClick() {
+ return (this == ClickType.NUMBER_KEY) || (this == ClickType.DROP) || (this == ClickType.CONTROL_DROP);
+ }
+
+ /**
+ * Gets whether this ClickType represents an action that can only be
+ * performed by a Player in creative mode.
+ *
+ * @return true if this action requires Creative mode
+ */
+ public boolean isCreativeAction() {
+ // Why use middle click?
+ return (this == ClickType.MIDDLE) || (this == ClickType.CREATIVE);
+ }
+
+ /**
+ * Gets whether this ClickType represents a right click.
+ *
+ * @return true if this ClickType represents a right click
+ */
+ public boolean isRightClick() {
+ return (this == ClickType.RIGHT) || (this == ClickType.SHIFT_RIGHT);
+ }
+
+ /**
+ * Gets whether this ClickType represents a left click.
+ *
+ * @return true if this ClickType represents a left click
+ */
+ public boolean isLeftClick() {
+ return (this == ClickType.LEFT) || (this == ClickType.SHIFT_LEFT) || (this == ClickType.DOUBLE_CLICK) || (this == ClickType.CREATIVE);
+ }
+
+ /**
+ * Gets whether this ClickType indicates that the shift key was pressed
+ * down when the click was made.
+ *
+ * @return true if the action uses Shift.
+ */
+ public boolean isShiftClick() {
+ return (this == ClickType.SHIFT_LEFT) || (this == ClickType.SHIFT_RIGHT) || (this == ClickType.CONTROL_DROP);
+ }
+}
diff --git a/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java b/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java
index 264ab0a9..4ebc36bd 100644
--- a/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java
+++ b/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java
@@ -8,8 +8,18 @@ import org.bukkit.inventory.Recipe;
public class CraftItemEvent extends InventoryClickEvent {
private Recipe recipe;
+ @Deprecated
public CraftItemEvent(Recipe recipe, InventoryView what, SlotType type, int slot, boolean right, boolean shift) {
- super(what, type, slot, right, shift);
+ this(recipe, what, type, slot, right ? (shift ? ClickType.SHIFT_RIGHT : ClickType.RIGHT) : (shift ? ClickType.SHIFT_LEFT : ClickType.LEFT), InventoryAction.PICKUP_ALL);
+ }
+
+ public CraftItemEvent(Recipe recipe, InventoryView what, SlotType type, int slot, ClickType click, InventoryAction action) {
+ super(what, type, slot, click, action);
+ this.recipe = recipe;
+ }
+
+ public CraftItemEvent(Recipe recipe, InventoryView what, SlotType type, int slot, ClickType click, InventoryAction action, int key) {
+ super(what, type, slot, click, action, key);
this.recipe = recipe;
}
diff --git a/src/main/java/org/bukkit/event/inventory/DragType.java b/src/main/java/org/bukkit/event/inventory/DragType.java
new file mode 100644
index 00000000..9000faf1
--- /dev/null
+++ b/src/main/java/org/bukkit/event/inventory/DragType.java
@@ -0,0 +1,18 @@
+package org.bukkit.event.inventory;
+
+/**
+ * Represents the effect of a drag that will be applied to an Inventory in an
+ * InventoryDragEvent.
+ */
+public enum DragType {
+ /**
+ * One item from the cursor is placed in each selected slot.
+ */
+ SINGLE,
+ /**
+ * The cursor is split evenly across all selected slots, not to
+ * exceed the Material's max stack size, with the remainder going to
+ * the cursor.
+ */
+ EVEN,
+}
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryAction.java b/src/main/java/org/bukkit/event/inventory/InventoryAction.java
new file mode 100644
index 00000000..c9da0222
--- /dev/null
+++ b/src/main/java/org/bukkit/event/inventory/InventoryAction.java
@@ -0,0 +1,90 @@
+package org.bukkit.event.inventory;
+
+/**
+ * An estimation of what the result will be.
+ */
+public enum InventoryAction {
+ /**
+ * Nothing will happen from the click.
+ * There may be cases where nothing will happen and this is value is
+ * not provided, but it is guaranteed that this value is accurate
+ * when given.
+ */
+ NOTHING,
+ /**
+ * All of the items on the clicked slot are moved to the cursor.
+ */
+ PICKUP_ALL,
+ /**
+ * Some of the items on the clicked slot are moved to the cursor.
+ */
+ PICKUP_SOME,
+ /**
+ * Half of the items on the clicked slot are moved to the cursor.
+ */
+ PICKUP_HALF,
+ /**
+ * One of the items on the clicked slot are moved to the cursor.
+ */
+ PICKUP_ONE,
+ /**
+ * All of the items on the cursor are moved to the clicked slot.
+ */
+ PLACE_ALL,
+ /**
+ * Some of the items from the cursor are moved to the clicked slot
+ * (usually up to the max stack size).
+ */
+ PLACE_SOME,
+ /**
+ * A single item from the cursor is moved to the clicked slot.
+ */
+ PLACE_ONE,
+ /**
+ * The clicked item and the cursor are exchanged.
+ */
+ SWAP_WITH_CURSOR,
+ /**
+ * The entire cursor item is dropped.
+ */
+ DROP_ALL_CURSOR,
+ /**
+ * One item is dropped from the cursor.
+ */
+ DROP_ONE_CURSOR,
+ /**
+ * The entire clicked slot is dropped.
+ */
+ DROP_ALL_SLOT,
+ /**
+ * One item is dropped from the clicked slot.
+ */
+ DROP_ONE_SLOT,
+ /**
+ * The item is moved to the opposite inventory if a space is found.
+ */
+ MOVE_TO_OTHER_INVENTORY,
+ /**
+ * The clicked item is moved to the hotbar, and the item currently
+ * there is re-added to the player's inventory.
+ */
+ HOTBAR_MOVE_AND_READD,
+ /**
+ * The clicked slot and the picked hotbar slot are swapped.
+ */
+ HOTBAR_SWAP,
+ /**
+ * A max-size stack of the clicked item is put on the cursor.
+ */
+ CLONE_STACK,
+ /**
+ * The inventory is searched for the same material, and they are put
+ * on the cursor up to {@link org.bukkit.Material#getMaxStackSize()}.
+ */
+ COLLECT_TO_CURSOR,
+ /**
+ * An unrecognized ClickType.
+ */
+ UNKNOWN,
+ ;
+}
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
index 26e1d382..28198b8b 100644
--- a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
+++ b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
@@ -3,133 +3,219 @@ package org.bukkit.event.inventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.entity.HumanEntity;
-import org.bukkit.event.Cancellable;
+import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.InventoryType.SlotType;
+import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
-
-public class InventoryClickEvent extends InventoryEvent implements Cancellable {
+import org.bukkit.scheduler.BukkitScheduler;
+import org.bukkit.plugin.Plugin;
+
+/**
+ * This event is called when a player clicks a slot in an inventory.
+ * <p>
+ * Because InventoryClickEvent occurs within a modification of the Inventory,
+ * not all Inventory related methods are safe to use.
+ * <p>
+ * The following should never be invoked by an EventHandler for
+ * InventoryClickEvent using the HumanEntity or InventoryView associated with
+ * this event:
+ * <ul>
+ * <li>{@link HumanEntity#closeInventory()}
+ * <li>{@link HumanEntity#openInventory(Inventory)}
+ * <li>{@link HumanEntity#openWorkbench(Location, boolean)}
+ * <li>{@link HumanEntity#openEnchanting(Location, boolean)}
+ * <li>{@link InventoryView#close()}
+ * </ul>
+ * To invoke one of these methods, schedule a task using
+ * {@link BukkitScheduler#runTask(Plugin, Runnable)}, which will run the task
+ * on the next tick. Also be aware that this is not an exhaustive list, and
+ * other methods could potentially create issues as well.
+ * <p>
+ * Assuming the EntityHuman associated with this event is an instance of a
+ * Player, manipulating the MaxStackSize or contents of an Inventory will
+ * require an Invocation of {@link Player#updateInventory()}.
+ * <p>
+ * Modifications to slots that are modified by the results of this
+ * InventoryClickEvent can be overwritten. To change these slots, this event
+ * should be cancelled and all desired changes to the inventory applied.
+ * Alternatively, scheduling a task using {@link BukkitScheduler#runTask(
+ * Plugin, Runnable)}, which would execute the task on the next tick, would
+ * work as well.
+ */
+public class InventoryClickEvent extends InventoryInteractEvent {
private static final HandlerList handlers = new HandlerList();
+ private final ClickType click;
+ private final InventoryAction action;
private SlotType slot_type;
- private boolean rightClick, shiftClick;
- private Result result;
private int whichSlot;
private int rawSlot;
private ItemStack current = null;
+ private int hotbarKey = -1;
+
+ @Deprecated
+ public InventoryClickEvent(InventoryView view, SlotType type, int slot, boolean right, boolean shift) {
+ this(view, type, slot, right ? (shift ? ClickType.SHIFT_RIGHT : ClickType.RIGHT) : (shift ? ClickType.SHIFT_LEFT : ClickType.LEFT), InventoryAction.SWAP_WITH_CURSOR);
+ }
- public InventoryClickEvent(InventoryView what, SlotType type, int slot, boolean right, boolean shift) {
- super(what);
+ public InventoryClickEvent(InventoryView view, SlotType type, int slot, ClickType click, InventoryAction action) {
+ super(view);
this.slot_type = type;
- this.rightClick = right;
- this.shiftClick = shift;
- this.result = Result.DEFAULT;
this.rawSlot = slot;
- this.whichSlot = what.convertSlot(slot);
+ this.whichSlot = view.convertSlot(slot);
+ this.click = click;
+ this.action = action;
+ }
+
+ public InventoryClickEvent(InventoryView view, SlotType type, int slot, ClickType click, InventoryAction action, int key) {
+ this(view, type, slot, click, action);
+ this.hotbarKey = key;
}
/**
- * Get the type of slot that was clicked.
- * @return The slot type.
+ * Gets the type of slot that was clicked.
+ *
+ * @return the slot type
*/
public SlotType getSlotType() {
return slot_type;
}
/**
- * Get the current item on the cursor.
- * @return The cursor item
+ * Gets the current ItemStack on the cursor.
+ *
+ * @return the cursor ItemStack
*/
public ItemStack getCursor() {
return getView().getCursor();
}
/**
- * Get the current item in the clicked slot.
- * @return The slot item.
+ * Gets the ItemStack currently in the clicked slot.
+ *
+ * @return the item in the clicked
*/
public ItemStack getCurrentItem() {
- if(slot_type == SlotType.OUTSIDE) return current;
+ if (slot_type == SlotType.OUTSIDE) {
+ return current;
+ }
return getView().getItem(rawSlot);
}
/**
- * @return True if the click is a right-click.
+ * Gets whether or not the ClickType for this event represents a right
+ * click.
+ *
+ * @return true if the ClickType uses the right mouse button.
+ * @see ClickType#isRightClick()
*/
public boolean isRightClick() {
- return rightClick;
+ return click.isRightClick();
}
/**
- * @return True if the click is a left-click.
+ * Gets whether or not the ClickType for this event represents a left
+ * click.
+ *
+ * @return true if the ClickType uses the left mouse button.
+ * @see ClickType#isLeftClick()
*/
public boolean isLeftClick() {
- return !rightClick;
+ return click.isLeftClick();
}
/**
- * Shift can be combined with right-click or left-click as a modifier.
- * @return True if the click is a shift-click.
+ * Gets whether the ClickType for this event indicates that the key was
+ * pressed down when the click was made.
+ *
+ * @return true if the ClickType uses Shift or Ctrl.
+ * @see ClickType#isShiftClick()
*/
public boolean isShiftClick() {
- return shiftClick;
- }
-
- public void setResult(Result newResult) {
- result = newResult;
- }
-
- public Result getResult() {
- return result;
+ return click.isShiftClick();
}
/**
- * Get the player who performed the click.
- * @return The clicking player.
+ * Sets the item on the cursor.
+ *
+ * @param stack the new cursor item
+ * @deprecated This changes the ItemStack in their hand before any
+ * calculations are applied to the Inventory, which has a tendency to
+ * create inconsistencies between the Player and the server, and to
+ * make unexpected changes in the behavior of the clicked Inventory.
*/
- public HumanEntity getWhoClicked() {
- return getView().getPlayer();
+ @Deprecated
+ public void setCursor(ItemStack stack) {
+ getView().setCursor(stack);
}
/**
- * Set the item on the cursor.
- * @param what The new cursor item.
+ * Sets the ItemStack currently in the clicked slot.
+ *
+ * @param stack the item to be placed in the current slot
*/
- public void setCursor(ItemStack what) {
- getView().setCursor(what);
+ public void setCurrentItem(ItemStack stack) {
+ if (slot_type == SlotType.OUTSIDE) {
+ current = stack;
+ } else {
+ getView().setItem(rawSlot, stack);
+ }
}
/**
- * Set the current item in the slot.
- * @param what The new slot item.
+ * The slot number that was clicked, ready for passing to
+ * {@link Inventory#getItem(int)}. Note that there may be two slots with
+ * the same slot number, since a view links two different inventories.
+ *
+ * @return The slot number.
*/
- public void setCurrentItem(ItemStack what) {
- if(slot_type == SlotType.OUTSIDE) current = what;
- else getView().setItem(rawSlot, what);
+ public int getSlot() {
+ return whichSlot;
}
- public boolean isCancelled() {
- return result == Result.DENY;
+ /**
+ * The raw slot number clicked, ready for passing to {@link InventoryView
+ * #getItem(int)} This slot number is unique for the view.
+ *
+ * @return the slot number
+ */
+ public int getRawSlot() {
+ return rawSlot;
}
- public void setCancelled(boolean toCancel) {
- result = toCancel ? Result.DENY : Result.ALLOW;
+ /**
+ * If the ClickType is NUMBER_KEY, this method will return the index of
+ * the pressed key (0-8).
+ *
+ * @return the number on the key minus 1 (range 0-8); or -1 if not
+ * a NUMBER_KEY action
+ */
+ public int getHotbarButton() {
+ return hotbarKey;
}
/**
- * The slot number that was clicked, ready for passing to {@link Inventory#getItem(int)}. Note
- * that there may be two slots with the same slot number, since a view links two different inventories.
- * @return The slot number.
+ * Gets the InventoryAction that triggered this event.
+ * <p>
+ * This action cannot be changed, and represents what the normal outcome
+ * of the event will be. To change the behavior of this
+ * InventoryClickEvent, changes must be manually applied.
+ *
+ * @return the InventoryAction that triggered this event.
*/
- public int getSlot() {
- return whichSlot;
+ public InventoryAction getAction() {
+ return action;
}
/**
- * The raw slot number, which is unique for the view.
- * @return The slot number.
+ * Gets the ClickType for this event.
+ * <p>
+ * This is insulated against changes to the inventory by other plugins.
+ *
+ * @return the type of inventory click
*/
- public int getRawSlot() {
- return rawSlot;
+ public ClickType getClick() {
+ return click;
}
@Override
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java
new file mode 100644
index 00000000..da7dffc0
--- /dev/null
+++ b/src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java
@@ -0,0 +1,27 @@
+package org.bukkit.event.inventory;
+
+import org.bukkit.event.inventory.InventoryType.SlotType;
+import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.ItemStack;
+
+/**
+ * This event is called when a player in creative mode puts down or picks up
+ * an item in their inventory / hotbar and when they drop items from their
+ * Inventory while in creative mode.
+ */
+public class InventoryCreativeEvent extends InventoryClickEvent {
+ private ItemStack item;
+
+ public InventoryCreativeEvent(InventoryView what, SlotType type, int slot, ItemStack newItem) {
+ super(what, type, slot, ClickType.CREATIVE, InventoryAction.PLACE_ALL);
+ this.item = newItem;
+ }
+
+ public ItemStack getCursor() {
+ return item;
+ }
+
+ public void setCursor(ItemStack item) {
+ this.item = item;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java
new file mode 100644
index 00000000..e7e54a75
--- /dev/null
+++ b/src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java
@@ -0,0 +1,164 @@
+package org.bukkit.event.inventory;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.Validate;
+import org.bukkit.Location;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.scheduler.BukkitScheduler;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This event is called when the player drags an item in their cursor across
+ * the inventory. The ItemStack is distributed across the slots the
+ * HumanEntity dragged over. The method of distribution is described by the
+ * DragType returned by {@link #getType()}.
+ * <p>
+ * Canceling this event will result in none of the changes described in
+ * {@link #getNewItems()} being applied to the Inventory.
+ * <p>
+ * Because InventoryDragEvent occurs within a modification of the Inventory,
+ * not all Inventory related methods are safe to use.
+ * <p>
+ * The following should never be invoked by an EventHandler for
+ * InventoryDragEvent using the HumanEntity or InventoryView associated with
+ * this event.
+ * <ul>
+ * <li>{@link HumanEntity#closeInventory()}
+ * <li>{@link HumanEntity#openInventory(Inventory)}
+ * <li>{@link HumanEntity#openWorkbench(Location, boolean)}
+ * <li>{@link HumanEntity#openEnchanting(Location, boolean)}
+ * <li>{@link InventoryView#close()}
+ * </ul>
+ * To invoke one of these methods, schedule a task using
+ * {@link BukkitScheduler#runTask(Plugin, Runnable)}, which will run the task
+ * on the next tick. Also be aware that this is not an exhaustive list, and
+ * other methods could potentially create issues as well.
+ * <p>
+ * Assuming the EntityHuman associated with this event is an instance of a
+ * Player, manipulating the MaxStackSize or contents of an Inventory will
+ * require an Invocation of {@link Player#updateInventory()}.
+ * <p>
+ * Any modifications to slots that are modified by the results of this
+ * InventoryDragEvent will be overwritten. To change these slots, this event
+ * should be cancelled and the changes applied. Alternatively, scheduling a
+ * task using {@link BukkitScheduler#runTask(Plugin, Runnable)}, which would
+ * execute the task on the next tick, would work as well.
+ */
+public class InventoryDragEvent extends InventoryInteractEvent {
+ private static final HandlerList handlers = new HandlerList();
+ private final DragType type;
+ private final Map<Integer, ItemStack> addedItems;
+ private final Set<Integer> containerSlots;
+ private final ItemStack oldCursor;
+ private ItemStack newCursor;
+
+ public InventoryDragEvent(InventoryView what, ItemStack newCursor, ItemStack oldCursor, boolean right, Map<Integer, ItemStack> slots) {
+ super(what);
+
+ Validate.notNull(oldCursor);
+ Validate.notNull(slots);
+
+ type = right ? DragType.SINGLE : DragType.EVEN;
+ this.newCursor = newCursor;
+ this.oldCursor = oldCursor;
+ this.addedItems = slots;
+ ImmutableSet.Builder<Integer> b = ImmutableSet.builder();
+ for (Integer slot : slots.keySet()) {
+ b.add(what.convertSlot(slot));
+ }
+ this.containerSlots = b.build();
+ }
+
+ /**
+ * Gets all items to be added to the inventory in this drag.
+ *
+ * @return map from raw slot id to new ItemStack
+ */
+ public Map<Integer, ItemStack> getNewItems() {
+ return Collections.unmodifiableMap(addedItems);
+ }
+
+ /**
+ * Gets the raw slot ids to be changed in this drag.
+ *
+ * @return list of raw slot ids, suitable for getView().getItem(int)
+ */
+ public Set<Integer> getRawSlots() {
+ return addedItems.keySet();
+ }
+
+ /**
+ * Gets the slots to be changed in this drag.
+ *
+ * @return list of converted slot ids, suitable for {@link
+ * org.bukkit.inventory.Inventory#getItem(int)}.
+ */
+ public Set<Integer> getInventorySlots() {
+ return containerSlots;
+ }
+
+ /**
+ * Gets the result cursor after the drag is done. The returned value is
+ * mutable.
+ *
+ * @return the result cursor
+ */
+ public ItemStack getCursor() {
+ return newCursor;
+ }
+
+ /**
+ * Sets the result cursor after the drag is done.
+ * <p>
+ * Changing this item stack changes the cursor item. Note that changing
+ * the affected "dragged" slots does not change this ItemStack, nor does
+ * changing this ItemStack affect the "dragged" slots.
+ *
+ * @param newCursor the new cursor ItemStack
+ */
+ public void setCursor(ItemStack newCursor) {
+ this.newCursor = newCursor;
+ }
+
+ /**
+ * Gets an ItemStack representing the cursor prior to any modifications
+ * as a result of this drag.
+ *
+ * @return the original cursor
+ */
+ public ItemStack getOldCursor() {
+ return oldCursor.clone();
+ }
+
+ /**
+ * Gets the DragType that describes the behavior of ItemStacks placed
+ * after this InventoryDragEvent.
+ * <p>
+ * The ItemStacks and the raw slots that they're being applied to can be
+ * found using {@link #getNewItems()}.
+ *
+ * @return the DragType of this InventoryDragEvent
+ */
+ public DragType getType() {
+ return type;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java
new file mode 100644
index 00000000..8624f8d7
--- /dev/null
+++ b/src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java
@@ -0,0 +1,78 @@
+package org.bukkit.event.inventory;
+
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event.Result;
+import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.ItemStack;
+
+/**
+ * An abstract base class for events that describe an interaction between a
+ * HumanEntity and the contents of an Inventory.
+ */
+public abstract class InventoryInteractEvent extends InventoryEvent implements Cancellable {
+ private Result result = Result.DEFAULT;
+
+ public InventoryInteractEvent(InventoryView transaction) {
+ super(transaction);
+ }
+
+ /**
+ * Gets the player who performed the click.
+ *
+ * @return The clicking player.
+ */
+ public HumanEntity getWhoClicked() {
+ return getView().getPlayer();
+ }
+
+ /**
+ * Sets the result of this event. This will change whether or not this
+ * event is considered cancelled.
+ *
+ * @see #isCancelled()
+ * @param newResult the new {@link Result} for this event
+ */
+ public void setResult(Result newResult) {
+ result = newResult;
+ }
+
+ /**
+ * Gets the {@link Result} of this event. The Result describes the
+ * behavior that will be applied to the inventory in relation to this
+ * event.
+ *
+ * @return the Result of this event.
+ */
+ public Result getResult() {
+ return result;
+ }
+
+ /**
+ * Gets whether or not this event is cancelled. This is based off of the
+ * Result value returned by {@link #getResult()}. Result.ALLOW and
+ * Result.DEFAULT will result in a returned value of false, but
+ * Result.DENY will result in a returned value of true.
+ * <p>
+ * {@inheritDoc}
+ *
+ * @return whether the event is cancelled
+ */
+ public boolean isCancelled() {
+ return getResult() == Result.DENY;
+ }
+
+ /**
+ * Proxy method to {@link #setResult(Event.Result)} for the Cancellable
+ * interface. {@link #setResult(Event.Result)} is preferred, as it allows
+ * you to specify the Result beyond Result.DENY and Result.ALLOW.
+ * <p>
+ * {@inheritDoc}
+ *
+ * @param toCancel result becomes DENY if true, ALLOW if false
+ */
+ public void setCancelled(boolean toCancel) {
+ setResult(toCancel ? Result.DENY : Result.ALLOW);
+ }
+
+}