Permit use of duplicate items for deliver-item objectives, fixes #985

This commit is contained in:
PikaMug 2019-11-10 23:53:36 -05:00
parent a1a22758e3
commit 7d90b19171
4 changed files with 75 additions and 126 deletions

View File

@ -398,21 +398,29 @@ public class QuestData {
} }
}; };
public LinkedHashMap<ItemStack, Integer> itemsDelivered = new LinkedHashMap<ItemStack, Integer>() { public LinkedList<ItemStack> itemsDelivered = new LinkedList<ItemStack>() {
private static final long serialVersionUID = 2712497347022734646L; private static final long serialVersionUID = 2712497347022734646L;
@Override @Override
public Integer put(ItemStack key, Integer val) { public ItemStack set(int index, ItemStack key) {
Integer data = super.put(key, val); ItemStack data = super.set(index, key);
if (doJournalUpdate) if (doJournalUpdate)
quester.updateJournal(); quester.updateJournal();
return data; return data;
} }
@Override @Override
public Integer remove(Object key) { public boolean add(ItemStack key) {
Integer i = super.remove(key); boolean data = super.add(key);
if (doJournalUpdate)
quester.updateJournal();
return data;
}
@Override
public boolean remove(Object key) {
boolean i = super.remove(key);
if (doJournalUpdate) if (doJournalUpdate)
quester.updateJournal(); quester.updateJournal();
return i; return i;
@ -426,10 +434,11 @@ public class QuestData {
} }
@Override @Override
public void putAll(Map<? extends ItemStack, ? extends Integer> m) { public boolean addAll(Collection<? extends ItemStack> m) {
super.putAll(m); boolean i = super.addAll(m);
if (doJournalUpdate) if (doJournalUpdate)
quester.updateJournal(); quester.updateJournal();
return i;
} }
}; };

View File

@ -790,23 +790,20 @@ public class Quester {
} }
int index = 0; int index = 0;
for (ItemStack is : getCurrentStage(quest).itemsToDeliver) { for (ItemStack is : getCurrentStage(quest).itemsToDeliver) {
int delivered = 0; int delivered = getQuestData(quest).itemsDelivered.get(index).getAmount();
if (getQuestData(quest).itemsDelivered.containsKey(is)) { int toDeliver = is.getAmount();
delivered = getQuestData(quest).itemsDelivered.get(is);
}
int amt = is.getAmount();
Integer npc = getCurrentStage(quest).itemDeliveryTargets.get(index); Integer npc = getCurrentStage(quest).itemDeliveryTargets.get(index);
index++; index++;
if (delivered < amt) { if (delivered < toDeliver) {
String obj = Lang.get(getPlayer(), "deliver"); String obj = Lang.get(getPlayer(), "deliver");
obj = obj.replace("<item>", ItemUtil.getName(is) + ChatColor.GREEN); obj = obj.replace("<item>", ItemUtil.getName(is) + ChatColor.GREEN);
obj = obj.replace("<npc>", plugin.getNPCName(npc)); obj = obj.replace("<npc>", plugin.getNPCName(npc));
unfinishedObjectives.add(ChatColor.GREEN + obj + ": " + delivered + "/" + amt); unfinishedObjectives.add(ChatColor.GREEN + obj + ": " + delivered + "/" + toDeliver);
} else { } else {
String obj = Lang.get(getPlayer(), "deliver"); String obj = Lang.get(getPlayer(), "deliver");
obj = obj.replace("<item>", ItemUtil.getName(is) + ChatColor.GRAY); obj = obj.replace("<item>", ItemUtil.getName(is) + ChatColor.GRAY);
obj = obj.replace("<npc>", plugin.getNPCName(npc)); obj = obj.replace("<npc>", plugin.getNPCName(npc));
finishedObjectives.add(ChatColor.GRAY + obj + ": " + delivered + "/" + amt); finishedObjectives.add(ChatColor.GRAY + obj + ": " + delivered + "/" + toDeliver);
} }
} }
for (Integer n : getCurrentStage(quest).citizensToInteract) { for (Integer n : getCurrentStage(quest).citizensToInteract) {
@ -1704,9 +1701,12 @@ public class Quester {
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void deliverToNPC(Quest quest, NPC n, ItemStack i) { public void deliverToNPC(Quest quest, NPC n, ItemStack i) {
if (n == null) {
return;
}
int currentIndex = -1; int currentIndex = -1;
LinkedList<Integer> matches = new LinkedList<Integer>(); LinkedList<Integer> matches = new LinkedList<Integer>();
for (ItemStack is : getQuestData(quest).itemsDelivered.keySet()) { for (ItemStack is : getQuestData(quest).itemsDelivered) {
currentIndex++; currentIndex++;
if (ItemUtil.compareItems(i, is, true) == 0) { if (ItemUtil.compareItems(i, is, true) == 0) {
matches.add(currentIndex); matches.add(currentIndex);
@ -1716,27 +1716,28 @@ public class Quester {
if (!matches.isEmpty()) { if (!matches.isEmpty()) {
Player player = getPlayer(); Player player = getPlayer();
for (Integer match : matches) { for (Integer match : matches) {
LinkedList<ItemStack> items = new LinkedList<ItemStack>(getQuestData(quest).itemsDelivered.keySet()); LinkedList<ItemStack> items = new LinkedList<ItemStack>(getQuestData(quest).itemsDelivered);
LinkedList<Integer> amounts = new LinkedList<Integer>(getQuestData(quest).itemsDelivered.values());
if (!getCurrentStage(quest).getItemDeliveryTargets().get(match).equals(n.getId())) { if (!getCurrentStage(quest).getItemDeliveryTargets().get(match).equals(n.getId())) {
continue; continue;
} }
ItemStack found = items.get(match); ItemStack found = items.get(match);
int amount = amounts.get(match); int amount = found.getAmount();
int req = getCurrentStage(quest).itemsToDeliver.get(match).getAmount(); int toDeliver = getCurrentStage(quest).itemsToDeliver.get(match).getAmount();
Material m = i.getType(); Material m = i.getType();
if (amount < req) { if (amount < toDeliver) {
int index = player.getInventory().first(i); int index = player.getInventory().first(i);
if (index == -1) { if (index == -1) {
Bukkit.getLogger().warning("Uh oh! " + i.getType().name() // Already delivered in previous loop
+ " suddenly disappeared from the inventory of " + player.getName()
+ " when delivering for quest " + quest.getName());
return; return;
} }
if ((i.getAmount() + amount) >= req) { if ((i.getAmount() + amount) >= toDeliver) {
getQuestData(quest).itemsDelivered.put(found, req); ItemStack newStack = found;
if ((i.getAmount() + amount) >= req) { found.setAmount(toDeliver);
i.setAmount(i.getAmount() - (req - amount)); // Take away remaining amount to be delivered getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack);
if ((i.getAmount() + amount) >= toDeliver) {
// Take away remaining amount to be delivered
i.setAmount(i.getAmount() - (toDeliver - amount));
player.getInventory().setItem(index, i); player.getInventory().setItem(index, i);
} else { } else {
player.getInventory().setItem(index, null); player.getInventory().setItem(index, null);
@ -1747,20 +1748,21 @@ public class Quester {
// Multiplayer // Multiplayer
dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> { dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> {
q.getQuestData(quest).itemsDelivered.put(found, req); q.getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack);
q.finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, q.finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null,
null, null, null, null); null, null, null, null);
return null; return null;
}); });
} else { } else {
getQuestData(quest).itemsDelivered.put(found, (amount + i.getAmount())); ItemStack newStack = found;
found.setAmount(amount + i.getAmount());
getQuestData(quest).itemsDelivered.set(items.indexOf(found), newStack);
player.getInventory().setItem(index, null); player.getInventory().setItem(index, null);
player.updateInventory(); player.updateInventory();
String[] message = Quests.parseStringWithPossibleLineBreaks(getCurrentStage(quest) String[] message = ConfigUtil.parseStringWithPossibleLineBreaks(getCurrentStage(quest)
.deliverMessages.get(new Random().nextInt(getCurrentStage(quest).deliverMessages .deliverMessages.get(new Random().nextInt(getCurrentStage(quest).deliverMessages
.size())), plugin.getDependencies().getCitizens().getNPCRegistry() .size())), plugin.getDependencies().getCitizens().getNPCRegistry()
.getById(getCurrentStage(quest).itemDeliveryTargets.get(getCurrentStage(quest) .getById(getCurrentStage(quest).itemDeliveryTargets.get(items.indexOf(found))));
.itemsToDeliver.indexOf(found))));
player.sendMessage(message); player.sendMessage(message);
} }
} }
@ -1768,71 +1770,6 @@ public class Quester {
} }
} }
/**
* 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 i The item being delivered
* @deprecated Use deliverToNPC()
*/
public void deliverItem(Quest quest, ItemStack i) {
Player player = getPlayer();
ItemStack found = null;
for (ItemStack is : getQuestData(quest).itemsDelivered.keySet()) {
if (ItemUtil.compareItems(i, is, true) == 0) {
found = is;
break;
}
}
if (found != null) {
int amount = getQuestData(quest).itemsDelivered.get(found);
if (getCurrentStage(quest).itemsToDeliver.indexOf(found) < 0) {
plugin.getLogger().severe("Index out of bounds while delivering " + found.getType() + " x "
+ found.getAmount() + " for quest " + quest.getName() + " with " + i.getType() + " x "
+ i.getAmount() + " already delivered. List amount reports value of " + amount
+ ". Please report this error on Github!");
player.sendMessage("Quests had a problem delivering your item, please contact an administrator!");
return;
}
int req = getCurrentStage(quest).itemsToDeliver.get(getCurrentStage(quest).itemsToDeliver.indexOf(found))
.getAmount();
Material m = i.getType();
if (amount < req) {
if ((i.getAmount() + amount) > req) {
getQuestData(quest).itemsDelivered.put(found, req);
if ((i.getAmount() + amount) > req) {
int index = player.getInventory().first(i);
i.setAmount(i.getAmount() - (req - amount)); // Take away remaining amount to be delivered
player.getInventory().setItem(index, i);
} else {
player.getInventory().setItem(player.getInventory().first(i), null);
}
player.updateInventory();
finishObjective(quest, "deliverItem", new ItemStack(m, 1), found, null, null, null, null, null,
null, null, null);
// Multiplayer
final ItemStack finalFound = found;
dispatchMultiplayerObjectives(quest, getCurrentStage(quest), (Quester q) -> {
q.getQuestData(quest).itemsDelivered.put(finalFound, req);
q.finishObjective(quest, "deliverItem", new ItemStack(m, 1), finalFound, null, null, null,
null, null, null, null, null);
return null;
});
} else {
getQuestData(quest).itemsDelivered.put(found, (amount + i.getAmount()));
player.getInventory().setItem(player.getInventory().first(i), null);
player.updateInventory();
String[] message = Quests.parseStringWithPossibleLineBreaks(getCurrentStage(quest).deliverMessages
.get(new Random().nextInt(getCurrentStage(quest).deliverMessages.size())), plugin
.getDependencies().getCitizens().getNPCRegistry().getById(getCurrentStage(quest)
.itemDeliveryTargets.get(getCurrentStage(quest).itemsToDeliver.indexOf(found))));
player.sendMessage(message);
}
}
}
}
/** /**
* Mark NPC as interacted with if Quester has such an objective * Mark NPC as interacted with if Quester has such an objective
* *
@ -2300,55 +2237,50 @@ public class Quester {
data.setDoJournalUpdate(false); data.setDoJournalUpdate(false);
if (quest.getStage(stage).blocksToBreak.isEmpty() == false) { if (quest.getStage(stage).blocksToBreak.isEmpty() == false) {
for (ItemStack i : quest.getStage(stage).blocksToBreak) { for (ItemStack i : quest.getStage(stage).blocksToBreak) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
if (data.blocksBroken.indexOf(i) != -1) { if (data.blocksBroken.indexOf(i) != -1) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksBroken.set(data.blocksBroken.indexOf(temp), temp); data.blocksBroken.set(data.blocksBroken.indexOf(temp), temp);
} else { } else {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksBroken.add(temp); data.blocksBroken.add(temp);
} }
} }
} }
if (quest.getStage(stage).blocksToDamage.isEmpty() == false) { if (quest.getStage(stage).blocksToDamage.isEmpty() == false) {
for (ItemStack i : quest.getStage(stage).blocksToDamage) { for (ItemStack i : quest.getStage(stage).blocksToDamage) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
if (data.blocksDamaged.indexOf(i) != -1) { if (data.blocksDamaged.indexOf(i) != -1) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksDamaged.set(data.blocksDamaged.indexOf(temp), temp); data.blocksDamaged.set(data.blocksDamaged.indexOf(temp), temp);
} else { } else {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksDamaged.add(temp); data.blocksDamaged.add(temp);
} }
} }
} }
if (quest.getStage(stage).blocksToPlace.isEmpty() == false) { if (quest.getStage(stage).blocksToPlace.isEmpty() == false) {
for (ItemStack i : quest.getStage(stage).blocksToPlace) { for (ItemStack i : quest.getStage(stage).blocksToPlace) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
if (data.blocksPlaced.indexOf(i) != -1) { if (data.blocksPlaced.indexOf(i) != -1) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksPlaced.set(data.blocksPlaced.indexOf(temp), temp); data.blocksPlaced.set(data.blocksPlaced.indexOf(temp), temp);
} else { } else {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksPlaced.add(temp); data.blocksPlaced.add(temp);
} }
} }
} }
if (quest.getStage(stage).blocksToUse.isEmpty() == false) { if (quest.getStage(stage).blocksToUse.isEmpty() == false) {
for (ItemStack i : quest.getStage(stage).blocksToUse) { for (ItemStack i : quest.getStage(stage).blocksToUse) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
if (data.blocksUsed.indexOf(i) != -1) { if (data.blocksUsed.indexOf(i) != -1) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksUsed.set(data.blocksUsed.indexOf(temp), temp); data.blocksUsed.set(data.blocksUsed.indexOf(temp), temp);
} else { } else {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksUsed.add(temp); data.blocksUsed.add(temp);
} }
} }
} }
if (quest.getStage(stage).blocksToCut.isEmpty() == false) { if (quest.getStage(stage).blocksToCut.isEmpty() == false) {
for (ItemStack i : quest.getStage(stage).blocksToCut) { for (ItemStack i : quest.getStage(stage).blocksToCut) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
if (data.blocksCut.indexOf(i) != -1) { if (data.blocksCut.indexOf(i) != -1) {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksCut.set(data.blocksCut.indexOf(temp), temp); data.blocksCut.set(data.blocksCut.indexOf(temp), temp);
} else { } else {
ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
data.blocksCut.add(temp); data.blocksCut.add(temp);
} }
} }
@ -2390,8 +2322,11 @@ public class Quester {
data.setFishCaught(0); data.setFishCaught(0);
data.setPlayersKilled(0); data.setPlayersKilled(0);
if (quest.getStage(stage).itemsToDeliver.isEmpty() == false) { if (quest.getStage(stage).itemsToDeliver.isEmpty() == false) {
for (ItemStack is : quest.getStage(stage).itemsToDeliver) { for (ItemStack i : quest.getStage(stage).itemsToDeliver) {
data.itemsDelivered.put(is, 0); ItemStack temp = new ItemStack(i.getType(), 0, i.getDurability());
temp.addEnchantments(i.getEnchantments());
temp.setItemMeta(i.getItemMeta());
data.itemsDelivered.add(temp);
} }
} }
if (quest.getStage(stage).citizensToInteract.isEmpty() == false) { if (quest.getStage(stage).citizensToInteract.isEmpty() == false) {
@ -2626,8 +2561,8 @@ public class Quester {
} }
if (questData.itemsDelivered.isEmpty() == false) { if (questData.itemsDelivered.isEmpty() == false) {
LinkedList<Integer> deliveryAmounts = new LinkedList<Integer>(); LinkedList<Integer> deliveryAmounts = new LinkedList<Integer>();
for (Entry<ItemStack, Integer> e : questData.itemsDelivered.entrySet()) { for (ItemStack m : questData.itemsDelivered) {
deliveryAmounts.add(e.getValue()); deliveryAmounts.add(m.getAmount());
} }
questSec.set("item-delivery-amounts", deliveryAmounts); questSec.set("item-delivery-amounts", deliveryAmounts);
} }
@ -3045,11 +2980,14 @@ public class Quester {
} }
if (questSec.contains("item-delivery-amounts")) { if (questSec.contains("item-delivery-amounts")) {
List<Integer> deliveryAmounts = questSec.getIntegerList("item-delivery-amounts"); List<Integer> deliveryAmounts = questSec.getIntegerList("item-delivery-amounts");
for (int i = 0; i < deliveryAmounts.size(); i++) { int index = 0;
if (i < getCurrentStage(quest).itemsToDeliver.size()) { for (int amt : deliveryAmounts) {
getQuestData(quest).itemsDelivered.put(getCurrentStage(quest).itemsToDeliver ItemStack is = getCurrentStage(quest).itemsToDeliver.get(index);
.get(i), deliveryAmounts.get(i)); is.setAmount(amt);
if (getQuestData(quest).itemsDelivered.size() > 0) {
getQuestData(quest).itemsDelivered.set(index, is);
} }
index++;
} }
} }
if (questSec.contains("citizen-ids-to-talk-to")) { if (questSec.contains("citizen-ids-to-talk-to")) {

View File

@ -987,20 +987,20 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener
int index = 0; int index = 0;
for (ItemStack is : stage.itemsToDeliver) { for (ItemStack is : stage.itemsToDeliver) {
int delivered = 0; int delivered = 0;
if (data.itemsDelivered.containsKey(is)) { if (data.itemsDelivered.size() > index) {
delivered = data.itemsDelivered.get(is); delivered = data.itemsDelivered.get(index).getAmount();
} }
int amt = is.getAmount(); int toDeliver = is.getAmount();
Integer npc = stage.itemDeliveryTargets.get(index); Integer npc = stage.itemDeliveryTargets.get(index);
index++; index++;
ChatColor color = delivered < amt ? ChatColor.GREEN : ChatColor.GRAY; ChatColor color = delivered < toDeliver ? ChatColor.GREEN : ChatColor.GRAY;
String message = ""; String message = "";
if (!ignoreOverrides && quester.getCurrentStage(quest).objectiveOverride != null) { if (!ignoreOverrides && quester.getCurrentStage(quest).objectiveOverride != null) {
message = color + quester.getCurrentStage(quest).objectiveOverride message = color + quester.getCurrentStage(quest).objectiveOverride
+ color + ": " + delivered + "/" + is.getAmount(); + color + ": " + delivered + "/" + toDeliver;
} else { } else {
message = color + Lang.get(quester.getPlayer(), "deliver") message = color + Lang.get(quester.getPlayer(), "deliver")
+ color + ": " + delivered + "/" + is.getAmount(); + color + ": " + delivered + "/" + toDeliver;
} }
message = message.replace("<npc>", depends.getNPCName(npc)); message = message.replace("<npc>", depends.getNPCName(npc));
if (depends.getPlaceholderApi() != null) { if (depends.getPlaceholderApi() != null) {
@ -2448,9 +2448,10 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener
if (getDependencies().getCitizens() != null) { if (getDependencies().getCitizens() != null) {
NPC npc = CitizensAPI.getNPCRegistry().getById(npcId); NPC npc = CitizensAPI.getNPCRegistry().getById(npcId);
if (npc != null) { if (npc != null) {
oStage.getItemsToDeliver().add(stack); oStage.itemsToDeliver.add(stack);
oStage.getItemDeliveryTargets().add(npcId); oStage.itemDeliveryTargets.add(npcId);
oStage.deliverMessages.addAll(deliveryMessages); oStage.deliverMessages.addAll(deliveryMessages);
ItemStack s = oStage.itemsToDeliver.get(index-1);
} else { } else {
stageFailed("Citizens was not installed for ID " + npcId stageFailed("Citizens was not installed for ID " + npcId
+ " inside npc-delivery-ids: inside Stage " + s2 + " inside npc-delivery-ids: inside Stage " + s2
@ -2479,8 +2480,8 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener
if (getDependencies().getCitizens() != null) { if (getDependencies().getCitizens() != null) {
NPC npc = CitizensAPI.getNPCRegistry().getById(npcId); NPC npc = CitizensAPI.getNPCRegistry().getById(npcId);
if (npc != null) { if (npc != null) {
oStage.getItemsToDeliver().add(is); oStage.itemsToDeliver.add(is);
oStage.getItemDeliveryTargets().add(npcId); oStage.itemDeliveryTargets.add(npcId);
oStage.deliverMessages.addAll(deliveryMessages); oStage.deliverMessages.addAll(deliveryMessages);
} else { } else {
stageFailed("" + npcId + " inside npc-delivery-ids: inside Stage " stageFailed("" + npcId + " inside npc-delivery-ids: inside Stage "

View File

@ -83,6 +83,7 @@ public class NpcListener implements Listener {
if (id.equals(clicked.getId())) { if (id.equals(clicked.getId())) {
quester.deliverToNPC(quest, clicked, hand); quester.deliverToNPC(quest, clicked, hand);
delivery = true; delivery = true;
return;
} }
} }
} else if (!hand.getType().equals(Material.AIR)) { } else if (!hand.getType().equals(Material.AIR)) {