diff --git a/Core/pom.xml b/Core/pom.xml index 1aa7dea..f0b2304 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.3.0.4 + 3.3.1 4.0.0 @@ -24,10 +24,16 @@ sk89q-repo https://maven.enginehub.org/repo/ + + false + dmulloy2-repo https://repo.dmulloy2.net/repository/public/ + + false + @@ -45,27 +51,27 @@ su.nightexpress.excellentenchants NMS - 3.3.0.4 + 3.3.1 su.nightexpress.excellentenchants V1_17_R1 - 3.3.0.4 + 3.3.1 su.nightexpress.excellentenchants V1_18_R2 - 3.3.0.4 + 3.3.1 su.nightexpress.excellentenchants V1_19_R1 - 3.3.0.4 + 3.3.1 su.nightexpress.excellentenchants V1_19_R2 - 3.3.0.4 + 3.3.1 fr.neatmonster diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/ExcellentEnchants.java b/Core/src/main/java/su/nightexpress/excellentenchants/ExcellentEnchants.java index 92b344b..c3839ce 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/ExcellentEnchants.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/ExcellentEnchants.java @@ -97,11 +97,14 @@ public class ExcellentEnchants extends NexPlugin { @Override public void registerHooks() { - if (Hooks.hasPlugin(HookId.PROTOCOL_LIB)) { - ProtocolHook.setup(); - } - else { - this.warn(HookId.PROTOCOL_LIB + " is not installed. Enchantments won't be displayed on items."); + if (Config.ENCHANTMENTS_DISPLAY_MODE.get() == 2) { + if (Hooks.hasPlugin(HookId.PROTOCOL_LIB)) { + ProtocolHook.setup(); + } + else { + this.warn(HookId.PROTOCOL_LIB + " is not installed. Set display mode to Plain lore."); + Config.ENCHANTMENTS_DISPLAY_MODE.set(1); + } } } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/api/enchantment/ExcellentEnchant.java b/Core/src/main/java/su/nightexpress/excellentenchants/api/enchantment/ExcellentEnchant.java index 678c103..c1adcc2 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/api/enchantment/ExcellentEnchant.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/api/enchantment/ExcellentEnchant.java @@ -247,7 +247,7 @@ public abstract class ExcellentEnchant extends Enchantment implements IEnchantme @NotNull public String getNameFormatted(int level, int charges) { - if (!this.isChargesEnabled()) return this.getNameFormatted(level); + if (!this.isChargesEnabled() || charges < 0) return this.getNameFormatted(level); int chargesMax = this.getChargesMax(level); double percent = (double) charges / (double) chargesMax * 100D; diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/command/BookCommand.java b/Core/src/main/java/su/nightexpress/excellentenchants/command/BookCommand.java index 9d475a4..8733f39 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/command/BookCommand.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/command/BookCommand.java @@ -86,6 +86,7 @@ public class BookCommand extends AbstractCommand { ItemStack item = new ItemStack(Material.ENCHANTED_BOOK); EnchantManager.addEnchantment(item, enchantment, level, true); + EnchantManager.updateEnchantmentsDisplay(item); PlayerUtil.addItem(player, item); plugin.getMessage(Lang.COMMAND_BOOK_DONE) diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/command/EnchantCommand.java b/Core/src/main/java/su/nightexpress/excellentenchants/command/EnchantCommand.java index ef064b1..531be7c 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/command/EnchantCommand.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/command/EnchantCommand.java @@ -83,6 +83,7 @@ public class EnchantCommand extends AbstractCommand { } else EnchantManager.removeEnchantment(item, enchantment); + EnchantManager.updateEnchantmentsDisplay(item); plugin.getMessage(Lang.COMMAND_ENCHANT_DONE).send(sender); } } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/command/TierbookCommand.java b/Core/src/main/java/su/nightexpress/excellentenchants/command/TierbookCommand.java index 9849ce8..d5a3da9 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/command/TierbookCommand.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/command/TierbookCommand.java @@ -91,6 +91,7 @@ public class TierbookCommand extends AbstractCommand { ItemStack item = new ItemStack(Material.ENCHANTED_BOOK); EnchantManager.addEnchantment(item, enchant, level, true); + EnchantManager.updateEnchantmentsDisplay(item); PlayerUtil.addItem(player, item); plugin.getMessage(Lang.COMMAND_TIER_BOOK_DONE) diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/config/Config.java b/Core/src/main/java/su/nightexpress/excellentenchants/config/Config.java index bb333ea..69c26f5 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/config/Config.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/config/Config.java @@ -26,7 +26,8 @@ public class Config { ); public static final JOption ENCHANTMENTS_CHARGES_ENABLED = JOption.create("Enchantments.Charges.Enabled", false, - "Enables the enchantment Charges feature."); // TODO Wiki link + "Enables the enchantment Charges feature.", + Placeholders.URL_WIKI + "Charges-System"); public static final JOption> ENCHANTMENTS_CHARGES_FORMAT = new JOption>("Enchantments.Charges.Format", (cfg, path, def) -> cfg.getSection(path).stream().collect(Collectors.toMap(k -> StringUtil.getDouble(k, 0), v -> StringUtil.color(cfg.getString(path + "." + v, "")), (o,n) -> n, TreeMap::new)), @@ -64,6 +65,13 @@ public class Config { "To disable all enchantments for a world, use '" + Placeholders.WILDCARD + "' instead of enchantment names.") .setWriter((cfg, path, map) -> map.forEach((world, enchants) -> cfg.set(path + "." + world, enchants))); + public static final JOption ENCHANTMENTS_DISPLAY_MODE = JOption.create("Enchantments.Display.Mode", 1, + "Sets how enchantment names and descriptions will be handled on items.", + "1 = Plain modification of item's lore (lore changes are real and persistent).", + "2 = Packet modification of item's lore (no real changes are made to the items). Requires ProtocolLib.", + "Plain mode is faster, but may not reflect all changes immediately.", + "Packet mode is slower, but instantly reflect all changes. In creative mode, there is a chance for lore duplication."); + public static final JOption ENCHANTMENTS_DESCRIPTION_ENABLED = JOption.create("Enchantments.Description.Enabled", true, "When 'true', adds the enchantment description to item lore under enchantment names.", "Note #1: You must have ProtocolLib installed for this feature to work (as well as for enchantments name display).", diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantManager.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantManager.java index 3220c5e..e50b469 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantManager.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/EnchantManager.java @@ -1,10 +1,12 @@ package su.nightexpress.excellentenchants.enchantment; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.entity.LivingEntity; import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; @@ -114,8 +116,7 @@ public class EnchantManager extends AbstractManager { // Класс для исключения неудачных попыток. EnchantPopulator populator = new EnchantPopulator(obtainType, item); - // Херачим до талого, пока нужное количество не будет добавлено - // или не закончатся чары и/или тиры. + // Добавляем сколько можем, пока нужное количество не будет добавлено или не закончатся чары и/или тиры. while (!populator.isEmpty() && enchRoll > 0) { // Достигнут максимум чар (любых) для итема, заканчиваем. if (enchantsToAdd.size() >= enchMax) break; @@ -159,6 +160,7 @@ public class EnchantManager extends AbstractManager { EnchantManager.getEnchantsToPopulate(item, obtainType).forEach((enchantment, level) -> { EnchantManager.addEnchantment(item, enchantment, level, false); }); + EnchantManager.updateEnchantmentsDisplay(item); return EnchantManager.getEnchantmentsAmount(item) != enchantsHad; } @@ -193,11 +195,52 @@ public class EnchantManager extends AbstractManager { item.setItemMeta(meta); } + public static final NamespacedKey KEY_LORE_SIZE = new NamespacedKey(ExcellentEnchantsAPI.PLUGIN, "lore_size"); + + public static boolean updateEnchantmentsDisplay(@NotNull ItemStack item) { + if (Config.ENCHANTMENTS_DISPLAY_MODE.get() != 1) return false; + + if (!isEnchantable(item)) { + PDCUtil.remove(item, KEY_LORE_SIZE); + return false; + } + + Map enchants = EnchantManager.getExcellentEnchantments(item); + + int sizeHas = PDCUtil.getInt(item, KEY_LORE_SIZE).orElse(0); + int sizeReal = enchants.size() + enchants.keySet().stream().map(ExcellentEnchant::getDescription).mapToInt(List::size).sum(); + + ItemMeta meta = item.getItemMeta(); + if (meta == null) return false; + + List lore = meta.getLore() == null ? new ArrayList<>() : meta.getLore(); + for (int index = 0; index < sizeHas && !lore.isEmpty(); index++) { + lore.remove(0); + } + + if (!meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) { + enchants.forEach((enchant, level) -> { + lore.addAll(0, enchant.formatDescription(level)); + }); + enchants.forEach((enchant, level) -> { + lore.add(0, enchant.getNameFormatted(level, getEnchantmentCharges(meta, enchant))); + }); + } + + meta.setLore(lore); + PDCUtil.set(meta, KEY_LORE_SIZE, sizeReal); + item.setItemMeta(meta); + return true; + } + @NotNull public static Map getEnchantments(@NotNull ItemStack item) { ItemMeta meta = item.getItemMeta(); - if (meta == null) return Collections.emptyMap(); + return meta == null ? Collections.emptyMap() : getEnchantments(meta); + } + @NotNull + public static Map getEnchantments(@NotNull ItemMeta meta) { return (meta instanceof EnchantmentStorageMeta meta2) ? meta2.getStoredEnchants() : meta.getEnchants(); } @@ -214,7 +257,11 @@ public class EnchantManager extends AbstractManager { } public static int getEnchantmentCharges(@NotNull ItemStack item, @NotNull ExcellentEnchant enchant) { - return PDCUtil.getIntData(item, enchant.getChargesKey()); + return enchant.isChargesEnabled() ? PDCUtil.getIntData(item, enchant.getChargesKey()) : -1; + } + + public static int getEnchantmentCharges(@NotNull ItemMeta meta, @NotNull ExcellentEnchant enchant) { + return enchant.isChargesEnabled() ? PDCUtil.getIntData(meta, enchant.getChargesKey()) : -1; } public static boolean isEnchantmentOutOfCharges(@NotNull ItemStack item, @NotNull ExcellentEnchant enchant) { @@ -269,7 +316,17 @@ public class EnchantManager extends AbstractManager { @NotNull public static Map getExcellentEnchantments(@NotNull ItemStack item) { - return EnchantManager.getEnchantments(item).entrySet().stream() + return getExcellentEnchantments(EnchantManager.getEnchantments(item)); + } + + @NotNull + public static Map getExcellentEnchantments(@NotNull ItemMeta meta) { + return getExcellentEnchantments(EnchantManager.getEnchantments(meta)); + } + + @NotNull + private static Map getExcellentEnchantments(@NotNull Map enchants) { + return enchants.entrySet().stream() .map(entry -> { ExcellentEnchant enchant = EnchantRegister.get(entry.getKey().getKey()); return enchant == null ? null : Pair.of(enchant, entry.getValue()); diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantSaturation.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantSaturation.java index 0d8b156..a446ee9 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantSaturation.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/armor/EnchantSaturation.java @@ -113,7 +113,11 @@ public class EnchantSaturation extends ExcellentEnchant implements PassiveEnchan public void action() { for (LivingEntity entity : this.getEntities()) { EnchantManager.getEquippedEnchants(entity, EnchantSaturation.class).forEach((item, enchants) -> { - enchants.forEach((enchant, level) -> enchant.onTrigger(entity, item, level)); + enchants.forEach((enchant, level) -> { + if (enchant.onTrigger(entity, item, level)) { + enchant.consumeCharges(item); + } + }); }); } } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantDivineTouch.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantDivineTouch.java index eb93fb9..5bbf247 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantDivineTouch.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/EnchantDivineTouch.java @@ -113,7 +113,7 @@ public class EnchantDivineTouch extends ExcellentEnchant implements Chanced, Blo e.setExpToDrop(0); e.setDropItems(true); block.setMetadata(META_HANDLE, new FixedMetadataValue(this.plugin, true)); - return true; + return false; // Do not consume charges } // Update spawner type of the placed spawner mined by Divine Touch. diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantAnvilListener.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantAnvilListener.java index 1e2e33a..d35590d 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantAnvilListener.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantAnvilListener.java @@ -64,6 +64,7 @@ public class EnchantAnvilListener extends AbstractListener { EnchantManager.getExcellentEnchantments(first).forEach((hasEnch, hasLevel) -> { EnchantManager.addEnchantment(result2, hasEnch, hasLevel, true); }); + EnchantManager.updateEnchantmentsDisplay(result2); e.setResult(result2); return true; } @@ -86,6 +87,7 @@ public class EnchantAnvilListener extends AbstractListener { } PDCUtil.setData(result2, RECHARGED, count); + EnchantManager.updateEnchantmentsDisplay(result2); e.setResult(result2); this.plugin.runTask(c -> e.getInventory().setRepairCost(chargeables.size()), false); return true; @@ -120,6 +122,7 @@ public class EnchantAnvilListener extends AbstractListener { if (first.equals(result2)) return false; + EnchantManager.updateEnchantmentsDisplay(result2); e.setResult(result2); // NMS ContainerAnvil will set level cost to 0 right after calling the event, need 1 tick delay. diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantGenericListener.java b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantGenericListener.java index b5d1783..c8b6f14 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantGenericListener.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/listener/EnchantGenericListener.java @@ -7,6 +7,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.VillagerAcquireTradeEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryDragEvent; @@ -19,6 +20,7 @@ import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import su.nexmedia.engine.api.manager.AbstractListener; +import su.nexmedia.engine.hooks.Hooks; import su.nightexpress.excellentenchants.ExcellentEnchants; import su.nightexpress.excellentenchants.api.enchantment.ExcellentEnchant; import su.nightexpress.excellentenchants.config.Config; @@ -80,9 +82,20 @@ public class EnchantGenericListener extends AbstractListener curses.forEach((excellentEnchant, level) -> { EnchantManager.addEnchantment(result, excellentEnchant, level, true); }); + EnchantManager.updateEnchantmentsDisplay(result); }); } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onEnchantUpdatePickup(EntityPickupItemEvent e) { + if (!(e.getEntity() instanceof Player player)) return; + + Item item = e.getItem(); + ItemStack itemStack = item.getItemStack(); + if (EnchantManager.updateEnchantmentsDisplay(itemStack)) { + item.setItemStack(itemStack); + } + } // --------------------------------------------------------------- // Handle Enchanting Table @@ -117,6 +130,7 @@ public class EnchantGenericListener extends AbstractListener EnchantManager.restoreEnchantmentCharges(result, enchant); } }); + EnchantManager.updateEnchantmentsDisplay(result); e.getInventory().setItem(0, result); }); @@ -177,6 +191,8 @@ public class EnchantGenericListener extends AbstractListener if (Config.getObtainSettings(ObtainType.MOB_SPAWNING).isEmpty()) return; LivingEntity entity = e.getEntity(); + if (Hooks.isMythicMob(entity)) return; + EntityEquipment equipment = entity.getEquipment(); if (equipment == null) return; @@ -184,6 +200,7 @@ public class EnchantGenericListener extends AbstractListener ItemStack item = equipment.getItem(slot); if (EnchantManager.isEnchantable(item)) { EnchantManager.populateEnchantments(item, ObtainType.MOB_SPAWNING); + EnchantManager.getExcellentEnchantments(item).keySet().forEach(enchant -> EnchantManager.restoreEnchantmentCharges(item, enchant)); equipment.setItem(slot, item); } } diff --git a/Core/src/main/java/su/nightexpress/excellentenchants/hook/impl/ProtocolHook.java b/Core/src/main/java/su/nightexpress/excellentenchants/hook/impl/ProtocolHook.java index 216149a..d7cb47c 100644 --- a/Core/src/main/java/su/nightexpress/excellentenchants/hook/impl/ProtocolHook.java +++ b/Core/src/main/java/su/nightexpress/excellentenchants/hook/impl/ProtocolHook.java @@ -7,6 +7,7 @@ import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import org.bukkit.GameMode; +import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.MerchantRecipe; import org.bukkit.inventory.meta.ItemMeta; @@ -82,9 +83,9 @@ public class ProtocolHook { ItemStack copy = new ItemStack(item); ItemMeta meta = copy.getItemMeta(); - if (meta == null) return item; + if (meta == null || meta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) return item; - Map enchants = EnchantManager.getExcellentEnchantments(item) + Map enchants = EnchantManager.getExcellentEnchantments(meta) .entrySet().stream() .sorted(Comparator.comparing(e -> e.getKey().getTier().getPriority())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (old,nev) -> nev, LinkedHashMap::new)); @@ -105,7 +106,7 @@ public class ProtocolHook { }); } enchants.forEach((enchant, level) -> { - int charges = EnchantManager.getEnchantmentCharges(item, enchant); + int charges = EnchantManager.getEnchantmentCharges(meta, enchant); lore.add(0, enchant.getNameFormatted(level, charges)); }); diff --git a/NMS/pom.xml b/NMS/pom.xml index 44321c5..a927bcd 100644 --- a/NMS/pom.xml +++ b/NMS/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.3.0.4 + 3.3.1 4.0.0 diff --git a/V1_17_R1/pom.xml b/V1_17_R1/pom.xml index 6399ebd..f9cf26e 100644 --- a/V1_17_R1/pom.xml +++ b/V1_17_R1/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.3.0.4 + 3.3.1 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.3.0.4 + 3.3.1 diff --git a/V1_18_R2/pom.xml b/V1_18_R2/pom.xml index 3d0ad72..7b086b9 100644 --- a/V1_18_R2/pom.xml +++ b/V1_18_R2/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.3.0.4 + 3.3.1 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.3.0.4 + 3.3.1 diff --git a/V1_19_R1/pom.xml b/V1_19_R1/pom.xml index 7c2aa0c..0e6a1b8 100644 --- a/V1_19_R1/pom.xml +++ b/V1_19_R1/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.3.0.4 + 3.3.1 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.3.0.4 + 3.3.1 diff --git a/V1_19_R2/pom.xml b/V1_19_R2/pom.xml index d34d5bb..da7821c 100644 --- a/V1_19_R2/pom.xml +++ b/V1_19_R2/pom.xml @@ -5,7 +5,7 @@ ExcellentEnchants su.nightexpress.excellentenchants - 3.3.0.4 + 3.3.1 4.0.0 @@ -26,7 +26,7 @@ su.nightexpress.excellentenchants NMS - 3.3.0.4 + 3.3.1 diff --git a/pom.xml b/pom.xml index 0c6d612..49c6380 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ su.nightexpress.excellentenchants ExcellentEnchants pom - 3.3.0.4 + 3.3.1 Core NMS