diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e670042b9..c4baf7cadc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] - ${maven.build.timestamp} ### Added - A Bukkit event which fires when a player's points change -- `folder` event now has a argument `cancelConditions` to cancel a running folder +- `folder` event now has an argument `cancelConditions` to cancel a running folder +- `action` objective now supports configuring the hand used for the interaction, preventing multiple objective completions at the same time on right click ### Changed ### Deprecated ### Removed diff --git a/docs/Documentation/Scripting/Building-Blocks/Events-List.md b/docs/Documentation/Scripting/Building-Blocks/Events-List.md index 1c963d3447..33d8026569 100644 --- a/docs/Documentation/Scripting/Building-Blocks/Events-List.md +++ b/docs/Documentation/Scripting/Building-Blocks/Events-List.md @@ -584,7 +584,7 @@ Can only effect loaded entities! | _location_ | [Unified Location Formatting](../Data-Formats.md#unified-location-formating) | :octicons-x-circle-16: | Required. The center location of the target entity's. | | _radius_ | Number | :octicons-x-circle-16: | Required. The radius around the location. Can be a variable. | | _name_ | `name:name` | :octicons-x-circle-16: | Name of the entity. All `_` will be replaced with spaces. | -| _marked_ | `marked:mark` | :octicons-x-circle-16: | Mark of the entity (form the [spawn event](../../Scripting/Building-Blocks/Events-List.md#spawn-mob-spawn) for example). Can be a variable. | +| _marked_ | `marked:mark` | :octicons-x-circle-16: | Mark of the entity (from the [spawn event](../../Scripting/Building-Blocks/Events-List.md#spawn-mob-spawn) for example). Can be a variable. | | _kill_ | `kill` | :octicons-x-circle-16: | Whether to remove or actually kill the entity (if possible). | ```YAML title="Example" @@ -891,4 +891,3 @@ events: setShortRain: "weather rain duration:60 world:rpgworld" setStorm: "weather storm duration:%point.tribute.left:150%" ``` - diff --git a/docs/Documentation/Scripting/Building-Blocks/Objectives-List.md b/docs/Documentation/Scripting/Building-Blocks/Objectives-List.md index bb19d8fe77..a5933894f9 100644 --- a/docs/Documentation/Scripting/Building-Blocks/Objectives-List.md +++ b/docs/Documentation/Scripting/Building-Blocks/Objectives-List.md @@ -274,27 +274,34 @@ objectives: ## Interact with entity: `interact` -The player must click on an entity to complete this objective. The first argument is the type of a click. -Available values are `right`, `left` and `any`. -Second required argument is the [mob type](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html). -Next is an amount of mobs required to click on. These must be unique, so the player can't simply click twenty times on -the same zombie to complete it. There is also an optional `name:` parameter which specifies what custom name the entity must have -(you need to write `_` instead of the space character). To check for the real name (e.g. if you renamed players to include -their rank) you can also use `realname:` instead. -Add `marked:` if the clicked entity needs to be marked by the `spawn` event (see its description for marking explanation). -You can also add `notify` argument to make the objective notify players whenever they click a correct entity, -optionally with the notification interval after colon and `cancel` if the click shouldn't do what it usually does -(i.e. left click won't hurt the entity). This can be limited with an optional `loc` and `range` attribute to limit within a range of a location. - -This objective has three properties: `amount`, `left` and `total`. `amount` is the amount of entities already interacted -with, `left` is the amount of entities still needed to be interacted with and `total` is the amount of entities -initially required. +The player must click on entities to complete this objective. + +| Parameter | Syntax | Default Value | Explanation | +|-----------------|-----------------------------------------------------------------------------------------------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| +| _Click Type_ | `right`, `left` or `any` | :octicons-x-circle-16: | What type of click should be handled | +| _Entity Type_ | [EntityType type](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/EntityType.html) | :octicons-x-circle-16: | The entity which must be clicked | +| _amount_ | number | :octicons-x-circle-16: | The amount of different entities which must be interacted with. | +| _name_ | name:text | Disabled | Only count named mobs. Spaces must be replaced with `_`. | +| _realname_ | realname:text | Disabled | To check for the real name (e.g. if you renamed players to include their rank). Spaces must be replaced with `_`. | +| _marked_ | marked:text | Disabled | If the clicked entity needs to be marked by the [spawn event](./Events-List.md#spawn-mob-spawn) (see its description for marking explanation) | +| _hand_ | hand:(`hand`,`off_hand`, `any`) | `hand` | The hand the player must use to click the block, `any` can the objective cause to be completed multiple times | +| _Notifications_ | Keyword (_notify_) | Disabled | Displays messages to the player each time they progress the objective. Optionally with the notification interval after colon. | +| _Cancel_ | Keyword (_cancel_) | Disabled | if the click shouldn't do what it usually does (i.e. left click won't hurt the entity). | +| _hookLocation_ | hookLocation:[Location](../Data-Formats.md#unified-location-formating) | Everywhere | The location at which the entity must be interacted. | +| _range_ | range:number | 1 | The range around the `loc`. Requires defined `loc`. | + +```YAML title="Example" +interact right creeper 1 marked:sick condition:syringeInHand cancel +``` + +
Variable Properties
+ +| Name | Example Output | Explanation | +|--------|----------------|------------------------------------------------------------| +| amount | 7 | The amount of already interacted entities. | +| left | 13 | The amount of entities still needed to be interacted with. | +| total | 20 | The initially required amount of entities to interact. | -!!! example - ```YAML - interact right creeper 1 marked:sick condition:syringeInHand cancel - ``` - ## Resource pack state: `resourcepack` **:fontawesome-solid-list-check:{.task} Objective ยท :fontawesome-solid-paper-plane: Requires [Paper](https://papermc.io)** diff --git a/src/main/java/org/betonquest/betonquest/objectives/ActionObjective.java b/src/main/java/org/betonquest/betonquest/objectives/ActionObjective.java index 6325f63b26..d1294190d7 100644 --- a/src/main/java/org/betonquest/betonquest/objectives/ActionObjective.java +++ b/src/main/java/org/betonquest/betonquest/objectives/ActionObjective.java @@ -38,12 +38,12 @@ @SuppressWarnings({"PMD.GodClass", "PMD.CommentRequired"}) public class ActionObjective extends Objective implements Listener { /** - * The key for the location property + * The key for the location property. */ private static final String LOCATION_PROPERTY = "location"; /** - * The key for any action + * The key for any action. */ private static final String ANY = "any"; diff --git a/src/main/java/org/betonquest/betonquest/objectives/EntityInteractObjective.java b/src/main/java/org/betonquest/betonquest/objectives/EntityInteractObjective.java index 1bac7b3f2c..4adef1c9b2 100644 --- a/src/main/java/org/betonquest/betonquest/objectives/EntityInteractObjective.java +++ b/src/main/java/org/betonquest/betonquest/objectives/EntityInteractObjective.java @@ -25,6 +25,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.Nullable; @@ -44,6 +45,11 @@ */ @SuppressWarnings("PMD.CommentRequired") public class EntityInteractObjective extends CountingObjective { + /** + * The key for any hand. + */ + private static final String ANY = "any"; + /** * Custom {@link BetonQuestLogger} instance for this class. */ @@ -60,6 +66,9 @@ public class EntityInteractObjective extends CountingObjective { @Nullable private final String realName; + @Nullable + private final EquipmentSlot slot; + protected EntityType mobType; @Nullable @@ -93,6 +102,16 @@ public EntityInteractObjective(final Instruction instruction) throws Instruction loc = instruction.getLocation(instruction.getOptional("loc")); final String stringRange = instruction.getOptional("range"); range = instruction.getVarNum(stringRange == null ? "1" : stringRange); + final String handString = instruction.getOptional("hand"); + if (handString == null || handString.equalsIgnoreCase(EquipmentSlot.HAND.toString())) { + slot = EquipmentSlot.HAND; + } else if (handString.equalsIgnoreCase(EquipmentSlot.OFF_HAND.toString())) { + slot = EquipmentSlot.OFF_HAND; + } else if (ANY.equalsIgnoreCase(handString)) { + slot = null; + } else { + throw new InstructionParseException("Invalid hand value: " + handString); + } } @Nullable @@ -224,6 +243,9 @@ public void onDamage(final EntityDamageByEntityEvent event) { } else { return; } + if (slot != null && slot != EquipmentSlot.HAND) { + return; + } final boolean success = onInteract(player, event.getEntity()); if (success && cancel) { event.setCancelled(true); @@ -238,6 +260,9 @@ public RightClickListener() { @EventHandler(ignoreCancelled = true) public void onRightClick(final PlayerInteractAtEntityEvent event) { + if (slot != null && slot != event.getHand()) { + return; + } final boolean success = onInteract(event.getPlayer(), event.getRightClicked()); if (success && cancel) { event.setCancelled(true);