From 63d26f2a987a88bc54a6a86fd4251dd4a06f88ae Mon Sep 17 00:00:00 2001 From: Krakenied Date: Fri, 12 Jun 2026 02:08:35 +0200 Subject: [PATCH] Introduce new blockshearing options --- .../tasktype/type/BlockshearingTaskType.java | 69 ++++++++++++++++++- docs/task-types/blockshearing-(task-type).md | 14 ++-- 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/BlockshearingTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/BlockshearingTaskType.java index cb7dd8c3c..e390db071 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/BlockshearingTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/BlockshearingTaskType.java @@ -1,6 +1,9 @@ package com.leonardobishop.quests.bukkit.tasktype.type; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.item.QuestItem; import com.leonardobishop.quests.bukkit.tasktype.BukkitTaskType; import com.leonardobishop.quests.bukkit.util.TaskUtils; import com.leonardobishop.quests.bukkit.util.constraint.TaskConstraintSet; @@ -13,10 +16,14 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; +import org.bukkit.inventory.ItemStack; + +import java.util.List; public final class BlockshearingTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; + private final Table fixedQuestItemCache = HashBasedTable.create(); public BlockshearingTaskType(BukkitQuestsPlugin plugin) { super("blockshearing", TaskUtils.TASK_ATTRIBUTION_STRING, "Shear a set amount of certain blocks."); @@ -24,7 +31,16 @@ public BlockshearingTaskType(BukkitQuestsPlugin plugin) { super.addConfigValidator(TaskUtils.useRequiredConfigValidator(this, "amount")); super.addConfigValidator(TaskUtils.useIntegerConfigValidator(this, "amount")); + super.addConfigValidator(TaskUtils.useItemStackConfigValidator(this, "item")); + super.addConfigValidator(TaskUtils.useIntegerConfigValidator(this, "data")); + super.addConfigValidator(TaskUtils.useBooleanConfigValidator(this, "exact-match")); super.addConfigValidator(TaskUtils.useMaterialListConfigValidator(this, TaskUtils.MaterialListConfigValidatorMode.BLOCK, "block", "blocks")); + super.addConfigValidator(TaskUtils.useBooleanConfigValidator(this, "count-shears")); + } + + @Override + public void onReady() { + fixedQuestItemCache.clear(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @@ -40,7 +56,18 @@ public void onPlayerShearBlock(PlayerShearBlockEvent event) { } Block block = event.getBlock(); + List drops = event.getDrops(); + + if (drops.isEmpty()) { + handle(player, qPlayer, block, null, 0); + } + for (int i = 0; i < drops.size(); i++) { + handle(player, qPlayer, block, drops.get(i), i); + } + } + + private void handle(Player player, QPlayer qPlayer, Block block, ItemStack item, int i) { for (TaskUtils.PendingTask pendingTask : TaskUtils.getApplicableTasks(player, qPlayer, this, TaskConstraintSet.ALL)) { Quest quest = pendingTask.quest(); Task task = pendingTask.task(); @@ -48,15 +75,55 @@ public void onPlayerShearBlock(PlayerShearBlockEvent event) { super.debug("Player sheared a block, current block is " + block.getType(), quest.getId(), task.getId(), player.getUniqueId()); + Boolean countShears = (Boolean) task.getConfigValue("count-shears", true); + final int amountToIncrease; + + // Just in case getConfigValue behavior changes (which is expected in the future) + //noinspection PointlessBooleanExpression + if (Boolean.TRUE.equals(countShears)) { + if (i != 0) { + continue; + } + + amountToIncrease = 1; + } else { + if (task.hasConfigKey("item")) { + if (item == null) { + super.debug("Specific item is required, dropped item is null; continuing...", quest.getId(), task.getId(), player.getUniqueId()); + continue; + } + + super.debug("Specific item is required; dropped item is of type '" + item.getType() + "'", quest.getId(), task.getId(), player.getUniqueId()); + + QuestItem qi; + if ((qi = fixedQuestItemCache.get(quest.getId(), task.getId())) == null) { + QuestItem fetchedItem = TaskUtils.getConfigQuestItem(task, "item", "data"); + fixedQuestItemCache.put(quest.getId(), task.getId(), fetchedItem); + qi = fetchedItem; + } + + boolean exactMatch = TaskUtils.getConfigBoolean(task, "exact-match", true); + if (!qi.compareItemStack(item, exactMatch)) { + super.debug("Item does not match required item, continuing...", quest.getId(), task.getId(), player.getUniqueId()); + continue; + } else { + super.debug("Item matches required item", quest.getId(), task.getId(), player.getUniqueId()); + } + } + + amountToIncrease = item != null ? item.getAmount() : 0; + } + if (!TaskUtils.matchBlock(this, pendingTask, block, player.getUniqueId())) { super.debug("Continuing...", quest.getId(), task.getId(), player.getUniqueId()); continue; } - int progress = TaskUtils.incrementIntegerTaskProgress(taskProgress); + int progress = TaskUtils.incrementIntegerTaskProgress(taskProgress, amountToIncrease); super.debug("Incrementing task progress (now " + progress + ")", quest.getId(), task.getId(), player.getUniqueId()); int amount = (int) task.getConfigValue("amount"); + if (progress >= amount) { super.debug("Marking task as complete", quest.getId(), task.getId(), player.getUniqueId()); taskProgress.setCompleted(true); diff --git a/docs/task-types/blockshearing-(task-type).md b/docs/task-types/blockshearing-(task-type).md index 7c11bc01a..b5785471f 100644 --- a/docs/task-types/blockshearing-(task-type).md +++ b/docs/task-types/blockshearing-(task-type).md @@ -19,11 +19,15 @@ Shear a set amount of blocks. ## Options -| Key | Description | Type | Required | Default | Notes | -|----------|-------------------------------------------------|-------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `amount` | The number of blocks to shear. | Integer | Yes | \- | \- | -| `block` | The specific block(s) to shear. | Material, or list of material | No | \- | Please see [this list](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html) (1.13+) or [this list](https://helpch.at/docs/1.12.2/org/bukkit/Material.html) (1.8-1.12) for material names. Note that some items are confusingly named, they may refer to the held item or block instead of the crop block. | -| `worlds` | Worlds which should count towards the progress. | List of world names | No | \- | \- | +| Key | Description | Type | Required | Default | Notes | +|----------------|--------------------------------------------------------------------|-------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `amount` | The number of blocks to shear. | Integer | Yes | \- | \- | +| `block` | The specific block(s) to shear. | Material, or list of material | No | \- | Please see [this list](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html) (1.13+) or [this list](https://helpch.at/docs/1.12.2/org/bukkit/Material.html) (1.8-1.12) for material names. Note that some items are confusingly named, they may refer to the held item or block instead of the crop block. | +| `item` | The specific item to be dropped when shearing. | Material, or ItemStack | No | \- | Accepts standard [item definition](../configuration/defining-items). Please see [this list](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html) (1.13+) or [this list](https://helpch.at/docs/1.12.2/org/bukkit/Material.html) (1.8-1.12) for material names. | +| `data` | The data code for the item. | Integer | No | 0 | This field is not used in Minecraft versions 1.13+, nor is it compatible with ItemStack definitions. | +| `exact-match` | Whether the item should exactly match what is defined. | Boolean | No | true | \- | +| `count-shears` | Whether the plugin should count shears (actions) instead of items. | Boolean | No | true | \- | +| `worlds` | Worlds which should count towards the progress. | List of world names | No | \- | \- | ## Examples