From 16707b375a8bb67340fb8a651c8ee56724f41bc1 Mon Sep 17 00:00:00 2001 From: LMBishop <13875753+LMBishop@users.noreply.github.com> Date: Mon, 16 Aug 2021 14:39:30 +0100 Subject: Add mmoitems as a quest item type (closes #221) --- .../quests/bukkit/BukkitQuestsPlugin.java | 12 +++- .../bukkit/command/AdminItemsCommandHandler.java | 6 +- .../quests/bukkit/config/BukkitQuestsLoader.java | 21 +++++-- .../quests/bukkit/item/MMOItemsQuestItem.java | 34 +++++++++++ .../quests/bukkit/item/ParsedQuestItem.java | 23 ++++++++ .../quests/bukkit/item/QuestItem.java | 20 +++++-- .../quests/bukkit/item/QuestItemRegistry.java | 4 ++ .../quests/bukkit/menu/QuestQMenu.java | 2 +- .../bukkit/tasktype/type/CraftingTaskType.java | 19 +++--- .../bukkit/tasktype/type/InventoryTaskType.java | 67 ++++++++++++---------- .../type/dependent/CitizensDeliverTaskType.java | 57 ++++++++++++++---- 11 files changed, 196 insertions(+), 69 deletions(-) create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/MMOItemsQuestItem.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/ParsedQuestItem.java (limited to 'bukkit/src/main/java') diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java index 10fc9e8a..6b1759f7 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java @@ -1,6 +1,5 @@ package com.leonardobishop.quests.bukkit; -import com.leonardobishop.quests.bukkit.command.QuestCommandHandler; import com.leonardobishop.quests.bukkit.command.QuestsCommandSwitcher; import com.leonardobishop.quests.bukkit.config.BukkitQuestsConfig; import com.leonardobishop.quests.bukkit.config.BukkitQuestsLoader; @@ -18,6 +17,8 @@ import com.leonardobishop.quests.bukkit.hook.title.Title; import com.leonardobishop.quests.bukkit.hook.title.Title_Bukkit; import com.leonardobishop.quests.bukkit.hook.title.Title_BukkitNoTimings; import com.leonardobishop.quests.bukkit.hook.title.Title_Other; +import com.leonardobishop.quests.bukkit.item.ParsedQuestItem; +import com.leonardobishop.quests.bukkit.item.QuestItem; import com.leonardobishop.quests.bukkit.item.QuestItemRegistry; import com.leonardobishop.quests.bukkit.listener.PlayerJoinListener; import com.leonardobishop.quests.bukkit.listener.PlayerLeaveListener; @@ -397,11 +398,16 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { } } - public ItemStack getItemStack(String path, ConfigurationSection config, ItemGetter.Filter... excludes) { + public QuestItem getConfiguredQuestItem(String path, ConfigurationSection config, ItemGetter.Filter... excludes) { if (config.contains(path + ".quest-item")) { - return questItemRegistry.getItem(config.getString(path + ".quest-item")).getItemStack(); + return questItemRegistry.getItem(config.getString(path + ".quest-item")); } + return new ParsedQuestItem("defined", null, getConfiguredItemStack(path, config, excludes)); + } + + + public ItemStack getConfiguredItemStack(String path, ConfigurationSection config, ItemGetter.Filter... excludes) { return itemGetter.getItem(path, config, excludes); } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminItemsCommandHandler.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminItemsCommandHandler.java index 78b16a73..c552a17a 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminItemsCommandHandler.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/command/AdminItemsCommandHandler.java @@ -1,6 +1,7 @@ package com.leonardobishop.quests.bukkit.command; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.item.ParsedQuestItem; import com.leonardobishop.quests.bukkit.item.QuestItem; import org.apache.commons.lang.StringUtils; import org.bukkit.ChatColor; @@ -13,7 +14,6 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -30,7 +30,7 @@ public class AdminItemsCommandHandler implements CommandHandler { if (args.length < 4) { sender.sendMessage(ChatColor.GRAY + "Imported items"); for (QuestItem questItem : plugin.getQuestItemRegistry().getAllItems()) { - sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + questItem.getId()); + sender.sendMessage(ChatColor.DARK_GRAY + " * " + ChatColor.RED + questItem.getId() + " (" + questItem.getType() + ")"); } sender.sendMessage(ChatColor.GRAY.toString() + plugin.getQuestItemRegistry().getAllItems().size() + " items imported."); sender.sendMessage(ChatColor.DARK_GRAY + "Import a new held item using /q a items import ."); @@ -61,7 +61,7 @@ public class AdminItemsCommandHandler implements CommandHandler { item.set("item", held); try { item.save(file); - plugin.getQuestItemRegistry().registerItem(id, new QuestItem(id, held)); + plugin.getQuestItemRegistry().registerItem(id, new ParsedQuestItem("raw", id, held)); sender.sendMessage(ChatColor.GRAY + "Held item saved to 'items/" + id + ".yml'. This can be referenced within tasks by the id '" + id + "'."); } catch (IOException e) { e.printStackTrace(); diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java index 2e297653..25fa8201 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/config/BukkitQuestsLoader.java @@ -2,6 +2,8 @@ package com.leonardobishop.quests.bukkit.config; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; import com.leonardobishop.quests.bukkit.hook.itemgetter.ItemGetter; +import com.leonardobishop.quests.bukkit.item.MMOItemsQuestItem; +import com.leonardobishop.quests.bukkit.item.ParsedQuestItem; import com.leonardobishop.quests.bukkit.item.QuestItem; import com.leonardobishop.quests.bukkit.item.QuestItemRegistry; import com.leonardobishop.quests.bukkit.menu.itemstack.QItemStack; @@ -19,6 +21,7 @@ import com.leonardobishop.quests.common.questcontroller.QuestController; import com.leonardobishop.quests.common.tasktype.TaskType; import com.leonardobishop.quests.common.tasktype.TaskTypeManager; import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -100,7 +103,7 @@ public class BukkitQuestsLoader implements QuestsLoader { } for (String id : categories.getKeys(false)) { - ItemStack displayItem = plugin.getItemStack(id + ".display", categories); + ItemStack displayItem = plugin.getConfiguredItemStack(id + ".display", categories); boolean permissionRequired = categories.getBoolean(id + ".permission-required", false); Category category = new Category(id, permissionRequired); @@ -347,18 +350,24 @@ public class BukkitQuestsLoader implements QuestsLoader { return FileVisitResult.CONTINUE; } - ItemStack itemStack; + QuestItem item; switch (config.getString("type", "").toLowerCase()) { default: return FileVisitResult.CONTINUE; case "raw": - itemStack = config.getItemStack("item"); + item = new ParsedQuestItem("raw", id, config.getItemStack("item")); break; case "defined": - itemStack = plugin.getItemStack("item", config); + item = new ParsedQuestItem("defined", id, plugin.getItemGetter().getItem("item", config)); + break; + case "mmoitems": + if (!Bukkit.getPluginManager().isPluginEnabled("MMOItems")) return FileVisitResult.CONTINUE; + item = new MMOItemsQuestItem(id, config.getString("item.type"), config.getString("item.id")); + break; } - questItemRegistry.registerItem(id, new QuestItem(id, itemStack)); + questItemRegistry.registerItem(id, item); + } catch (Exception e) { questsLogger.severe("An exception occurred when attempting to load quest item '" + path + "' (will be ignored)"); e.printStackTrace(); @@ -406,7 +415,7 @@ public class BukkitQuestsLoader implements QuestsLoader { String name; name = Chat.color(cName); - ItemStack is = plugin.getItemStack(path, config, + ItemStack is = plugin.getConfiguredItemStack(path, config, ItemGetter.Filter.DISPLAY_NAME, ItemGetter.Filter.LORE, ItemGetter.Filter.ENCHANTMENTS, ItemGetter.Filter.ITEM_FLAGS); return new QItemStack(plugin, name, loreNormal, loreStarted, is); diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/MMOItemsQuestItem.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/MMOItemsQuestItem.java new file mode 100644 index 00000000..7d5af7f0 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/MMOItemsQuestItem.java @@ -0,0 +1,34 @@ +package com.leonardobishop.quests.bukkit.item; + +import io.lumine.mythic.lib.api.item.NBTItem; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.Type; +import org.bukkit.inventory.ItemStack; + +public class MMOItemsQuestItem extends QuestItem { + + private final String mmoItemType; + private final String mmoItemId; + + public MMOItemsQuestItem(String id, String mmoItemType, String mmoItemId) { + super("mmoitems", id); + this.mmoItemType = mmoItemType; + this.mmoItemId = mmoItemId; + } + + @Override + public ItemStack getItemStack() { + return MMOItems.plugin.getItem(Type.get(mmoItemType), mmoItemId); + } + + @Override + public boolean compareItemStack(ItemStack other) { + NBTItem item = NBTItem.get(other); + if (!item.hasType()) return false; + + String type = item.getType(); + String id = item.getString("MMOITEMS_ITEM_ID"); + return mmoItemType.equals(type) && mmoItemId.equals(id); + } + +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/ParsedQuestItem.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/ParsedQuestItem.java new file mode 100644 index 00000000..a6253666 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/ParsedQuestItem.java @@ -0,0 +1,23 @@ +package com.leonardobishop.quests.bukkit.item; + +import org.bukkit.inventory.ItemStack; + +public class ParsedQuestItem extends QuestItem { + + private final ItemStack itemStack; + + public ParsedQuestItem(String type, String id, ItemStack itemStack) { + super(type, id); + this.itemStack = itemStack; + } + + @Override + public ItemStack getItemStack() { + return itemStack; + } + + @Override + public boolean compareItemStack(ItemStack other) { + return other.isSimilar(itemStack); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItem.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItem.java index ec0f7622..e4fa40b5 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItem.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItem.java @@ -5,21 +5,29 @@ import org.bukkit.inventory.ItemStack; /** * Represents a single quest item. */ -public class QuestItem { +public abstract class QuestItem { + private final String type; private final String id; - private final ItemStack itemStack; - public QuestItem(String id, ItemStack itemStack) { + public QuestItem(String type, String id) { + this.type = type; this.id = id; - this.itemStack = itemStack; + } + + public String getType() { + return type; } public String getId() { return id; } - public ItemStack getItemStack() { - return itemStack; + public boolean isTemporary() { + return type == null; } + + public abstract ItemStack getItemStack(); + + public abstract boolean compareItemStack(ItemStack other); } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItemRegistry.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItemRegistry.java index f066bc2f..93c674b0 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItemRegistry.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/item/QuestItemRegistry.java @@ -16,6 +16,10 @@ public class QuestItemRegistry { Objects.requireNonNull(id, "id cannot be null"); Objects.requireNonNull(item, "item cannot be null"); + if (item.getId() == null) { + throw new IllegalArgumentException("null id cannot be registered"); + } + registry.put(id, item); } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/QuestQMenu.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/QuestQMenu.java index 1f35bb18..881ba3fa 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/QuestQMenu.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/menu/QuestQMenu.java @@ -67,7 +67,7 @@ public class QuestQMenu implements QMenu { int repeat = plugin.getConfig().getInt(path + "." + s + ".repeat"); MenuElement menuElement; if (plugin.getConfig().contains(path + "." + s + ".display")) { - ItemStack is = plugin.getItemStack(path + "." + s + ".display", plugin.getConfig()); + ItemStack is = plugin.getConfiguredItemStack(path + "." + s + ".display", plugin.getConfig()); menuElement = new CustomMenuElement(is); } else if (plugin.getConfig().getBoolean(path + "." + s + ".spacer", false)) { menuElement = new SpacerMenuElement(); diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/CraftingTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/CraftingTaskType.java index a55e8f10..90cd29c9 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/CraftingTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/CraftingTaskType.java @@ -3,6 +3,8 @@ 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.ParsedQuestItem; +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.common.config.ConfigProblem; @@ -28,7 +30,7 @@ import java.util.List; public final class CraftingTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; - private final Table fixedItemStackCache = HashBasedTable.create(); + private final Table fixedQuestItemCache = HashBasedTable.create(); public CraftingTaskType(BukkitQuestsPlugin plugin) { super("crafting", TaskUtils.TASK_ATTRIBUTION_STRING, "Craft a specific item."); @@ -48,7 +50,7 @@ public final class CraftingTaskType extends BukkitTaskType { @Override public void onReady() { - fixedItemStackCache.clear(); + fixedQuestItemCache.clear(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @@ -87,13 +89,13 @@ public final class CraftingTaskType extends BukkitTaskType { Object configBlock = task.getConfigValue("item"); Object configData = task.getConfigValue("data"); - ItemStack is; - if ((is = fixedItemStackCache.get(quest.getId(), task.getId())) == null) { + QuestItem qi; + if ((qi = fixedQuestItemCache.get(quest.getId(), task.getId())) == null) { if (configBlock instanceof ConfigurationSection) { - is = plugin.getItemStack("", (ConfigurationSection) configBlock); + qi = plugin.getConfiguredQuestItem("", (ConfigurationSection) configBlock); } else { material = Material.getMaterial(String.valueOf(configBlock)); - + ItemStack is; if (material == null) { continue; } @@ -102,11 +104,12 @@ public final class CraftingTaskType extends BukkitTaskType { } else { is = new ItemStack(material, 1); } + qi = new ParsedQuestItem("parsed", null, is); } - fixedItemStackCache.put(quest.getId(), task.getId(), is); + fixedQuestItemCache.put(quest.getId(), task.getId(), qi); } - if (!clickedItem.isSimilar(is)) continue; + if (!qi.compareItemStack(clickedItem)) continue; int progress; if (taskProgress.getProgress() == null) { diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java index 94605cb4..60c50d0c 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/InventoryTaskType.java @@ -3,6 +3,8 @@ 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.ParsedQuestItem; +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.common.config.ConfigProblem; @@ -29,8 +31,8 @@ import java.util.List; public final class InventoryTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; - private final Table fixedItemStackCache = HashBasedTable.create(); - + private final Table fixedQuestItemCache = HashBasedTable.create(); + public InventoryTaskType(BukkitQuestsPlugin plugin) { super("inventory", TaskUtils.TASK_ATTRIBUTION_STRING, "Obtain a set of items."); this.plugin = plugin; @@ -51,7 +53,7 @@ public final class InventoryTaskType extends BukkitTaskType { @Override public void onReady() { - fixedItemStackCache.clear(); + fixedQuestItemCache.clear(); } @SuppressWarnings("deprecation") @@ -97,13 +99,13 @@ public final class InventoryTaskType extends BukkitTaskType { Object configData = task.getConfigValue("data"); Object remove = task.getConfigValue("remove-items-when-complete"); - ItemStack is; - if ((is = fixedItemStackCache.get(quest.getId(), task.getId())) == null) { + QuestItem qi; + if ((qi = fixedQuestItemCache.get(quest.getId(), task.getId())) == null) { if (configBlock instanceof ConfigurationSection) { - is = plugin.getItemStack("", (ConfigurationSection) configBlock); + qi = plugin.getConfiguredQuestItem("", (ConfigurationSection) configBlock); } else { material = Material.getMaterial(String.valueOf(configBlock)); - + ItemStack is; if (material == null) { continue; } @@ -112,45 +114,50 @@ public final class InventoryTaskType extends BukkitTaskType { } else { is = new ItemStack(material, 1); } + qi = new ParsedQuestItem("parsed", null, is); } - fixedItemStackCache.put(quest.getId(), task.getId(), is); + fixedQuestItemCache.put(quest.getId(), task.getId(), qi); } - if (task.getConfigValue("update-progress") != null - && (Boolean) task.getConfigValue("update-progress")) { - int inInv = getAmount(player, is, amount); - if (taskProgress.getProgress() != null && (int) taskProgress.getProgress() != inInv) { - taskProgress.setProgress(inInv); - } else if (taskProgress.getProgress() == null) { - taskProgress.setProgress(inInv); - } - } + int[] amountPerSlot = getAmountsPerSlot(player, qi); + int total = Math.min(amountPerSlot[36], amount); + taskProgress.setProgress(total); - if (player.getInventory().containsAtLeast(is, amount)) { - is.setAmount(amount); + if (total >= amount) { taskProgress.setCompleted(true); - if (remove != null && ((Boolean) remove)) { - player.getInventory().removeItem(is); - } + if (remove != null && ((Boolean) remove)) removeItemsInSlots(player, amountPerSlot, total); } } } } } - private int getAmount(Player player, ItemStack is, int max) { - if (is == null) { - return 0; - } - int amount = 0; + private int[] getAmountsPerSlot(Player player, QuestItem qi) { + int[] slotToAmount = new int[37]; + // idx 36 = total for (int i = 0; i < 36; i++) { ItemStack slot = player.getInventory().getItem(i); - if (slot == null || !slot.isSimilar(is)) + if (slot == null || !qi.compareItemStack(slot)) continue; - amount += slot.getAmount(); + slotToAmount[36] = slotToAmount[36] + slot.getAmount(); + slotToAmount[i] = slot.getAmount(); } - return Math.min(amount, max); + return slotToAmount; } + private void removeItemsInSlots(Player player, int[] amountPerSlot, int amountToRemove) { + for (int i = 0; i < 36; i++) { + if (amountPerSlot[i] == 0) continue; + + ItemStack slot = player.getInventory().getItem(i); + if (slot == null) continue; + + int amountInStack = slot.getAmount(); + int min = Math.max(0, amountInStack - amountToRemove); + slot.setAmount(min); + amountToRemove = amountToRemove - amountInStack; + if (amountToRemove <= 0) break; + } + } } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java index 4a7eaaa2..110d0ba6 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/dependent/CitizensDeliverTaskType.java @@ -3,6 +3,8 @@ package com.leonardobishop.quests.bukkit.tasktype.type.dependent; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import com.leonardobishop.quests.bukkit.BukkitQuestsPlugin; +import com.leonardobishop.quests.bukkit.item.ParsedQuestItem; +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.chat.Chat; @@ -29,7 +31,7 @@ import java.util.List; public final class CitizensDeliverTaskType extends BukkitTaskType { private final BukkitQuestsPlugin plugin; - private final Table fixedItemStackCache = HashBasedTable.create(); + private final Table fixedQuestItemCache = HashBasedTable.create(); public CitizensDeliverTaskType(BukkitQuestsPlugin plugin) { super("citizens_deliver", TaskUtils.TASK_ATTRIBUTION_STRING, "Deliver a set of items to a NPC."); @@ -50,7 +52,7 @@ public final class CitizensDeliverTaskType extends BukkitTaskType { @Override public void onReady() { - fixedItemStackCache.clear(); + fixedQuestItemCache.clear(); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @@ -91,13 +93,13 @@ public final class CitizensDeliverTaskType extends BukkitTaskType { Object configData = task.getConfigValue("data"); Object remove = task.getConfigValue("remove-items-when-complete"); - ItemStack is; - if ((is = fixedItemStackCache.get(quest.getId(), task.getId())) == null) { + QuestItem qi; + if ((qi = fixedQuestItemCache.get(quest.getId(), task.getId())) == null) { if (configBlock instanceof ConfigurationSection) { - is = plugin.getItemStack("", (ConfigurationSection) configBlock); + qi = plugin.getConfiguredQuestItem("", (ConfigurationSection) configBlock); } else { material = Material.getMaterial(String.valueOf(configBlock)); - + ItemStack is; if (material == null) { continue; } @@ -106,21 +108,52 @@ public final class CitizensDeliverTaskType extends BukkitTaskType { } else { is = new ItemStack(material, 1); } + qi = new ParsedQuestItem("parsed", null, is); } - fixedItemStackCache.put(quest.getId(), task.getId(), is); + fixedQuestItemCache.put(quest.getId(), task.getId(), qi); } - if (player.getInventory().containsAtLeast(is, amount)) { - is.setAmount(amount); + int[] amountPerSlot = getAmountsPerSlot(player, qi); + int total = Math.min(amountPerSlot[36], amount); + taskProgress.setProgress(total); + + if (total >= amount) { taskProgress.setCompleted(true); - if (remove != null && ((Boolean) remove)) { - player.getInventory().removeItem(is); - } + if (remove != null && ((Boolean) remove)) removeItemsInSlots(player, amountPerSlot, total); } } } } } + + private int[] getAmountsPerSlot(Player player, QuestItem qi) { + int[] slotToAmount = new int[37]; + // idx 36 = total + for (int i = 0; i < 36; i++) { + ItemStack slot = player.getInventory().getItem(i); + if (slot == null || !qi.compareItemStack(slot)) + continue; + slotToAmount[36] = slotToAmount[36] + slot.getAmount(); + slotToAmount[i] = slot.getAmount(); + } + return slotToAmount; + } + + private void removeItemsInSlots(Player player, int[] amountPerSlot, int amountToRemove) { + for (int i = 0; i < 36; i++) { + if (amountPerSlot[i] == 0) continue; + + ItemStack slot = player.getInventory().getItem(i); + if (slot == null) continue; + + int amountInStack = slot.getAmount(); + int min = Math.max(0, amountInStack - amountToRemove); + slot.setAmount(min); + amountToRemove = amountToRemove - amountInStack; + if (amountToRemove <= 0) break; + } + } + } -- cgit v1.2.3-70-g09d2