Resolve impasse from Enchanted Books, fixes #1825

This commit is contained in:
PikaMug 2021-10-31 06:26:36 -04:00
parent 5b0ab9c817
commit 095fd8c419
6 changed files with 115 additions and 50 deletions

View File

@ -131,7 +131,7 @@
<dependency> <dependency>
<groupId>com.github.PikaMug</groupId> <groupId>com.github.PikaMug</groupId>
<artifactId>LocaleLib</artifactId> <artifactId>LocaleLib</artifactId>
<version>2.2</version> <version>2.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>

View File

@ -12,12 +12,14 @@
package me.blackvein.quests; package me.blackvein.quests;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
/**
* Quest objective data for a specified Quester
*/
public class QuestData { public class QuestData {
private final Quester quester; private final Quester quester;

View File

@ -54,6 +54,7 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.Crops; import org.bukkit.material.Crops;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -429,7 +430,6 @@ public class Quester implements Comparable<Quester> {
* @param quest The quest to start * @param quest The quest to start
* @param ignoreRequirements Whether to ignore Requirements * @param ignoreRequirements Whether to ignore Requirements
*/ */
@SuppressWarnings("deprecation")
public void takeQuest(final Quest quest, final boolean ignoreRequirements) { public void takeQuest(final Quest quest, final boolean ignoreRequirements) {
if (quest == null) { if (quest == null) {
return; return;
@ -1926,6 +1926,67 @@ public class Quester implements Comparable<Quester> {
} }
} }
/**
* Mark book as enchanted if Quester has such an objective
*
* @param quest The quest for which the item is being enchanted
* @param itemStack The book being enchanted
*/
public void enchantBook(final Quest quest, final ItemStack itemStack,
final Map<Enchantment, Integer> enchantsToAdd) {
int currentIndex = -1;
final LinkedList<Integer> matches = new LinkedList<>();
for (final ItemStack is : getQuestData(quest).itemsEnchanted) {
currentIndex++;
if (is.getItemMeta() instanceof EnchantmentStorageMeta) {
if (((EnchantmentStorageMeta)is.getItemMeta()).getStoredEnchants().equals(enchantsToAdd)) {
matches.add(currentIndex);
}
}
}
if (matches.isEmpty()) {
return;
}
for (final Integer match : matches) {
final LinkedList<ItemStack> items = new LinkedList<>(getQuestData(quest).itemsEnchanted);
final ItemStack found = items.get(match);
final int amount = found.getAmount();
final int toEnchant = getCurrentStage(quest).itemsToEnchant.get(match).getAmount();
final ObjectiveType type = ObjectiveType.ENCHANT_ITEM;
final QuesterPreUpdateObjectiveEvent preEvent = new QuesterPreUpdateObjectiveEvent(this, quest,
new Objective(type, amount, toEnchant));
plugin.getServer().getPluginManager().callEvent(preEvent);
final int newAmount = itemStack.getAmount() + amount;
final Material m = itemStack.getType();
if (amount < toEnchant) {
if (newAmount >= toEnchant) {
found.setAmount(toEnchant);
getQuestData(quest).itemsEnchanted.set(items.indexOf(found), found);
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).itemsEnchanted.set(items.indexOf(found), found);
q.finishObjective(quest, new Objective(type, new ItemStack(m, 1), found), null, null, null,
null, null, null, null);
return null;
});
} else {
found.setAmount(newAmount);
getQuestData(quest).itemsEnchanted.set(items.indexOf(found), found);
}
return;
}
final QuesterPostUpdateObjectiveEvent postEvent = new QuesterPostUpdateObjectiveEvent(this, quest,
new Objective(type, itemStack.getAmount() + amount, toEnchant));
plugin.getServer().getPluginManager().callEvent(postEvent);
}
}
/** /**
* Mark item as enchanted if Quester has such an objective * Mark item as enchanted if Quester has such an objective
* *
@ -1935,6 +1996,7 @@ public class Quester implements Comparable<Quester> {
public void enchantItem(final Quest quest, final ItemStack itemStack) { public void enchantItem(final Quest quest, final ItemStack itemStack) {
int currentIndex = -1; int currentIndex = -1;
final LinkedList<Integer> matches = new LinkedList<>(); final LinkedList<Integer> matches = new LinkedList<>();
if (!itemStack.getType().equals(Material.BOOK)) {
for (final ItemStack is : getQuestData(quest).itemsEnchanted) { for (final ItemStack is : getQuestData(quest).itemsEnchanted) {
currentIndex++; currentIndex++;
if (!is.getEnchantments().isEmpty()) { if (!is.getEnchantments().isEmpty()) {
@ -1947,6 +2009,7 @@ public class Quester implements Comparable<Quester> {
} }
} }
} }
}
if (matches.isEmpty()) { if (matches.isEmpty()) {
return; return;
} }
@ -2113,7 +2176,6 @@ public class Quester implements Comparable<Quester> {
* @param npc The NPC being delivered to * @param npc The NPC being delivered to
* @param itemStack The item being delivered * @param itemStack The item being delivered
*/ */
@SuppressWarnings("deprecation")
public void deliverToNPC(final Quest quest, final NPC npc, final ItemStack itemStack) { public void deliverToNPC(final Quest quest, final NPC npc, final ItemStack itemStack) {
if (npc == null) { if (npc == null) {
return; return;
@ -3283,12 +3345,12 @@ public class Quester implements Comparable<Quester> {
} }
} }
if (!quest.getStage(stage).citizensToKill.isEmpty()) { if (!quest.getStage(stage).citizensToKill.isEmpty()) {
for (final Integer toKill : quest.getStage(stage).citizensToKill) { for (final Integer ignored : quest.getStage(stage).citizensToKill) {
data.citizensNumKilled.add(0); data.citizensNumKilled.add(0);
} }
} }
if (!quest.getStage(stage).mobsToKill.isEmpty()) { if (!quest.getStage(stage).mobsToKill.isEmpty()) {
for (final EntityType toKill : quest.getStage(stage).mobsToKill) { for (final EntityType ignored : quest.getStage(stage).mobsToKill) {
data.mobNumKilled.add(0); data.mobNumKilled.add(0);
} }
} }

View File

@ -153,11 +153,7 @@ public class ItemListener implements Listener {
if (plugin.canUseQuests(evt.getEnchanter().getUniqueId())) { if (plugin.canUseQuests(evt.getEnchanter().getUniqueId())) {
final ItemStack enchantedItem = evt.getItem().clone(); final ItemStack enchantedItem = evt.getItem().clone();
enchantedItem.setAmount(1); enchantedItem.setAmount(1);
try { enchantedItem.addUnsafeEnchantments(evt.getEnchantsToAdd());
enchantedItem.addEnchantments(evt.getEnchantsToAdd());
} catch (final IllegalArgumentException e) {
// Ignore
}
final Quester quester = plugin.getQuester(evt.getEnchanter().getUniqueId()); final Quester quester = plugin.getQuester(evt.getEnchanter().getUniqueId());
final ObjectiveType type = ObjectiveType.ENCHANT_ITEM; final ObjectiveType type = ObjectiveType.ENCHANT_ITEM;
final Set<String> dispatchedQuestIDs = new HashSet<>(); final Set<String> dispatchedQuestIDs = new HashSet<>();
@ -168,13 +164,21 @@ public class ItemListener implements Listener {
if (quester.getCurrentQuests().containsKey(quest) if (quester.getCurrentQuests().containsKey(quest)
&& quester.getCurrentStage(quest).containsObjective(type)) { && quester.getCurrentStage(quest).containsObjective(type)) {
if (enchantedItem.getType().equals(Material.BOOK)) {
quester.enchantBook(quest, enchantedItem, evt.getEnchantsToAdd());
} else {
quester.enchantItem(quest, enchantedItem); quester.enchantItem(quest, enchantedItem);
} }
}
dispatchedQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, type, (final Quester q, final Quest cq) -> { dispatchedQuestIDs.addAll(quester.dispatchMultiplayerEverything(quest, type, (final Quester q, final Quest cq) -> {
if (!dispatchedQuestIDs.contains(cq.getId())) { if (!dispatchedQuestIDs.contains(cq.getId())) {
if (enchantedItem.getType().equals(Material.BOOK)) {
q.enchantBook(cq, enchantedItem, evt.getEnchantsToAdd());
} else {
q.enchantItem(cq, enchantedItem); q.enchantItem(cq, enchantedItem);
} }
}
return null; return null;
})); }));
} }

View File

@ -173,6 +173,8 @@ public class ItemUtil {
return -5; return -5;
} }
if (one.getType().equals(Material.ENCHANTED_BOOK)) { if (one.getType().equals(Material.ENCHANTED_BOOK)) {
if (one.getItemMeta() instanceof EnchantmentStorageMeta
&& two.getItemMeta() instanceof EnchantmentStorageMeta) {
final EnchantmentStorageMeta esMeta1 = (EnchantmentStorageMeta) one.getItemMeta(); final EnchantmentStorageMeta esMeta1 = (EnchantmentStorageMeta) one.getItemMeta();
final EnchantmentStorageMeta esMeta2 = (EnchantmentStorageMeta) two.getItemMeta(); final EnchantmentStorageMeta esMeta2 = (EnchantmentStorageMeta) two.getItemMeta();
if (esMeta1.hasStoredEnchants() && !esMeta2.hasStoredEnchants()) { if (esMeta1.hasStoredEnchants() && !esMeta2.hasStoredEnchants()) {
@ -182,6 +184,7 @@ public class ItemUtil {
return -6; return -6;
} }
} }
}
return 0; return 0;
} }
@ -453,45 +456,39 @@ public class ItemUtil {
* @return formatted string, or null if invalid stack * @return formatted string, or null if invalid stack
*/ */
public static String serializeItemStack(final ItemStack is) { public static String serializeItemStack(final ItemStack is) {
String serial; final StringBuilder serial;
if (is == null) { if (is == null) {
return null; return null;
} }
serial = "name-" + is.getType().name(); serial = new StringBuilder("name-" + is.getType().name());
serial += ":amount-" + is.getAmount(); serial.append(":amount-").append(is.getAmount());
if (is.getDurability() != 0) { if (is.getDurability() != 0) {
serial += ":data-" + is.getDurability(); serial.append(":data-").append(is.getDurability());
} }
if (!is.getEnchantments().isEmpty()) { if (!is.getEnchantments().isEmpty()) {
for (final Entry<Enchantment, Integer> e : is.getEnchantments().entrySet()) { for (final Entry<Enchantment, Integer> e : is.getEnchantments().entrySet()) {
serial += ":enchantment-" + e.getKey().getName() + " " + e.getValue(); serial.append(":enchantment-").append(e.getKey().getName()).append(" ").append(e.getValue());
} }
} }
if (is.hasItemMeta()) { if (is.hasItemMeta()) {
final ItemMeta meta = is.getItemMeta(); final ItemMeta meta = is.getItemMeta();
if (meta.hasDisplayName()) { if (meta.hasDisplayName()) {
serial += ":displayname-" + meta.getDisplayName(); serial.append(":displayname-").append(meta.getDisplayName());
} }
if (meta.hasLore()) { if (meta.hasLore()) {
for (final String s : meta.getLore()) { for (final String s : meta.getLore()) {
serial += ":lore-" + s; serial.append(":lore-").append(s);
} }
} }
final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>(); final LinkedHashMap<String, Object> map = new LinkedHashMap<>(meta.serialize());
map.putAll(meta.serialize());
if (map.containsKey("lore")) {
map.remove("lore"); map.remove("lore");
}
if (map.containsKey("display-name")) {
map.remove("display-name"); map.remove("display-name");
}
for (final String key : map.keySet()) { for (final String key : map.keySet()) {
serial += ":" + key + "-" + map.get(key).toString().replace("minecraft:", "minecraft|"); serial.append(":").append(key).append("-").append(map.get(key).toString().replace("minecraft:", "minecraft|"));
} }
} }
return serial; return serial.toString();
} }
/** /**
@ -516,7 +513,7 @@ public class ItemUtil {
* @return true display or item name, plus durability and amount, plus enchantments * @return true display or item name, plus durability and amount, plus enchantments
*/ */
public static String getDisplayString(final ItemStack is) { public static String getDisplayString(final ItemStack is) {
StringBuilder text; final StringBuilder text;
if (is == null) { if (is == null) {
return null; return null;
} }
@ -576,7 +573,7 @@ public class ItemUtil {
if (is == null) { if (is == null) {
return null; return null;
} }
String text = ""; final String text;
if (is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) { if (is.getItemMeta() != null && is.getItemMeta().hasDisplayName()) {
text = "" + ChatColor.DARK_AQUA + ChatColor.ITALIC + is.getItemMeta().getDisplayName(); text = "" + ChatColor.DARK_AQUA + ChatColor.ITALIC + is.getItemMeta().getDisplayName();
} else { } else {