diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index 965d7495..ac982257 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -5,7 +5,6 @@ import io.delilaheve.util.ConfigOptions; import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; @@ -39,14 +38,14 @@ public class EnchantmentApi { * @param enchantment The enchantment to register * @return True if successful. */ - public static boolean registerEnchantment(@NotNull CAEnchantment enchantment) { - if (!CAEnchantmentRegistry.getInstance().register(enchantment)) return false; + public static boolean registerEnchantment(@NotNull CAEnchantment enchantment){ + if(!CAEnchantmentRegistry.getInstance().register(enchantment)) return false; // Add enchantment to gui. - if (EnchantCostConfigGui.getInstance() != null) { + if(EnchantCostConfigGui.getInstance() != null){ EnchantCostConfigGui.getInstance().updateValueForGeneric(enchantment, true); } - if (EnchantLimitConfigGui.getInstance() != null) { + if(EnchantLimitConfigGui.getInstance() != null){ EnchantLimitConfigGui.getInstance().updateValueForGeneric(enchantment, true); } @@ -63,8 +62,8 @@ public class EnchantmentApi { * @param defaultRarity The default rarity of the provided enchantment * @return True if successful. */ - public static boolean registerEnchantment(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity defaultRarity) { - if (defaultRarity == null) + public static boolean registerEnchantment(@NotNull Enchantment enchantment, @Nullable EnchantmentRarity defaultRarity){ + if(defaultRarity == null) return registerEnchantment(new CABukkitEnchantment(enchantment)); return registerEnchantment(new CABukkitEnchantment(enchantment, defaultRarity)); @@ -78,7 +77,7 @@ public class EnchantmentApi { * @param enchantment The enchantment to register * @return True if successful. */ - public static boolean registerEnchantment(@NotNull Enchantment enchantment) { + public static boolean registerEnchantment(@NotNull Enchantment enchantment){ return registerEnchantment(new CABukkitEnchantment(enchantment)); } @@ -88,12 +87,12 @@ public class EnchantmentApi { * @param enchantment The enchantment to unregister * @return True if successful. */ - public static boolean unregisterEnchantment(@Nullable CAEnchantment enchantment) { + public static boolean unregisterEnchantment(@Nullable CAEnchantment enchantment){ // Remove from gui - if (EnchantCostConfigGui.getInstance() != null) { + if(EnchantCostConfigGui.getInstance() != null){ EnchantCostConfigGui.getInstance().removeGeneric(enchantment); } - if (EnchantLimitConfigGui.getInstance() != null) { + if(EnchantLimitConfigGui.getInstance() != null){ EnchantLimitConfigGui.getInstance().removeGeneric(enchantment); } @@ -106,7 +105,7 @@ public class EnchantmentApi { * @param key The enchantment key to unregister * @return True if successful. */ - public static boolean unregisterEnchantment(@NotNull NamespacedKey key) { + public static boolean unregisterEnchantment(@NotNull NamespacedKey key){ CAEnchantment enchantment = CAEnchantment.getByKey(key); return unregisterEnchantment(enchantment); } @@ -117,7 +116,7 @@ public class EnchantmentApi { * @param enchantment The enchantment to unregister * @return True if successful. */ - public static boolean unregisterEnchantment(@NotNull Enchantment enchantment) { + public static boolean unregisterEnchantment(@NotNull Enchantment enchantment){ return unregisterEnchantment(enchantment.getKey()); } @@ -128,7 +127,7 @@ public class EnchantmentApi { * @return The custom anvil enchantment of this key. null if not found. */ @Nullable - public static CAEnchantment getByKey(@NotNull NamespacedKey key) { + public static CAEnchantment getByKey(@NotNull NamespacedKey key){ return CAEnchantment.getByKey(key); } @@ -141,7 +140,7 @@ public class EnchantmentApi { */ @Deprecated(since = "1.6.3") @Nullable - public static CAEnchantment getByName(@NotNull String name) { + public static CAEnchantment getByName(@NotNull String name){ return CAEnchantment.getByName(name); } @@ -151,31 +150,29 @@ public class EnchantmentApi { * @param name The name used to fetch * @return List of custom anvil enchantments of this name. May be empty if not found. */ - public static List getListByName(@NotNull String name) { + public static List getListByName(@NotNull String name){ return CAEnchantment.getListByName(name); } /** * Get every registered custom anvil enchantments. - * * @return An immutable map of enchantment key as map key and custom anvil enchantment as value. */ @NotNull - public static Map getRegisteredEnchantments() { + public static Map getRegisteredEnchantments(){ return Collections.unmodifiableMap(CAEnchantmentRegistry.getInstance().registeredEnchantments()); } /** * Write the default level and rarity configuration of the enchantment. - * * @param enchantment The enchantment to write default configuration - * @param override If it should override old configuration + * @param override If it should override old configuration * @return Return false if override is false and a configuration exist. true otherwise. */ - public static boolean writeDefaultConfig(CAEnchantment enchantment, boolean override) { + public static boolean writeDefaultConfig(CAEnchantment enchantment, boolean override){ FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig(); - if (tryWriteDefaultConfig(config, enchantment, override)) { + if(tryWriteDefaultConfig(config, enchantment, override)){ prepareSaveTask(); } return true; @@ -185,7 +182,7 @@ public class EnchantmentApi { boolean hasChange = false; String levelPath = ConfigOptions.ENCHANT_LIMIT_ROOT + "." + enchantment.getKey(); - if (override || !defaultConfig.isSet(levelPath)) { + if(override || !defaultConfig.isSet(levelPath)){ defaultConfig.set(levelPath, enchantment.defaultMaxLevel()); hasChange = true; } @@ -195,11 +192,11 @@ public class EnchantmentApi { String itemPath = basePath + ".item"; String bookPath = basePath + ".book"; - if (override || !defaultConfig.isSet(itemPath)) { + if(override || !defaultConfig.isSet(itemPath)){ defaultConfig.set(itemPath, rarity.getItemValue()); hasChange = true; } - if (override || !defaultConfig.isSet(bookPath)) { + if(override || !defaultConfig.isSet(bookPath)){ defaultConfig.set(bookPath, rarity.getBookValue()); hasChange = true; } @@ -211,81 +208,28 @@ public class EnchantmentApi { * Prepare a task to save custom recipe configuration. */ private static void prepareSaveTask() { - if (saveChangeTask != null) return; + if(saveChangeTask != null) return; - saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, () -> { + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); saveChangeTask = null; }); } /** - * Add a bulk get operator. (not needed for proper "bukkit" enchantments) - *

- * Do not forget to mark your enchantments as {@link CAEnchantment#isGetOptimised() Get Optimized} - * + * Add a bulk get operator. * @param operation An optimised get enchantments operation */ - public static void addBulkGet(@NotNull BulkGetEnchantOperation operation) { + public static void addBulkGet(@NotNull BulkGetEnchantOperation operation){ CAEnchantmentRegistry.getInstance().getOptimisedGetOperators().add(operation); } /** * Add a bulk clean operator. - * - * @param operation An optimised clean enchantments operation (not needed for proper "bukkit" enchantments) - *

- * Do not forget to mark your enchantments as {@link CAEnchantment#isCleanOptimised() Clean Optimized} + * @param operation An optimised clean enchantments operation */ - public static void addBulkClean(@NotNull BulkCleanEnchantOperation operation) { + public static void addBulkClean(@NotNull BulkCleanEnchantOperation operation){ CAEnchantmentRegistry.getInstance().getOptimisedCleanOperators().add(operation); } - /** - * Get all the enchantments of an item - * - * @param item The item to get the enchantment from - * @return A map of key of enchantment, value the level of all the enchantments of the item - * @since 1.17.6 - */ - public static Map getEnchantments(@NotNull ItemStack item) { - return CAEnchantment.getEnchants(item); - } - - /** - * Set all the enchantments to an item. Clearing previous enchantments - * - * @param item The item to get the enchantment from - * @param enchants A map of key of enchantment, value the level of all the enchantments - * @since 1.17.6 - */ - public static void setEnchantments(@NotNull ItemStack item, @NotNull Map enchants) { - clearEnchantments(item); - addEnchantments(item, enchants); - } - - /** - * Add enchantment with there respective level. - * If the enchantment is already present it will be overridden to the new level - * - * @param item The item to get the enchantment from - * @param enchants A map of key of enchantment, value the level of the new enchantments - * @since 1.17.6 - */ - public static void addEnchantments(@NotNull ItemStack item, @NotNull Map enchants) { - enchants.forEach((enchantment, level) -> - enchantment.addEnchantmentUnsafe(item, level) - ); - } - - /** - * Clear all the enchantments - * - * @param item The item to clear the enchantments from - * @since 1.17.6 - */ - public static void clearEnchantments(@NotNull ItemStack item) { - CAEnchantment.clearEnchants(item); - } - } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/SuperEnchantBulkOperation.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/SuperEnchantBulkOperation.java index 85535594..8bc729ab 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/SuperEnchantBulkOperation.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/bulk/SuperEnchantBulkOperation.java @@ -41,7 +41,7 @@ public class SuperEnchantBulkOperation implements BulkGetEnchantOperation, BulkC @Override public void bulkClear(@NotNull ItemStack item, @NotNull ItemMeta meta) { - // item meta is not preferred for super enchant + // item meta is not preferred for enchantment squared clear } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CASuperEnchantEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CASuperEnchantEnchantment.java index 22e36056..6039dc84 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CASuperEnchantEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CASuperEnchantEnchantment.java @@ -73,14 +73,4 @@ public class CASuperEnchantEnchantment extends CAEnchantmentBase implements Addi return !enchant.canApplyTo(item.getType()); } - - @Override - public boolean isCleanOptimised() { - return true; - } - - @Override - public boolean isGetOptimised() { - return true; - } } diff --git a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt index bf075231..25698ad1 100644 --- a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt +++ b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt @@ -21,6 +21,23 @@ object ItemUtil { */ fun ItemStack.isEnchantedBook() = type == ENCHANTED_BOOK + /** + * Find the enchantment map for this [ItemStack] and return it as a [MutableMap] + */ + fun ItemStack.findEnchantments(): MutableMap = CAEnchantment.getEnchants(this) + + /** + * Apply an [enchantments] map to this [ItemStack] + */ + fun ItemStack.setEnchantmentsUnsafe(enchantments: Map) { + CAEnchantment.clearEnchants(this) + + enchantments.forEach { (enchantment, level) -> + enchantment.addEnchantmentUnsafe(this, level) + } + + } + private fun maxDamage(damageable: Damageable): Int { val ver = UpdateUtils.currentMinecraftVersion() if(ver.major <= 1 && ver.minor <= 20 && ver.patch < 5) return Integer.MAX_VALUE diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt index 6da9f5d9..915a3903 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/anvil/AnvilMergeLogic.kt @@ -3,8 +3,10 @@ package xyz.alexcrea.cuanvil.anvil import io.delilaheve.CustomAnvil import io.delilaheve.util.ConfigOptions import io.delilaheve.util.EnchantmentUtil.combineWith +import io.delilaheve.util.ItemUtil.findEnchantments import io.delilaheve.util.ItemUtil.isEnchantedBook import io.delilaheve.util.ItemUtil.repairFrom +import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.ChatColor import org.bukkit.Material @@ -15,7 +17,6 @@ import org.bukkit.inventory.InventoryView import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.ItemMeta import org.bukkit.persistence.PersistentDataType -import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.enchant.CAEnchantment @@ -188,19 +189,14 @@ object AnvilMergeLogic { player: Player, first: ItemStack, second: ItemStack ): AnvilResult { - val firstEnchants = EnchantmentApi.getEnchantments(first) - val secondEnchants = EnchantmentApi.getEnchantments(second) - - // newEnchants will be mutated by combineWith - val newEnchants = HashMap(firstEnchants) - newEnchants.combineWith(secondEnchants, first, player) - - var hasChanged = !isIdentical(firstEnchants, newEnchants) + val newEnchants = first.findEnchantments() + .combineWith(second.findEnchantments(), first, player) + var hasChanged = !isIdentical(first.findEnchantments(), newEnchants) val resultItem = DependencyManager.cloneItem(player, first) val cost = AnvilCost() if (hasChanged) { - EnchantmentApi.setEnchantments(resultItem, newEnchants) + resultItem.setEnchantmentsUnsafe(newEnchants) // Calculate enchantment cost AnvilXpUtil.getRightValues(first, second, resultItem, cost) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index 5b256dd8..38d54764 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -5,7 +5,6 @@ import org.bukkit.NamespacedKey import org.bukkit.configuration.ConfigurationSection import org.bukkit.enchantments.Enchantment import org.bukkit.inventory.ItemStack -import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.enchant.AdditionalTestEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry @@ -67,7 +66,7 @@ class EnchantConflictManager { val keys = config.getKeys(false) for (key in keys) { val section = config.getConfigurationSection(key) - if (section == null) { + if(section == null) { warnBadKey(key) continue } @@ -141,12 +140,8 @@ class EnchantConflictManager { return conflict } - private fun fetchConditionalRestriction( - restrictions: MutableMap, - section: ConfigurationSection?, - conflictName: String - ) { - if (section == null) return + private fun fetchConditionalRestriction(restrictions: MutableMap, section: ConfigurationSection?, conflictName: String) { + if(section == null) return for (enchantName in section.getKeys(false)) { val enchants = getEnchantByIdentifier(enchantName) if (enchants.isEmpty()) { @@ -155,7 +150,7 @@ class EnchantConflictManager { } val value = section.getInt(enchantName, -1) - if (value < 0) continue + if(value < 0) continue for (enchant in enchants) { val previous = restrictions.getOrDefault(enchant, value) @@ -264,8 +259,7 @@ class EnchantConflictManager { } if ((result != ConflictType.ITEM_CONFLICT) && (newEnchant is AdditionalTestEnchantment)) { - val partialItem = item.clone() - EnchantmentApi.setEnchantments(partialItem, immutableEnchants) + val partialItem = createPartialResult(item, immutableEnchants) if (newEnchant.isItemConflict(immutableEnchants, type, partialItem)) { return ConflictType.ITEM_CONFLICT @@ -276,6 +270,17 @@ class EnchantConflictManager { return result } + private fun createPartialResult(item: ItemStack, enchantments: Map): ItemStack { + val newItem = item.clone() + + CAEnchantment.clearEnchants(newItem) + enchantments.forEach { enchantment -> + enchantment.key.addEnchantmentUnsafe(newItem, enchantment.value) + } + + return newItem + } + } /** diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt index 9d2f5420..63dc9d03 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/anvil/AnvilXpUtil.kt @@ -3,6 +3,7 @@ package xyz.alexcrea.cuanvil.util.anvil import io.delilaheve.CustomAnvil import io.delilaheve.util.ConfigOptions import io.delilaheve.util.EnchantmentUtil.enchantmentName +import io.delilaheve.util.ItemUtil.findEnchantments import io.delilaheve.util.ItemUtil.isEnchantedBook import org.bukkit.GameMode import org.bukkit.NamespacedKey @@ -16,7 +17,6 @@ import org.bukkit.persistence.PersistentDataType import xyz.alexcrea.cuanvil.anvil.AnvilCost import xyz.alexcrea.cuanvil.anvil.AnvilMergeLogic.AnvilResult import xyz.alexcrea.cuanvil.anvil.AnvilUseType -import xyz.alexcrea.cuanvil.api.EnchantmentApi import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager @@ -247,8 +247,8 @@ object AnvilXpUtil { // Calculate right value and illegal enchant penalty val rightIsFormBook = right.isEnchantedBook() - val rightEnchs = EnchantmentApi.getEnchantments(right) - val resultEnchs = EnchantmentApi.getEnchantments(result) + val rightEnchs = right.findEnchantments() + val resultEnchs = result.findEnchantments() val resultEnchsKeys = HashMap(resultEnchs) var rightValue = 0 @@ -282,7 +282,7 @@ object AnvilXpUtil { } if(ConfigOptions.includeLeftEnchantmentForCost) { val leftIsFormBook = left.isEnchantedBook() - val leftEnchs = EnchantmentApi.getEnchantments(left) + val leftEnchs = left.findEnchantments() for (enchantment in leftEnchs) { // Do not process enchantment that are present on the sacrifice if(rightEnchs.contains(enchantment.key)) continue diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java index fefec130..6f5c7bb8 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java @@ -13,7 +13,6 @@ import org.bukkit.inventory.meta.Repairable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Assertions; -import xyz.alexcrea.cuanvil.api.EnchantmentApi; import xyz.alexcrea.cuanvil.data.AnvilClickTestData; import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; @@ -48,7 +47,7 @@ public class AnvilFuseTestUtil { } ItemStack item = new ItemStack(material); - EnchantmentApi.setEnchantments(item, enchantmentMap); + ItemUtil.INSTANCE.setEnchantmentsUnsafe(item, enchantmentMap); ItemMeta meta = item.getItemMeta(); ((Repairable) meta).setRepairCost(repairCost);