diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/WrappedEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/WrappedEnchantment.java index 146f6db..efe277c 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/WrappedEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/WrappedEnchantment.java @@ -1,16 +1,17 @@ package xyz.alexcrea.cuanvil.enchant; import io.delilaheve.CustomAnvil; +import io.delilaheve.util.ItemUtil; import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.enchant.wrapped.VanillaEnchant; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.logging.Level; /** @@ -77,6 +78,14 @@ public abstract class WrappedEnchantment { */ public final int defaultMaxLevel(){return defaultMaxLevel;} + /** + * If the enchantment have specialised group operation. + * @return If the enchantment is optimised for group operation. + */ + protected boolean isOptimised(){ + return false; + } + /** * Get current level of the enchantment. * @param item Item to search the level for. @@ -133,17 +142,35 @@ public abstract class WrappedEnchantment { * Clear every enchantment from this item. * @param item Item to be cleared from enchantments. */ - public static void clearEnchants(@NotNull ItemStack item){ //TODO faster method to clear vanilla enchantment - for (WrappedEnchantment enchant : getEnchants(item).keySet()) { - enchant.removeFrom(item); + public static void clearEnchants(@NotNull ItemStack item){ + ItemMeta meta = item.getItemMeta(); + if(meta == null) return; + + // Clean Vanilla enchants + if (ItemUtil.INSTANCE.isEnchantedBook(item)) { + EnchantmentStorageMeta bookMeta = (EnchantmentStorageMeta) meta; + bookMeta.getStoredEnchants().forEach( + (enchantment, leve) -> bookMeta.removeStoredEnchant(enchantment) + ); + } else { + item.getEnchantments().forEach( + (enchantment, leve) -> item.removeEnchantment(enchantment) + ); + } + + // Clean unoptimised enchants + for (WrappedEnchantment enchant : unoptimisedValues()) { + if(enchant.isEnchantmentPresent(item)){ + enchant.removeFrom(item); + } } } /** * Get enchantments of an item. - * @param item item to get enchantment from. - * @return a map of the set enchantments and there's respective levels. + * @param item Item to get enchantment from. + * @return A map of the set enchantments and there's respective levels. */ public static Map getEnchants(@NotNull ItemStack item){ //TODO faster method to find vanilla enchantment Map enchantments = new HashMap<>(); @@ -151,18 +178,50 @@ public abstract class WrappedEnchantment { ItemMeta meta = item.getItemMeta(); if(meta == null) return enchantments; - for (WrappedEnchantment enchantment : WrappedEnchantment.values()) { + // Vanilla optimised get + if (ItemUtil.INSTANCE.isEnchantedBook(item)) { + ((EnchantmentStorageMeta)meta).getStoredEnchants().forEach( + (enchantment, level) -> enchantments.put(getByKey(enchantment.getKey()), level) + ); + } else { + item.getEnchantments().forEach( + (enchantment, level) -> enchantments.put(getByKey(enchantment.getKey()), level) + ); + } + + // Unoptimised enchantment get + findEnchantsFromSelectedList(item, meta, enchantments, unoptimisedValues()); + + return enchantments; + } + + + /** + * Find enchantments of an item. only test the enchantment from the list. + * @param item Item to get enchantment from. + * @param meta Meta of the provided item. + * @param enchantments Map of enchantment to complete. + * @param enchantmentToTest Enchantment to test + */ + private static void findEnchantsFromSelectedList( + @NotNull ItemStack item, + @NotNull ItemMeta meta, + @NotNull Map enchantments, + @NotNull Collection enchantmentToTest){ + + for (WrappedEnchantment enchantment : enchantmentToTest) { if(enchantment.isEnchantmentPresent(item, meta)){ enchantments.put(enchantment, enchantment.getLevel(item, meta)); } } - return enchantments; } + // Register enchantment functions private static final HashMap BY_KEY = new HashMap<>(); private static final HashMap BY_NAME = new HashMap<>(); + private static final List UNOPTIMISED_ENCHANTMENT = new ArrayList<>(); /** * This should only be called on main of custom anvil. @@ -198,6 +257,10 @@ public abstract class WrappedEnchantment { BY_KEY.put(enchantment.getKey(), enchantment); BY_NAME.put(enchantment.getName(), enchantment); + + if(!enchantment.isOptimised()){ + UNOPTIMISED_ENCHANTMENT.add(enchantment); + } } /** @@ -241,4 +304,13 @@ public abstract class WrappedEnchantment { return BY_KEY.values().toArray(new WrappedEnchantment[0]); } + /** + * Gets a list of all the unoptimised enchantments. + * @return List of enchantment. + */ + @NotNull + private static List unoptimisedValues() { + return UNOPTIMISED_ENCHANTMENT; + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/VanillaEnchant.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/VanillaEnchant.java index 5bfd436..3347d0e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/VanillaEnchant.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/VanillaEnchant.java @@ -1,7 +1,6 @@ package xyz.alexcrea.cuanvil.enchant.wrapped; import io.delilaheve.util.ItemUtil; -import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; @@ -25,9 +24,14 @@ public class VanillaEnchant extends WrappedEnchantment { } + @Override + protected boolean isOptimised() { + return true; + } + @Override public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) { - if (isEnchantedBook(item)) { + if (ItemUtil.INSTANCE.isEnchantedBook(item)) { return ((EnchantmentStorageMeta)meta).getStoredEnchantLevel(this.enchantment); } else { return meta.getEnchantLevel(this.enchantment); @@ -47,7 +51,7 @@ public class VanillaEnchant extends WrappedEnchantment { @Override public void addEnchantmentUnsafe(@NotNull ItemStack item, int level) { - if (isEnchantedBook(item)) { + if (ItemUtil.INSTANCE.isEnchantedBook(item)) { EnchantmentStorageMeta bookMeta = ((EnchantmentStorageMeta)item.getItemMeta()); assert bookMeta != null; @@ -73,10 +77,6 @@ public class VanillaEnchant extends WrappedEnchantment { } - public static boolean isEnchantedBook(@NotNull ItemStack item){ - return Material.ENCHANTED_BOOK.equals(item.getType()); - } - public static EnchantmentRarity getRarity(Enchantment enchantment){ try {return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();} catch (IllegalArgumentException ignored) {}