diff --git a/plugin/src/main/java/com/denizenscript/denizen/events/BukkitScriptEvent.java b/plugin/src/main/java/com/denizenscript/denizen/events/BukkitScriptEvent.java index b3718668cd..d857748d58 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/events/BukkitScriptEvent.java +++ b/plugin/src/main/java/com/denizenscript/denizen/events/BukkitScriptEvent.java @@ -28,6 +28,50 @@ public abstract class BukkitScriptEvent extends ScriptEvent { + public boolean couldMatchInArea(String lower) { + int index = CoreUtilities.split(lower, ' ').indexOf("in"); + if (index == -1) { + return true; + } + + String in = CoreUtilities.getXthArg(index + 1, lower); + if (InventoryTag.matches(in) || in.equalsIgnoreCase("inventory") || isRegexMatchable(in)) { + return false; + } + if (in.equalsIgnoreCase("notable")) { + String next = CoreUtilities.getXthArg(index + 2, lower); + if (!next.equalsIgnoreCase("cuboid") && !next.equalsIgnoreCase("ellipsoid")) { + return false; + } + } + return true; + } + + public boolean couldMatchInventory(String text) { + if (text.equals("inventory")) { + return true; + } + if (InventoryTag.matches(text)) { + return true; + } + if (CoreUtilities.contains(text, '*')) { + return true; + } + if (text.startsWith("regex:")) { + return true; + } + // This one must be last. + if (CoreUtilities.contains(text, '|')) { + for (String subMatch : text.split("\\|")) { + if (!couldMatchInventory(subMatch)) { + return false; + } + } + return true; + } + return false; + } + public boolean couldMatchItem(String text) { if (text.equals("item")) { return true; @@ -53,6 +97,25 @@ public boolean couldMatchItem(String text) { return false; } + public boolean nonSwitchWithCheck(ScriptPath path, ItemTag held) { + int index; + for (index = 0; index < path.eventArgsLower.length; index++) { + if (path.eventArgsLower[index].equals("with")) { + break; + } + } + if (index >= path.eventArgsLower.length) { + // No 'with ...' specified + return true; + } + + String with = path.eventArgLowerAt(index + 1); + if (with != null && (held == null || !tryItem(held, with))) { + return false; + } + return true; + } + public BukkitTagContext getTagContext(ScriptPath path) { BukkitTagContext context = (BukkitTagContext) getScriptEntryData().getTagContext(); context.script = new ScriptTag(path.container); diff --git a/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksBlockScriptEvent.java b/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksBlockScriptEvent.java index 7b281db685..644ef7e7c1 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksBlockScriptEvent.java +++ b/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksBlockScriptEvent.java @@ -7,7 +7,6 @@ import com.denizenscript.denizencore.objects.core.ElementTag; import com.denizenscript.denizencore.objects.ObjectTag; import com.denizenscript.denizencore.scripts.ScriptEntryData; -import com.denizenscript.denizencore.utilities.CoreUtilities; import org.bukkit.Material; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; @@ -23,13 +22,15 @@ public class PlayerClicksBlockScriptEvent extends BukkitScriptEvent implements L // <--[event] // @Events // player clicks block - // player (right/left) clicks () (with ) (using hand/off_hand/either_hand) - // player (right/left) clicks block (with ) (using hand/off_hand/either_hand) + // player (right/left) clicks () + // player (right/left) clicks block // // @Cancellable true // - // @Regex ^on player (((([^\s]+ )?clicks [^\s]+( with [^\s]+)?( in [^\s]+)?)))$ + // @Regex ^on player ([^\s]+ )?clicks [^\s]+$ // + // @Switch with: to only process the event if a specified item was held. + // @Switch using:hand/off_hand/either_hand to only process the event if the specified hand was used to click. // @Switch in: to only process the event if it occurred within a specified area. // // @Triggers when a player clicks on a block or in the air. @@ -57,38 +58,21 @@ public PlayerClicksBlockScriptEvent() { public ElementTag hand; public MaterialTag blockMaterial; - private boolean couldMatchIn(String lower) { - int index = CoreUtilities.split(lower, ' ').indexOf("in"); - if (index == -1) { - return true; - } - - String in = CoreUtilities.getXthArg(index + 1, lower); - if (InventoryTag.matches(in) || in.equalsIgnoreCase("inventory") || isRegexMatchable(in)) { - return false; - } - if (in.equalsIgnoreCase("notable")) { - String next = CoreUtilities.getXthArg(index + 2, lower); - if (!next.equalsIgnoreCase("cuboid") && !next.equalsIgnoreCase("ellipsoid")) { - return false; - } - } - return true; - } - private boolean runUsingCheck(ScriptPath path) { - int index; - for (index = 0; index < path.eventArgsLower.length; index++) { - if (path.eventArgsLower[index].equals("using")) { - break; + String using = path.switches.get("using"); + if (using == null) { + int index; + for (index = 0; index < path.eventArgsLower.length; index++) { + if (path.eventArgsLower[index].equals("using")) { + break; + } + } + if (index >= path.eventArgsLower.length) { + using = "hand"; + } + else { + using = path.eventArgLowerAt(index + 1); } - } - String using; - if (index >= path.eventArgsLower.length) { - using = "hand"; - } - else { - using = path.eventArgLowerAt(index + 1); } if (!using.equals("hand") && !using.equals("off_hand") && !using.equals("either_hand")) { Debug.echoError("Invalid USING hand in " + getName() + " for '" + path.event + "' in " + path.container.getName()); @@ -100,25 +84,6 @@ private boolean runUsingCheck(ScriptPath path) { return true; } - public boolean nonSwitchWithCheck(ScriptPath path, ItemTag held) { - int index; - for (index = 0; index < path.eventArgsLower.length; index++) { - if (path.eventArgsLower[index].equals("with")) { - break; - } - } - if (index >= path.eventArgsLower.length) { - // No 'with ...' specified - return true; - } - - String with = path.eventArgLowerAt(index + 1); - if (with != null && !tryItem(held, with)) { - return false; - } - return true; - } - private static final HashSet matchHelpList = new HashSet<>(Arrays.asList("at", "entity", "npc", "player", "vehicle", "projectile", "hanging", "fake")); @Override @@ -129,7 +94,7 @@ public boolean couldMatch(ScriptPath path) { || path.eventLower.startsWith("player right clicks") && !matchHelpList.contains(path.eventArgLowerAt(3)) && !EntityTag.matches(path.eventArgLowerAt(3)))) - && couldMatchIn(path.eventLower); // Avoid matching "clicks in inventory" + && couldMatchInArea(path.eventLower); // Avoid matching "clicks in inventory" } private static final HashSet withHelpList = new HashSet<>(Arrays.asList("with", "using", "in")); @@ -147,6 +112,9 @@ public boolean matches(ScriptPath path) { if (!nonSwitchWithCheck(path, new ItemTag(event.getItem()))) { return false; } + if (!runWithCheck(path, new ItemTag(event.getItem()))) { + return false; + } if (!runUsingCheck(path)) { return false; } diff --git a/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksInInventoryScriptEvent.java b/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksInInventoryScriptEvent.java index dd8fe95c86..1a598c2805 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksInInventoryScriptEvent.java +++ b/plugin/src/main/java/com/denizenscript/denizen/events/player/PlayerClicksInInventoryScriptEvent.java @@ -6,7 +6,6 @@ import com.denizenscript.denizencore.objects.ObjectTag; import com.denizenscript.denizencore.objects.core.ElementTag; import com.denizenscript.denizencore.scripts.ScriptEntryData; -import com.denizenscript.denizencore.utilities.CoreUtilities; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -14,6 +13,9 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; +import java.util.Arrays; +import java.util.HashSet; + public class PlayerClicksInInventoryScriptEvent extends BukkitScriptEvent implements Listener { // <--[language] @@ -69,9 +71,11 @@ public class PlayerClicksInInventoryScriptEvent extends BukkitScriptEvent implem // <--[event] // @Events // player clicks in inventory - // player () clicks () in (with ) + // player () clicks () in + // + // @Regex ^on player( [^\s]+)? clicks [^\s]+( in [^\s]+)?$ // - // @Regex ^on player( [^\s]+)? clicks [^\s]+( in [^\s]+)?( with [^\s]+)?$ + // @Switch with: to only process the event if a specified cursor item was used. // // @Triggers when a player clicks in an inventory. Note that you likely will also want to listen to <@link event player drags in inventory>. // @@ -107,6 +111,8 @@ public PlayerClicksInInventoryScriptEvent() { public ItemTag cursor; // Needed due to internal oddity public InventoryClickEvent event; + private static final HashSet matchHelpList = new HashSet<>(Arrays.asList("at", "entity", "npc", "player", "vehicle", "projectile", "hanging", "fake")); + @Override public boolean couldMatch(ScriptPath path) { if (!path.eventLower.startsWith("player")) { @@ -115,18 +121,29 @@ public boolean couldMatch(ScriptPath path) { if (!path.eventArgLowerAt(1).equals("clicks") && !path.eventArgLowerAt(2).equals("clicks")) { return false; } - for (String arg : path.eventArgsLower) { - if (arg.equals("in")) { - return true; + String clickedObj = path.eventArgLowerAt(3); + if (matchHelpList.contains(clickedObj)) { + return false; + } + int inIndex = -1; + for (int i = 0; i < path.eventArgsLower.length; i++) { + if (path.eventArgLowerAt(i).equals("in")) { + inIndex = i; } } - return false; + if (inIndex == -1) { + return false; + } + if (!couldMatchInventory(path.eventArgLowerAt(inIndex + 1))) { + return false; + } + return true; } @Override public boolean matches(ScriptPath path) { boolean hasClickType = path.eventArgLowerAt(2).equals("clicks"); - if (hasClickType && !path.eventArgLowerAt(1).equals(CoreUtilities.toLowerCase(event.getClick().name()))) { + if (hasClickType && !runGenericCheck(path.eventArgLowerAt(1), event.getClick().name())) { return false; } String clickedItemText = path.eventArgLowerAt(hasClickType ? 3 : 2); @@ -142,13 +159,10 @@ public boolean matches(ScriptPath path) { if (!tryInventory(inventory, path.eventArgLowerAt(inIndex + 1))) { return false; } - int withIndex = -1; - for (int i = 0; i < path.eventArgsLower.length; i++) { - if (path.eventArgLowerAt(i).equals("with")) { - withIndex = i; - } + if (!runWithCheck(path, cursor)) { + return false; } - if (withIndex > 0 && (event.getCursor() == null || !tryItem(new ItemTag(event.getCursor()), path.eventArgLowerAt(withIndex + 1)))) { + if (!nonSwitchWithCheck(path, cursor)) { return false; } return super.matches(path);