diff --git a/main/src/main/java/me/blackvein/quests/QuestData.java b/main/src/main/java/me/blackvein/quests/QuestData.java index 529ac0146..c3a2361df 100644 --- a/main/src/main/java/me/blackvein/quests/QuestData.java +++ b/main/src/main/java/me/blackvein/quests/QuestData.java @@ -395,21 +395,29 @@ public class QuestData { } }; - public LinkedHashMap itemsConsumed = new LinkedHashMap() { + public LinkedList itemsConsumed = new LinkedList() { private static final long serialVersionUID = -5475073316902757883L; - + @Override - public Integer put(final ItemStack key, final Integer val) { - final Integer data = super.put(key, val); + public ItemStack set(final int index, final ItemStack key) { + final ItemStack data = super.set(index, key); if (doJournalUpdate) quester.updateJournal(); return data; } @Override - public Integer remove(final Object key) { - final Integer i = super.remove(key); + public boolean add(final ItemStack key) { + final boolean data = super.add(key); + if (doJournalUpdate) + quester.updateJournal(); + return data; + } + + @Override + public boolean remove(final Object key) { + final boolean i = super.remove(key); if (doJournalUpdate) quester.updateJournal(); return i; @@ -423,10 +431,11 @@ public class QuestData { } @Override - public void putAll(final Map m) { - super.putAll(m); + public boolean addAll(final Collection m) { + final boolean i = super.addAll(m); if (doJournalUpdate) quester.updateJournal(); + return i; } }; diff --git a/main/src/main/java/me/blackvein/quests/Quester.java b/main/src/main/java/me/blackvein/quests/Quester.java index 2736d3743..842a1d3e5 100644 --- a/main/src/main/java/me/blackvein/quests/Quester.java +++ b/main/src/main/java/me/blackvein/quests/Quester.java @@ -1085,16 +1085,18 @@ public class Quester implements Comparable { } objectives.add(message.replace("", ItemUtil.getName(is))); } + int consumeIndex = 0; for (final ItemStack is : stage.itemsToConsume) { int consumed = 0; - if (data.itemsConsumed.containsKey(is)) { - consumed = data.itemsConsumed.get(is); + if (data.itemsConsumed.size() > consumeIndex) { + consumed = data.itemsConsumed.get(consumeIndex).getAmount(); } - final int amt = is.getAmount(); - final ChatColor color = consumed < amt ? ChatColor.GREEN : ChatColor.GRAY; + final int toConsume = is.getAmount(); + consumeIndex++; + final ChatColor color = consumed < toConsume ? ChatColor.GREEN : ChatColor.GRAY; String message = color + Lang.get(getPlayer(), "consumeItem"); if (message.contains("")) { - message = message.replace("", "" + color + consumed + "/" + is.getAmount()); + message = message.replace("", "" + color + consumed + "/" + toConsume); } else { // Legacy message += color + ": " + consumed + "/" + is.getAmount(); @@ -1104,89 +1106,6 @@ public class Quester implements Comparable { } objectives.add(message.replace("", ItemUtil.getName(is))); } - if (stage.cowsToMilk != null) { - final ChatColor color = data.getCowsMilked() < stage.cowsToMilk ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + Lang.get(getPlayer(), "milkCow"); - if (message.contains("")) { - message = message.replace("", "" + color + data.getCowsMilked() + "/" + stage.cowsToMilk); - } else { - // Legacy - message += color + ": " + data.getCowsMilked() + "/" + stage.cowsToMilk; - } - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(getPlayer(), message); - } - objectives.add(message); - } - if (getCurrentStage(quest).fishToCatch != null) { - final ChatColor color = data.getFishCaught() < stage.fishToCatch ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + Lang.get(getPlayer(), "catchFish"); - if (message.contains("")) { - message = message.replace("", "" + color + data.getFishCaught() + "/" + stage.fishToCatch); - } else { - // Legacy - message += color + ": " + data.getFishCaught() + "/" + stage.fishToCatch; - } - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(getPlayer(), message); - } - objectives.add(message); - } - for (final EntityType e : getCurrentStage(quest).mobsToKill) { - for (final EntityType e2 : getQuestData(quest).mobsKilled) { - if (e == e2) { - if (data.mobNumKilled.size() > data.mobsKilled.indexOf(e2) - && stage.mobNumToKill.size() > stage.mobsToKill.indexOf(e)) { - final ChatColor color = data.mobNumKilled.get(data.mobsKilled.indexOf(e2)) - < stage.mobNumToKill.get(stage.mobsToKill.indexOf(e)) - ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + ""; - if (stage.locationsToKillWithin.isEmpty()) { - message += Lang.get(getPlayer(), "kill"); - if (message.contains("")) { - message = message.replace("", "" + color - + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" - + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e)))); - } else { - // Legacy - message += ChatColor.AQUA + " " + color + ": " - + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" - + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e))); - } - } else { - message += Lang.get(getPlayer(), "killAtLocation").replace("", - stage.killNames.get(stage.mobsToKill.indexOf(e))); - if (message.contains("")) { - message = message.replace("", "" + color - + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" - + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e)))); - } else { - message += color + ": " + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" - + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e))); - } - } - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(getPlayer(), message); - } - objectives.add(message.replace("", MiscUtil.getProperMobName(e))); - } - } - } - } - if (stage.playersToKill != null) { - final ChatColor color = data.getPlayersKilled() < stage.playersToKill ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + Lang.get(getPlayer(), "killPlayer"); - if (message.contains("")) { - message = message.replace("", "" + color + data.getPlayersKilled() + "/" + stage.playersToKill); - } else { - // Legacy - message += color + ": " + data.getPlayersKilled() + "/" + stage.playersToKill; - } - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(getPlayer(), message); - } - objectives.add(message); - } int index = 0; for (final ItemStack is : stage.itemsToDeliver) { int delivered = 0; @@ -1253,6 +1172,47 @@ public class Quester implements Comparable { } } } + for (final EntityType e : getCurrentStage(quest).mobsToKill) { + for (final EntityType e2 : getQuestData(quest).mobsKilled) { + if (e == e2) { + if (data.mobNumKilled.size() > data.mobsKilled.indexOf(e2) + && stage.mobNumToKill.size() > stage.mobsToKill.indexOf(e)) { + final ChatColor color = data.mobNumKilled.get(data.mobsKilled.indexOf(e2)) + < stage.mobNumToKill.get(stage.mobsToKill.indexOf(e)) + ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + ""; + if (stage.locationsToKillWithin.isEmpty()) { + message += Lang.get(getPlayer(), "kill"); + if (message.contains("")) { + message = message.replace("", "" + color + + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" + + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e)))); + } else { + // Legacy + message += ChatColor.AQUA + " " + color + ": " + + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" + + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e))); + } + } else { + message += Lang.get(getPlayer(), "killAtLocation").replace("", + stage.killNames.get(stage.mobsToKill.indexOf(e))); + if (message.contains("")) { + message = message.replace("", "" + color + + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" + + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e)))); + } else { + message += color + ": " + (data.mobNumKilled.get(data.mobsKilled.indexOf(e2))) + "/" + + (stage.mobNumToKill.get(stage.mobsToKill.indexOf(e))); + } + } + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(getPlayer(), message); + } + objectives.add(message.replace("", MiscUtil.getProperMobName(e))); + } + } + } + } for (final Entry e : getCurrentStage(quest).mobsToTame.entrySet()) { for (final Entry e2 : getQuestData(quest).mobsTamed.entrySet()) { if (e.getKey().equals(e2.getKey())) { @@ -1271,6 +1231,34 @@ public class Quester implements Comparable { } } } + if (getCurrentStage(quest).fishToCatch != null) { + final ChatColor color = data.getFishCaught() < stage.fishToCatch ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + Lang.get(getPlayer(), "catchFish"); + if (message.contains("")) { + message = message.replace("", "" + color + data.getFishCaught() + "/" + stage.fishToCatch); + } else { + // Legacy + message += color + ": " + data.getFishCaught() + "/" + stage.fishToCatch; + } + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(getPlayer(), message); + } + objectives.add(message); + } + if (stage.cowsToMilk != null) { + final ChatColor color = data.getCowsMilked() < stage.cowsToMilk ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + Lang.get(getPlayer(), "milkCow"); + if (message.contains("")) { + message = message.replace("", "" + color + data.getCowsMilked() + "/" + stage.cowsToMilk); + } else { + // Legacy + message += color + ": " + data.getCowsMilked() + "/" + stage.cowsToMilk; + } + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(getPlayer(), message); + } + objectives.add(message); + } for (final Entry e : getCurrentStage(quest).sheepToShear.entrySet()) { for (final Entry e2 : getQuestData(quest).sheepSheared.entrySet()) { if (e.getKey().equals(e2.getKey())) { @@ -1287,6 +1275,20 @@ public class Quester implements Comparable { } } } + if (stage.playersToKill != null) { + final ChatColor color = data.getPlayersKilled() < stage.playersToKill ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + Lang.get(getPlayer(), "killPlayer"); + if (message.contains("")) { + message = message.replace("", "" + color + data.getPlayersKilled() + "/" + stage.playersToKill); + } else { + // Legacy + message += color + ": " + data.getPlayersKilled() + "/" + stage.playersToKill; + } + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(getPlayer(), message); + } + objectives.add(message); + } for (final Location l : getCurrentStage(quest).locationsToReach) { for (final Location l2 : getQuestData(quest).locationsReached) { if (l.equals(l2)) { @@ -2120,56 +2122,225 @@ public class Quester implements Comparable { * @param i The item being consumed */ public void consumeItem(final Quest quest, final ItemStack i) { - ItemStack found = null; - for (final ItemStack is : getQuestData(quest).itemsConsumed.keySet()) { + int currentIndex = -1; + final LinkedList matches = new LinkedList(); + for (final ItemStack is : getQuestData(quest).itemsConsumed) { + currentIndex++; if (ItemUtil.compareItems(i, is, true) == 0) { - found = is; - break; + matches.add(currentIndex); } } - if (found == null) { + if (matches.isEmpty()) { return; } - final int amount = getQuestData(quest).itemsConsumed.get(found); - if (getCurrentStage(quest).itemsToConsume.indexOf(found) < 0) { - plugin.getLogger().severe("Index out of bounds while consuming " + found.getType() + " x " - + found.getAmount() + " for quest " + quest.getName() + " with " + i.getType() + " x " - + i.getAmount() + " already consumed. List amount reports value of " + amount - + ". Please report this error on Github!"); - sendMessage(ChatColor.RED + "Quests had a problem consuming your item, please contact an administrator!"); + for (final Integer match : matches) { + final LinkedList items = new LinkedList(getQuestData(quest).itemsConsumed); + final ItemStack found = items.get(match); + final int amount = found.getAmount(); + final int toConsume = getCurrentStage(quest).itemsToConsume.get(match).getAmount(); + + final ObjectiveType type = ObjectiveType.CONSUME_ITEM; + final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, + new Objective(type, amount, toConsume)); + plugin.getServer().getPluginManager().callEvent(preEvent); + + final int newAmount = i.getAmount() + amount; + final Material m = i.getType(); + if (amount < toConsume) { + if (newAmount >= toConsume) { + final ItemStack newStack = found; + found.setAmount(toConsume); + getQuestData(quest).itemsConsumed.set(items.indexOf(found), newStack); + finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, null, + null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { + q.getQuestData(quest).itemsConsumed.set(items.indexOf(found), newStack); + q.finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, + null, null, null, null); + return null; + }); + } else { + final ItemStack newStack = found; + found.setAmount(newAmount); + getQuestData(quest).itemsConsumed.set(items.indexOf(found), newStack); + } + return; + } + + final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, + new Objective(type, newAmount, toConsume)); + plugin.getServer().getPluginManager().callEvent(postEvent); + } + } + + /** + * Mark item as delivered to a NPC if Quester has such an objective + * + * @param quest The quest for which the item is being delivered + * @param n The NPC being delivered to + * @param i The item being delivered + */ + @SuppressWarnings("deprecation") + public void deliverToNPC(final Quest quest, final NPC n, final ItemStack i) { + if (n == null) { return; } - final int req = getCurrentStage(quest).itemsToConsume.get(getCurrentStage(quest).itemsToConsume.indexOf(found)) - .getAmount(); - final ObjectiveType type = ObjectiveType.CONSUME_ITEM; + int currentIndex = -1; + final LinkedList matches = new LinkedList(); + for (final ItemStack is : getQuestData(quest).itemsDelivered) { + currentIndex++; + if (ItemUtil.compareItems(i, is, true) == 0) { + matches.add(currentIndex); + } + } + if (matches.isEmpty()) { + return; + } + final Player player = getPlayer(); + for (final Integer match : matches) { + final LinkedList items = new LinkedList(getQuestData(quest).itemsDelivered); + if (!getCurrentStage(quest).getItemDeliveryTargets().get(match).equals(n.getId())) { + continue; + } + final ItemStack found = items.get(match); + final int amount = found.getAmount(); + final int toDeliver = getCurrentStage(quest).itemsToDeliver.get(match).getAmount(); + + final ObjectiveType type = ObjectiveType.DELIVER_ITEM; + final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, + new Objective(type, amount, toDeliver)); + plugin.getServer().getPluginManager().callEvent(preEvent); + + final int newAmount = i.getAmount() + amount; + final Material m = i.getType(); + if (amount < toDeliver) { + final int index = player.getInventory().first(i); + if (index == -1) { + // Already delivered in previous loop + return; + } + if (newAmount >= toDeliver) { + final ItemStack newStack = found; + found.setAmount(toDeliver); + getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack); + if ((i.getAmount() + amount) >= toDeliver) { + // Take away remaining amount to be delivered + final ItemStack clone = i.clone(); + clone.setAmount(i.getAmount() - (toDeliver - amount)); + player.getInventory().setItem(index, clone); + } else { + player.getInventory().setItem(index, null); + } + player.updateInventory(); + finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, null, + null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { + q.getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack); + q.finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, + null, null, null, null); + return null; + }); + } else { + final ItemStack newStack = found; + found.setAmount(newAmount); + getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack); + player.getInventory().setItem(index, null); + player.updateInventory(); + final String[] message = ConfigUtil.parseStringWithPossibleLineBreaks(getCurrentStage(quest) + .deliverMessages.get(new Random().nextInt(getCurrentStage(quest).deliverMessages + .size())), plugin.getDependencies().getCitizens().getNPCRegistry() + .getById(getCurrentStage(quest).itemDeliveryTargets.get(items.indexOf(found)))); + player.sendMessage(message); + } + } + + final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, + new Objective(type, newAmount, toDeliver)); + plugin.getServer().getPluginManager().callEvent(postEvent); + } + } + + /** + * Mark NPC as interacted with if Quester has such an objective + * + * @param quest The quest for which the NPC is being interacted with + * @param n The NPC being interacted with + */ + public void interactWithNPC(final Quest quest, final NPC n) { + final ObjectiveType type = ObjectiveType.TALK_TO_NPC; final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, - new Objective(type, amount, req)); + new Objective(type, 1, 1)); plugin.getServer().getPluginManager().callEvent(preEvent); - final int newAmount = i.getAmount() + amount; - if (amount < req) { - final Material m = i.getType(); - if (newAmount >= req) { - getQuestData(quest).itemsConsumed.put(found, req); - finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, null, null, - null, null); + if (!getQuestData(quest).citizensInteracted.containsKey(n.getId())) { + return; + } + + final Boolean b = getQuestData(quest).citizensInteracted.get(n.getId()); + if (b != null && !b) { + getQuestData(quest).citizensInteracted.put(n.getId(), true); + finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1)), + null, null, n, null, null, null, null); + + // Multiplayer + dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { + q.getQuestData(quest).citizensInteracted.put(n.getId(), true); + q.finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), + new ItemStack(Material.AIR, 1)), null, null, n, null, null, null, null); + return null; + }); + + final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, + new Objective(type, 1, 1)); + plugin.getServer().getPluginManager().callEvent(postEvent); + } + } + + /** + * Mark NPC as killed if the Quester has such an objective + * + * @param quest The quest for which the NPC is being killed + * @param n The NPC being killed + */ + public void killNPC(final Quest quest, final NPC n) { + if (!getQuestData(quest).citizensKilled.contains(n.getId())) { + return; + } + + final int index = getQuestData(quest).citizensKilled.indexOf(n.getId()); + final int npcsKilled = getQuestData(quest).citizenNumKilled.get(index); + final int npcsToKill = getCurrentStage(quest).citizenNumToKill.get(index); + + final ObjectiveType type = ObjectiveType.KILL_NPC; + final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, + new Objective(type, npcsKilled, npcsToKill)); + plugin.getServer().getPluginManager().callEvent(preEvent); + + final int newNpcsKilled = getQuestData(quest).citizenNumKilled.get(index) + 1; + if (npcsKilled < npcsToKill) { + getQuestData(quest).citizenNumKilled.set(index, newNpcsKilled); + if (newNpcsKilled >= npcsToKill) { + finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), + new ItemStack(Material.AIR, npcsToKill)), null, null, n, null, null, null, null); // Multiplayer - final ItemStack finalFound = found; dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { - q.getQuestData(quest).itemsConsumed.put(finalFound, req); - q.finishObjective(quest, new Objective(type, new ItemStack(m, 1), finalFound), null, null, null, - null, null, null, null); + q.getQuestData(quest).citizenNumKilled.set(index, getQuestData(quest).citizenNumKilled + .get(index)); + q.finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), + new ItemStack(Material.AIR, npcsToKill)), null, null, n, null, null, null, null); return null; }); - } else { - getQuestData(quest).itemsConsumed.put(found, newAmount); } } final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, - new Objective(type, newAmount, req)); + new Objective(type, newNpcsKilled, npcsToKill)); plugin.getServer().getPluginManager().callEvent(postEvent); } @@ -2392,175 +2563,6 @@ public class Quester implements Comparable { new Objective(type, newPlayersKilled, playersToKill)); plugin.getServer().getPluginManager().callEvent(postEvent); } - - /** - * Mark item as delivered to a NPC if Quester has such an objective - * - * @param quest The quest for which the item is being delivered - * @param n The NPC being delivered to - * @param i The item being delivered - */ - @SuppressWarnings("deprecation") - public void deliverToNPC(final Quest quest, final NPC n, final ItemStack i) { - if (n == null) { - return; - } - - int currentIndex = -1; - final LinkedList matches = new LinkedList(); - for (final ItemStack is : getQuestData(quest).itemsDelivered) { - currentIndex++; - if (ItemUtil.compareItems(i, is, true) == 0) { - matches.add(currentIndex); - } - } - if (matches.isEmpty()) { - return; - } - final Player player = getPlayer(); - for (final Integer match : matches) { - final LinkedList items = new LinkedList(getQuestData(quest).itemsDelivered); - if (!getCurrentStage(quest).getItemDeliveryTargets().get(match).equals(n.getId())) { - continue; - } - final ItemStack found = items.get(match); - final int amount = found.getAmount(); - final int toDeliver = getCurrentStage(quest).itemsToDeliver.get(match).getAmount(); - - final ObjectiveType type = ObjectiveType.DELIVER_ITEM; - final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, - new Objective(type, amount, toDeliver)); - plugin.getServer().getPluginManager().callEvent(preEvent); - - final int newAmount = i.getAmount() + amount; - final Material m = i.getType(); - if (amount < toDeliver) { - final int index = player.getInventory().first(i); - if (index == -1) { - // Already delivered in previous loop - return; - } - if (newAmount >= toDeliver) { - final ItemStack newStack = found; - found.setAmount(toDeliver); - getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack); - if ((i.getAmount() + amount) >= toDeliver) { - // Take away remaining amount to be delivered - final ItemStack clone = i.clone(); - clone.setAmount(i.getAmount() - (toDeliver - amount)); - player.getInventory().setItem(index, clone); - } else { - player.getInventory().setItem(index, null); - } - player.updateInventory(); - finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, null, - null, null, null); - - // Multiplayer - dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { - q.getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack); - q.finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null, - null, null, null, null); - return null; - }); - } else { - final ItemStack newStack = found; - found.setAmount(newAmount); - getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack); - player.getInventory().setItem(index, null); - player.updateInventory(); - final String[] message = ConfigUtil.parseStringWithPossibleLineBreaks(getCurrentStage(quest) - .deliverMessages.get(new Random().nextInt(getCurrentStage(quest).deliverMessages - .size())), plugin.getDependencies().getCitizens().getNPCRegistry() - .getById(getCurrentStage(quest).itemDeliveryTargets.get(items.indexOf(found)))); - player.sendMessage(message); - } - } - - final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, - new Objective(type, newAmount, toDeliver)); - plugin.getServer().getPluginManager().callEvent(postEvent); - } - } - - /** - * Mark NPC as interacted with if Quester has such an objective - * - * @param quest The quest for which the NPC is being interacted with - * @param n The NPC being interacted with - */ - public void interactWithNPC(final Quest quest, final NPC n) { - final ObjectiveType type = ObjectiveType.TALK_TO_NPC; - final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, - new Objective(type, 1, 1)); - plugin.getServer().getPluginManager().callEvent(preEvent); - - if (!getQuestData(quest).citizensInteracted.containsKey(n.getId())) { - return; - } - - final Boolean b = getQuestData(quest).citizensInteracted.get(n.getId()); - if (b != null && !b) { - getQuestData(quest).citizensInteracted.put(n.getId(), true); - finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), new ItemStack(Material.AIR, 1)), - null, null, n, null, null, null, null); - - // Multiplayer - dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { - q.getQuestData(quest).citizensInteracted.put(n.getId(), true); - q.finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), - new ItemStack(Material.AIR, 1)), null, null, n, null, null, null, null); - return null; - }); - - final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, - new Objective(type, 1, 1)); - plugin.getServer().getPluginManager().callEvent(postEvent); - } - } - - /** - * Mark NPC as killed if the Quester has such an objective - * - * @param quest The quest for which the NPC is being killed - * @param n The NPC being killed - */ - public void killNPC(final Quest quest, final NPC n) { - if (!getQuestData(quest).citizensKilled.contains(n.getId())) { - return; - } - - final int index = getQuestData(quest).citizensKilled.indexOf(n.getId()); - final int npcsKilled = getQuestData(quest).citizenNumKilled.get(index); - final int npcsToKill = getCurrentStage(quest).citizenNumToKill.get(index); - - final ObjectiveType type = ObjectiveType.KILL_NPC; - final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest, - new Objective(type, npcsKilled, npcsToKill)); - plugin.getServer().getPluginManager().callEvent(preEvent); - - final int newNpcsKilled = getQuestData(quest).citizenNumKilled.get(index) + 1; - if (npcsKilled < npcsToKill) { - getQuestData(quest).citizenNumKilled.set(index, newNpcsKilled); - if (newNpcsKilled >= npcsToKill) { - finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), - new ItemStack(Material.AIR, npcsToKill)), null, null, n, null, null, null, null); - - // Multiplayer - dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (final Quester q) -> { - q.getQuestData(quest).citizenNumKilled.set(index, getQuestData(quest).citizenNumKilled - .get(index)); - q.finishObjective(quest, new Objective(type, new ItemStack(Material.AIR, 1), - new ItemStack(Material.AIR, npcsToKill)), null, null, n, null, null, null, null); - return null; - }); - } - } - - final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest, - new Objective(type, newNpcsKilled, npcsToKill)); - plugin.getServer().getPluginManager().callEvent(postEvent); - } /** * Mark location as reached if the Quester has such an objective @@ -3279,26 +3281,19 @@ public class Quester implements Comparable { } } if (quest.getStage(stage).itemsToConsume.isEmpty() == false) { - for (final ItemStack is : quest.getStage(stage).itemsToConsume) { - data.itemsConsumed.put(is, 0); + for (final ItemStack i : quest.getStage(stage).itemsToConsume) { + final ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability()); + try { + temp.addEnchantments(i.getEnchantments()); + } catch (final Exception e) { + plugin.getLogger().warning("Unable to add enchantment(s) " + i.getEnchantments().toString() + + " to consume item " + i.getType().name() + " x " + i.getAmount() + " for quest ID " + + quest.getId()); + } + temp.setItemMeta(i.getItemMeta()); + data.itemsConsumed.add(temp); } } - if (quest.getStage(stage).mobsToKill.isEmpty() == false) { - for (final EntityType e : quest.getStage(stage).mobsToKill) { - data.mobsKilled.add(e); - data.mobNumKilled.add(0); - if (quest.getStage(stage).locationsToKillWithin.isEmpty() == false) { - data.locationsToKillWithin.add(quest.getStage(stage).locationsToKillWithin.get(data.mobsKilled - .indexOf(e))); - } - if (quest.getStage(stage).radiiToKillWithin.isEmpty() == false) { - data.radiiToKillWithin.add(quest.getStage(stage).radiiToKillWithin.get(data.mobsKilled.indexOf(e))); - } - } - } - data.setCowsMilked(0); - data.setFishCaught(0); - data.setPlayersKilled(0); if (quest.getStage(stage).itemsToDeliver.isEmpty() == false) { for (final ItemStack i : quest.getStage(stage).itemsToDeliver) { final ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability()); @@ -3324,6 +3319,22 @@ public class Quester implements Comparable { data.citizenNumKilled.add(0); } } + if (quest.getStage(stage).mobsToKill.isEmpty() == false) { + for (final EntityType e : quest.getStage(stage).mobsToKill) { + data.mobsKilled.add(e); + data.mobNumKilled.add(0); + if (quest.getStage(stage).locationsToKillWithin.isEmpty() == false) { + data.locationsToKillWithin.add(quest.getStage(stage).locationsToKillWithin.get(data.mobsKilled + .indexOf(e))); + } + if (quest.getStage(stage).radiiToKillWithin.isEmpty() == false) { + data.radiiToKillWithin.add(quest.getStage(stage).radiiToKillWithin.get(data.mobsKilled.indexOf(e))); + } + } + } + data.setCowsMilked(0); + data.setFishCaught(0); + data.setPlayersKilled(0); if (quest.getStage(stage).locationsToReach.isEmpty() == false) { for (final Location l : quest.getStage(stage).locationsToReach) { data.locationsReached.add(l); @@ -3530,11 +3541,36 @@ public class Quester implements Comparable { } if (questData.itemsConsumed.isEmpty() == false) { final LinkedList consumeAmounts = new LinkedList(); - for (final Entry e : questData.itemsConsumed.entrySet()) { - consumeAmounts.add(e.getValue()); + for (final ItemStack m : questData.itemsConsumed) { + consumeAmounts.add(m.getAmount()); } questSec.set("item-consume-amounts", consumeAmounts); } + if (questData.itemsDelivered.isEmpty() == false) { + final LinkedList deliveryAmounts = new LinkedList(); + for (final ItemStack m : questData.itemsDelivered) { + deliveryAmounts.add(m.getAmount()); + } + questSec.set("item-delivery-amounts", deliveryAmounts); + } + if (questData.citizensInteracted.isEmpty() == false) { + final LinkedList npcIds = new LinkedList(); + final LinkedList hasTalked = new LinkedList(); + for (final Integer n : questData.citizensInteracted.keySet()) { + npcIds.add(n); + hasTalked.add(questData.citizensInteracted.get(n)); + } + questSec.set("citizen-ids-to-talk-to", npcIds); + questSec.set("has-talked-to", hasTalked); + } + if (questData.citizensKilled.isEmpty() == false) { + final LinkedList npcIds = new LinkedList(); + for (final Integer n : questData.citizensKilled) { + npcIds.add(n); + } + questSec.set("citizen-ids-killed", npcIds); + questSec.set("citizen-amounts-killed", questData.citizenNumKilled); + } if (getCurrentStage(quest) != null) { if (getCurrentStage(quest).cowsToMilk != null) { questSec.set("cows-milked", questData.getCowsMilked()); @@ -3570,31 +3606,6 @@ public class Quester implements Comparable { questSec.set("mob-kill-location-radii", radii); } } - if (questData.itemsDelivered.isEmpty() == false) { - final LinkedList deliveryAmounts = new LinkedList(); - for (final ItemStack m : questData.itemsDelivered) { - deliveryAmounts.add(m.getAmount()); - } - questSec.set("item-delivery-amounts", deliveryAmounts); - } - if (questData.citizensInteracted.isEmpty() == false) { - final LinkedList npcIds = new LinkedList(); - final LinkedList hasTalked = new LinkedList(); - for (final Integer n : questData.citizensInteracted.keySet()) { - npcIds.add(n); - hasTalked.add(questData.citizensInteracted.get(n)); - } - questSec.set("citizen-ids-to-talk-to", npcIds); - questSec.set("has-talked-to", hasTalked); - } - if (questData.citizensKilled.isEmpty() == false) { - final LinkedList npcIds = new LinkedList(); - for (final Integer n : questData.citizensKilled) { - npcIds.add(n); - } - questSec.set("citizen-ids-killed", npcIds); - questSec.set("citizen-amounts-killed", questData.citizenNumKilled); - } if (questData.locationsReached.isEmpty() == false) { final LinkedList locations = new LinkedList(); final LinkedList has = new LinkedList(); diff --git a/main/src/main/java/me/blackvein/quests/Quests.java b/main/src/main/java/me/blackvein/quests/Quests.java index b2b0f914c..06a47c0ee 100644 --- a/main/src/main/java/me/blackvein/quests/Quests.java +++ b/main/src/main/java/me/blackvein/quests/Quests.java @@ -1210,12 +1210,14 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener quester.sendMessage(message.replace("", ItemUtil.getName(is))); } } + int consumeIndex = 0; for (final ItemStack is : stage.itemsToConsume) { int consumed = 0; - if (data.itemsConsumed.containsKey(is)) { - consumed = data.itemsConsumed.get(is); + if (data.itemsConsumed.size() > consumeIndex) { + consumed = data.itemsConsumed.get(consumeIndex).getAmount(); } final int amt = is.getAmount(); + consumeIndex++; final ChatColor color = consumed < amt ? ChatColor.GREEN : ChatColor.GRAY; String message = color + "- " + Lang.get(quester.getPlayer(), "consumeItem"); if (message.contains("")) { @@ -1240,6 +1242,78 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener quester.sendMessage(message.replace("", ItemUtil.getName(is))); } } + + int index = 0; + for (final ItemStack is : stage.itemsToDeliver) { + int delivered = 0; + if (data.itemsDelivered.size() > index) { + delivered = data.itemsDelivered.get(index).getAmount(); + } + final int toDeliver = is.getAmount(); + final Integer npc = stage.itemDeliveryTargets.get(index); + index++; + final ChatColor color = delivered < toDeliver ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + "- " + Lang.get(quester.getPlayer(), "deliver").replace("", depends.getNPCName(npc)); + if (message.contains("")) { + message = message.replace("", "" + color + delivered + "/" + toDeliver); + } else { + // Legacy + message += color + ": " + delivered + "/" + toDeliver; + } + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message); + } + if (getSettings().canTranslateNames() && !is.hasItemMeta() && !is.getItemMeta().hasDisplayName()) { + localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(), + is.getEnchantments()); + } else { + quester.sendMessage(message.replace("", ItemUtil.getName(is))); + } + } + for (final Integer n : stage.citizensToInteract) { + for (final Entry e : data.citizensInteracted.entrySet()) { + if (e.getKey().equals(n)) { + final ChatColor color = e.getValue() == false ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + "- " + Lang.get(quester.getPlayer(), "talkTo") + .replace("", depends.getNPCName(n)); + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message); + } + quester.sendMessage(message); + } + } + } + for (final Integer n : stage.citizensToKill) { + for (final Integer n2 : data.citizensKilled) { + if (n.equals(n2)) { + if (data.citizenNumKilled.size() > data.citizensKilled.indexOf(n2) + && stage.citizenNumToKill.size() > stage.citizensToKill.indexOf(n)) { + final ChatColor color = data.citizenNumKilled.get(data.citizensKilled.indexOf(n2)) + < stage.citizenNumToKill.get(stage.citizensToKill.indexOf(n)) + ? ChatColor.GREEN : ChatColor.GRAY; + String message = color + "- " + Lang.get(quester.getPlayer(), "kill"); + if (message.contains("")) { + message = message.replace("", depends.getNPCName(n)); + } else { + message += " " + depends.getNPCName(n); + } + if (message.contains("")) { + message = message.replace("", "" + color + + data.citizenNumKilled.get(stage.citizensToKill.indexOf(n)) + "/" + + stage.citizenNumToKill.get(stage.citizensToKill.indexOf(n))); + } else { + // Legacy + message += color + ": " + data.citizenNumKilled.get(stage.citizensToKill.indexOf(n)) + "/" + + stage.citizenNumToKill.get(stage.citizensToKill.indexOf(n)); + } + if (depends.getPlaceholderApi() != null) { + message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message); + } + quester.sendMessage(message); + } + } + } + } if (stage.cowsToMilk != null) { final ChatColor color = data.getCowsMilked() < stage.cowsToMilk ? ChatColor.GREEN : ChatColor.GRAY; String message = color + "- " + Lang.get(quester.getPlayer(), "milkCow"); @@ -1327,77 +1401,6 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener } quester.sendMessage(message); } - int index = 0; - for (final ItemStack is : stage.itemsToDeliver) { - int delivered = 0; - if (data.itemsDelivered.size() > index) { - delivered = data.itemsDelivered.get(index).getAmount(); - } - final int toDeliver = is.getAmount(); - final Integer npc = stage.itemDeliveryTargets.get(index); - index++; - final ChatColor color = delivered < toDeliver ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + "- " + Lang.get(quester.getPlayer(), "deliver").replace("", depends.getNPCName(npc)); - if (message.contains("")) { - message = message.replace("", "" + color + delivered + "/" + toDeliver); - } else { - // Legacy - message += color + ": " + delivered + "/" + toDeliver; - } - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message); - } - if (getSettings().canTranslateNames() && !is.hasItemMeta() && !is.getItemMeta().hasDisplayName()) { - localeManager.sendMessage(quester.getPlayer(), message, is.getType(), is.getDurability(), - is.getEnchantments()); - } else { - quester.sendMessage(message.replace("", ItemUtil.getName(is))); - } - } - for (final Integer n : stage.citizensToInteract) { - for (final Entry e : data.citizensInteracted.entrySet()) { - if (e.getKey().equals(n)) { - final ChatColor color = e.getValue() == false ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + "- " + Lang.get(quester.getPlayer(), "talkTo") - .replace("", depends.getNPCName(n)); - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message); - } - quester.sendMessage(message); - } - } - } - for (final Integer n : stage.citizensToKill) { - for (final Integer n2 : data.citizensKilled) { - if (n.equals(n2)) { - if (data.citizenNumKilled.size() > data.citizensKilled.indexOf(n2) - && stage.citizenNumToKill.size() > stage.citizensToKill.indexOf(n)) { - final ChatColor color = data.citizenNumKilled.get(data.citizensKilled.indexOf(n2)) - < stage.citizenNumToKill.get(stage.citizensToKill.indexOf(n)) - ? ChatColor.GREEN : ChatColor.GRAY; - String message = color + "- " + Lang.get(quester.getPlayer(), "kill"); - if (message.contains("")) { - message = message.replace("", depends.getNPCName(n)); - } else { - message += " " + depends.getNPCName(n); - } - if (message.contains("")) { - message = message.replace("", "" + color - + data.citizenNumKilled.get(stage.citizensToKill.indexOf(n)) + "/" - + stage.citizenNumToKill.get(stage.citizensToKill.indexOf(n))); - } else { - // Legacy - message += color + ": " + data.citizenNumKilled.get(stage.citizensToKill.indexOf(n)) + "/" - + stage.citizenNumToKill.get(stage.citizensToKill.indexOf(n)); - } - if (depends.getPlaceholderApi() != null) { - message = PlaceholderAPI.setPlaceholders(quester.getPlayer(), message); - } - quester.sendMessage(message); - } - } - } - } for (final Entry e : stage.mobsToTame.entrySet()) { for (final Entry e2 : data.mobsTamed.entrySet()) { if (e.getKey().equals(e2.getKey())) { diff --git a/main/src/main/java/me/blackvein/quests/storage/implementation/file/SeparatedYamlStorage.java b/main/src/main/java/me/blackvein/quests/storage/implementation/file/SeparatedYamlStorage.java index 57b001e3a..d369a68d3 100644 --- a/main/src/main/java/me/blackvein/quests/storage/implementation/file/SeparatedYamlStorage.java +++ b/main/src/main/java/me/blackvein/quests/storage/implementation/file/SeparatedYamlStorage.java @@ -311,12 +311,61 @@ public class SeparatedYamlStorage implements StorageImplementation { } } if (questSec.contains("item-consume-amounts")) { - final List consumeAmounts = questSec.getIntegerList("item-consume-amounts"); + /*final List consumeAmounts = questSec.getIntegerList("item-consume-amounts"); for (int i = 0; i < consumeAmounts.size(); i++) { if (i < quester.getCurrentStage(quest).getItemsToConsume().size()) { - quester.getQuestData(quest).itemsConsumed.put(quester.getCurrentStage(quest) - .getItemsToConsume().get(i), consumeAmounts.get(i)); + quester.getQuestData(quest).itemsConsumed.set(i, quester.getCurrentStage(quest) + .getItemsToConsume().get(i).clone()); } + }*/ + final List consumeAmounts = questSec.getIntegerList("item-consume-amounts"); + int index = 0; + for (final int amt : consumeAmounts) { + final ItemStack is = quester.getCurrentStage(quest).getItemsToConsume().get(index); + final ItemStack temp = is.clone(); + temp.setAmount(amt); + if (quester.getQuestData(quest).itemsConsumed.size() > 0) { + quester.getQuestData(quest).itemsConsumed.set(index, temp); + } + index++; + } + } + + if (questSec.contains("item-delivery-amounts")) { + final List deliveryAmounts = questSec.getIntegerList("item-delivery-amounts"); + int index = 0; + for (final int amt : deliveryAmounts) { + final ItemStack is = quester.getCurrentStage(quest).getItemsToDeliver().get(index); + final ItemStack temp = new ItemStack(is.getType(), amt, is.getDurability()); + try { + temp.addEnchantments(is.getEnchantments()); + } catch (final Exception e) { + plugin.getLogger().warning("Unable to add enchantment(s) " + is.getEnchantments().toString() + + " to delivery item " + is.getType().name() + " x " + amt + " for quest " + + quest.getName()); + } + temp.setItemMeta(is.getItemMeta()); + if (quester.getQuestData(quest).itemsDelivered.size() > 0) { + quester.getQuestData(quest).itemsDelivered.set(index, temp); + } + index++; + } + } + if (questSec.contains("citizen-ids-to-talk-to")) { + final List ids = questSec.getIntegerList("citizen-ids-to-talk-to"); + final List has = questSec.getBooleanList("has-talked-to"); + for (final int i : ids) { + quester.getQuestData(quest).citizensInteracted.put(i, has.get(ids.indexOf(i))); + } + } + if (questSec.contains("citizen-ids-killed")) { + final List ids = questSec.getIntegerList("citizen-ids-killed"); + final List num = questSec.getIntegerList("citizen-amounts-killed"); + quester.getQuestData(quest).citizensKilled.clear(); + quester.getQuestData(quest).citizenNumKilled.clear(); + for (final int i : ids) { + quester.getQuestData(quest).citizensKilled.add(i); + quester.getQuestData(quest).citizenNumKilled.add(num.get(ids.indexOf(i))); } } if (questSec.contains("cows-milked")) { @@ -358,43 +407,6 @@ public class SeparatedYamlStorage implements StorageImplementation { } } } - if (questSec.contains("item-delivery-amounts")) { - final List deliveryAmounts = questSec.getIntegerList("item-delivery-amounts"); - int index = 0; - for (final int amt : deliveryAmounts) { - final ItemStack is = quester.getCurrentStage(quest).getItemsToDeliver().get(index); - final ItemStack temp = new ItemStack(is.getType(), amt, is.getDurability()); - try { - temp.addEnchantments(is.getEnchantments()); - } catch (final Exception e) { - plugin.getLogger().warning("Unable to add enchantment(s) " + is.getEnchantments().toString() - + " to delivery item " + is.getType().name() + " x " + amt + " for quest " - + quest.getName()); - } - temp.setItemMeta(is.getItemMeta()); - if (quester.getQuestData(quest).itemsDelivered.size() > 0) { - quester.getQuestData(quest).itemsDelivered.set(index, temp); - } - index++; - } - } - if (questSec.contains("citizen-ids-to-talk-to")) { - final List ids = questSec.getIntegerList("citizen-ids-to-talk-to"); - final List has = questSec.getBooleanList("has-talked-to"); - for (final int i : ids) { - quester.getQuestData(quest).citizensInteracted.put(i, has.get(ids.indexOf(i))); - } - } - if (questSec.contains("citizen-ids-killed")) { - final List ids = questSec.getIntegerList("citizen-ids-killed"); - final List num = questSec.getIntegerList("citizen-amounts-killed"); - quester.getQuestData(quest).citizensKilled.clear(); - quester.getQuestData(quest).citizenNumKilled.clear(); - for (final int i : ids) { - quester.getQuestData(quest).citizensKilled.add(i); - quester.getQuestData(quest).citizenNumKilled.add(num.get(ids.indexOf(i))); - } - } if (questSec.contains("locations-to-reach")) { final LinkedList locations = new LinkedList(); final List has = questSec.getBooleanList("has-reached-location");