diff --git a/src/main/java/ch/njol/skript/events/EvtClick.java b/src/main/java/ch/njol/skript/events/EvtClick.java index 9c580767793..6246e85bf48 100644 --- a/src/main/java/ch/njol/skript/events/EvtClick.java +++ b/src/main/java/ch/njol/skript/events/EvtClick.java @@ -38,6 +38,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.Skript; @@ -59,13 +60,19 @@ @SuppressWarnings("unchecked") public class EvtClick extends SkriptEvent { - // Important: a click on an entity fires both an PlayerInteractEntityEvent and a PlayerInteractEvent - // TheBukor: It only fires a PlayerInteractEntityEvent in 1.9, I guess. - - private final static boolean twoHanded = Skript.isRunningMinecraft(1, 9); + final static boolean twoHanded = Skript.isRunningMinecraft(1, 9); + /** + * Click types. + */ private final static int RIGHT = 1, LEFT = 2, ANY = RIGHT | LEFT; + /** + * If we used "holding" somewhere there, we must check if either hand + * contains the tool. + */ + private final static int HOLDING = 4; + static { Class clickEvent; if (twoHanded) // Armor stand support! @@ -73,11 +80,10 @@ public class EvtClick extends SkriptEvent { else clickEvent = PlayerInteractEntityEvent.class; - @SuppressWarnings("unchecked") Class[] eventTypes = CollectionUtils.array(PlayerInteractEvent.class, clickEvent); Skript.registerEvent("Click", EvtClick.class, eventTypes, - "[(" + RIGHT + "¦right|" + LEFT + "¦left)(| |-)][mouse(| |-)]click[ing] [on %-entitydata/itemtype%] [(with|using|holding) %itemtype%]", - "[(" + RIGHT + "¦right|" + LEFT + "¦left)(| |-)][mouse(| |-)]click[ing] (with|using|holding) %itemtype% on %entitydata/itemtype%") + "[(" + RIGHT + "¦right|" + LEFT + "¦left)(| |-)][mouse(| |-)]click[ing] [on %-entitydata/itemtype%] [(with|using|" + HOLDING + "¦holding) %itemtype%]", + "[(" + RIGHT + "¦right|" + LEFT + "¦left)(| |-)][mouse(| |-)]click[ing] (with|using|" + HOLDING + "¦holding) %itemtype% on %entitydata/itemtype%") .description("Called when a user clicks on a block, an entity or air with or without an item in their hand.", "Please note that rightclick events with an empty hand while not looking at a block are not sent to the server, so there's no way to detect them.") .examples("on click", @@ -94,10 +100,11 @@ public class EvtClick extends SkriptEvent { private Literal tools; private int click = ANY; + boolean isHolding = false; @Override public boolean init(final Literal[] args, final int matchedPattern, final ParseResult parser) { - //Skript.info("matchedPattern is " + matchedPattern); // TODO there is something wrong here... + //Skript.info("matchedPattern is " + matchedPattern); //Skript.info("args is " + Arrays.toString(args)); click = parser.mark == 0 ? ANY : parser.mark; types = args[matchedPattern]; @@ -110,6 +117,7 @@ public boolean init(final Literal[] args, final int matchedPattern, final Par } } tools = (Literal) args[1 - matchedPattern]; + isHolding = (parser.mark & HOLDING) != 0; // Check if third-least significant byte is 1 return true; } @@ -181,7 +189,12 @@ public boolean check(final Event e) { if (e instanceof PlayerInteractEvent && tools != null && !tools.check(e, new Checker() { @Override public boolean check(final ItemType t) { - return t.isOfType(((PlayerInteractEvent) e).getItem()); + if (isHolding && twoHanded) { + PlayerInventory invi = ((PlayerInteractEvent) e).getPlayer().getInventory(); + return t.isOfType(invi.getItemInMainHand()) || t.isOfType(invi.getItemInOffHand()); + } else { + return t.isOfType(((PlayerInteractEvent) e).getItem()); + } } })) { return false;