Implement modular enchantment system
- Added new enchantment management system that makes it easier to add support for custom enchantment plugins.
This commit is contained in:
		| @@ -1,7 +1,6 @@ | ||||
| package com.codingforcookies.armorequip; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import com.codingforcookies.armorequip.ArmorEquipEvent.EquipMethod; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.entity.Player; | ||||
| @@ -20,7 +19,7 @@ import org.bukkit.event.player.PlayerInteractEvent; | ||||
| import org.bukkit.event.player.PlayerItemBreakEvent; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import com.codingforcookies.armorequip.ArmorEquipEvent.EquipMethod; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * @author Arnah | ||||
| @@ -74,11 +73,15 @@ public class ArmorListener implements Listener | ||||
|                     (equipping ? isAirOrNull(e.getWhoClicked().getInventory().getHelmet()) : | ||||
|                      !isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) || | ||||
|                     newArmorType.equals(ArmorType.CHESTPLATE) && (equipping ? | ||||
|                         isAirOrNull(e.getWhoClicked().getInventory().getChestplate()) : | ||||
|                         !isAirOrNull(e.getWhoClicked().getInventory().getChestplate())) || | ||||
|                                                                   isAirOrNull(e.getWhoClicked().getInventory() | ||||
|                                                                                .getChestplate()) : | ||||
|                                                                   !isAirOrNull(e.getWhoClicked().getInventory() | ||||
|                                                                                 .getChestplate())) || | ||||
|                     newArmorType.equals(ArmorType.LEGGINGS) && (equipping ? | ||||
|                         isAirOrNull(e.getWhoClicked().getInventory().getLeggings()) : | ||||
|                         !isAirOrNull(e.getWhoClicked().getInventory().getLeggings())) || | ||||
|                                                                 isAirOrNull( | ||||
|                                                                     e.getWhoClicked().getInventory().getLeggings()) : | ||||
|                                                                 !isAirOrNull( | ||||
|                                                                     e.getWhoClicked().getInventory().getLeggings())) || | ||||
|                     newArmorType.equals(ArmorType.BOOTS) && (equipping ? | ||||
|                                                              isAirOrNull(e.getWhoClicked().getInventory().getBoots()) : | ||||
|                                                              !isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) | ||||
| @@ -123,10 +126,6 @@ public class ArmorListener implements Listener | ||||
|                     if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem())) | ||||
|                         // unequip with no new item going into the slot. | ||||
|                         newArmorType = ArmorType.matchType(e.getCurrentItem()); | ||||
|                 // e.getCurrentItem() == Unequip | ||||
|                 // e.getCursor() == Equip | ||||
|                 // newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? | ||||
|                 // e.getCurrentItem() : e.getCursor()); | ||||
|                 } | ||||
|             if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot()) | ||||
|             { | ||||
| @@ -204,15 +203,6 @@ public class ArmorListener implements Listener | ||||
|                 event.setCancelled(true); | ||||
|             } | ||||
|         } | ||||
|         // Debug shit | ||||
|         /* | ||||
|          * System.out.println("Slots: " + event.getInventorySlots().toString()); | ||||
|          * System.out.println("Raw Slots: " + event.getRawSlots().toString()); | ||||
|          * if(event.getCursor() != null){ System.out.println("Cursor: " + | ||||
|          * event.getCursor().getType().name()); } if(event.getOldCursor() != null){ | ||||
|          * System.out.println("OldCursor: " + event.getOldCursor().getType().name()); } | ||||
|          * System.out.println("Type: " + event.getType().name()); | ||||
|          */ | ||||
|     } | ||||
|  | ||||
|     @EventHandler | ||||
|   | ||||
| @@ -41,7 +41,6 @@ public class ArmoredElytra extends JavaPlugin implements Listener | ||||
|  | ||||
|     private final Map<ArmorTier, ArmorTierName> armorTierNames = new EnumMap<>(ArmorTier.class); | ||||
|     private boolean upToDate; | ||||
|     private boolean is1_9; | ||||
|     private UpdateManager updateManager; | ||||
|  | ||||
|     private INBTEditor nbtEditor; | ||||
| @@ -57,13 +56,6 @@ public class ArmoredElytra extends JavaPlugin implements Listener | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| ////        Material mat = Material.ELYTRA; | ||||
| ////        n3kas.ae.Core.canApplyTo(mat); | ||||
| //        for (String str : n3kas.ae.api.getAllEnchantments()) | ||||
| //            System.out.println(str); | ||||
| //        System.exit(0); | ||||
|  | ||||
|         nbtEditor = new NBTEditor(); | ||||
|         if (isBlacklistedVersion()) | ||||
|         { | ||||
|             myLogger(Level.SEVERE, | ||||
| @@ -74,6 +66,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener | ||||
|                     "blacklisted version of Spiogt! Please update Spigot!"), this); | ||||
|             return; | ||||
|         } | ||||
|         nbtEditor = new NBTEditor(); | ||||
|  | ||||
|         config = new ConfigLoader(this); | ||||
|         messages = new Messages(this); | ||||
|   | ||||
| @@ -0,0 +1,69 @@ | ||||
| package nl.pim16aap2.armoredElytra.enchantment; | ||||
|  | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.Map; | ||||
|  | ||||
| class EnchantmentContainer | ||||
| { | ||||
|     private Map<String, Integer> enchantments; | ||||
|     private final IEnchantmentPlatform manager; | ||||
|  | ||||
|     public EnchantmentContainer(final Map<String, Integer> enchantments, final IEnchantmentPlatform manager) | ||||
|     { | ||||
|         this.enchantments = enchantments; | ||||
|         this.manager = manager; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Removes any entries from the list of enchantments that do not exist in the provided filter. | ||||
|      * | ||||
|      * @param allowed The names of enchantments (upper case) that are allowed. Any names not in this list are removed. | ||||
|      * @return This instance. | ||||
|      */ | ||||
|     public EnchantmentContainer filter(final Collection<String> allowed) | ||||
|     { | ||||
|         if (!enchantments.isEmpty()) | ||||
|             enchantments.keySet().retainAll(allowed); | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Applies the enchantments to an itemstack. | ||||
|      * | ||||
|      * @param is The itemstack to apply the enchantments to. | ||||
|      */ | ||||
|     public void apply(final ItemStack is) | ||||
|     { | ||||
|         manager.applyEnchantments(is, enchantments); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Merges this container with another one. | ||||
|      */ | ||||
|     public void merge(EnchantmentContainer other) | ||||
|     { | ||||
|         if (!(manager.getClass() == other.manager.getClass())) | ||||
|             throw new RuntimeException("Trying to add enchantment containers of different types!"); | ||||
|         enchantments = manager.merge(enchantments, other.enchantments); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the number of enchantments in this container. | ||||
|      */ | ||||
|     public int size() | ||||
|     { | ||||
|         return enchantments.size(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String toString() | ||||
|     { | ||||
|         StringBuilder sb = new StringBuilder("["); | ||||
|         enchantments.forEach((k, v) -> sb.append("\"").append(k).append("\" (").append(v).append("), ")); | ||||
|         String ret = sb.toString(); | ||||
|         ret = ret.length() > 1 ? ret.substring(0, ret.length() - 2) : ret; | ||||
|         return ret + "]"; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,73 @@ | ||||
| package nl.pim16aap2.armoredElytra.enchantment; | ||||
|  | ||||
| import nl.pim16aap2.armoredElytra.ArmoredElytra; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| public class EnchantmentManager | ||||
| { | ||||
|     private final ArmoredElytra armoredElytra; | ||||
|     private final List<EnchantmentContainer> containers = new ArrayList<>(); | ||||
|     private Integer count = null; | ||||
|  | ||||
|     public EnchantmentManager(final ItemStack is) | ||||
|     { | ||||
|         armoredElytra = ArmoredElytra.getInstance(); | ||||
|         EnchantmentPlatformManager.get().getPlatforms().forEach(platform -> | ||||
|                                                                     containers.add(platform.getEnchantments(is))); | ||||
|  | ||||
|         Collection<String> filter = armoredElytra.getConfigLoader().allowedEnchantments(); | ||||
|         containers.forEach(container -> container.filter(filter)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Merges this EnchantmentManager with another one. | ||||
|      * | ||||
|      * @param other The EnchantmentManager to merge into the current one. | ||||
|      * @return The instance of the current EnchantmentManager. | ||||
|      */ | ||||
|     public EnchantmentManager merge(final EnchantmentManager other) | ||||
|     { | ||||
|         for (int idx = 0; idx < containers.size(); ++idx) | ||||
|             containers.get(idx).merge(other.containers.get(idx)); | ||||
|         count = null; // Reset count, as it's no longer up-to-date. | ||||
|         return this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Applies all the enchantments to the provided itemstack. | ||||
|      * | ||||
|      * @param is The itemstack to apply all enchantments to. | ||||
|      */ | ||||
|     public void apply(final ItemStack is) | ||||
|     { | ||||
|         containers.forEach(container -> container.apply(is)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the total number of enchantments. | ||||
|      * | ||||
|      * @return The total number of enchantments. | ||||
|      */ | ||||
|     public int getEnchantmentCount() | ||||
|     { | ||||
|         if (count != null) | ||||
|             return count; | ||||
|  | ||||
|         count = 0; | ||||
|         for (EnchantmentContainer container : containers) | ||||
|             count += container.size(); | ||||
|         return count; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String toString() | ||||
|     { | ||||
|         StringBuilder sb = new StringBuilder("Enchantments: \n"); | ||||
|         containers.forEach(container -> sb.append(container.toString()).append("\n")); | ||||
|         return sb.toString(); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,30 @@ | ||||
| package nl.pim16aap2.armoredElytra.enchantment; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| public class EnchantmentPlatformManager | ||||
| { | ||||
|     private static final EnchantmentPlatformManager INSTANCE = new EnchantmentPlatformManager(); | ||||
|     private final List<IEnchantmentPlatform> platforms = new ArrayList<>(); | ||||
|  | ||||
|     private EnchantmentPlatformManager() | ||||
|     { | ||||
|         addPlatform(new VanillaEnchantmentPlatform()); | ||||
|     } | ||||
|  | ||||
|     public static EnchantmentPlatformManager get() | ||||
|     { | ||||
|         return INSTANCE; | ||||
|     } | ||||
|  | ||||
|     public void addPlatform(final IEnchantmentPlatform platform) | ||||
|     { | ||||
|         platforms.add(platform); | ||||
|     } | ||||
|  | ||||
|     public List<IEnchantmentPlatform> getPlatforms() | ||||
|     { | ||||
|         return platforms; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,22 @@ | ||||
| package nl.pim16aap2.armoredElytra.enchantment; | ||||
|  | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
|  | ||||
| import java.util.Map; | ||||
|  | ||||
| interface IEnchantmentPlatform | ||||
| { | ||||
|     EnchantmentContainer getEnchantmentsFromItem(final ItemStack is); | ||||
|  | ||||
|     EnchantmentContainer getEnchantmentsFromBook(final ItemStack is); | ||||
|  | ||||
|     default EnchantmentContainer getEnchantments(final ItemStack is) | ||||
|     { | ||||
|         return is.getType() == Material.ENCHANTED_BOOK ? getEnchantmentsFromBook(is) : getEnchantmentsFromItem(is); | ||||
|     } | ||||
|  | ||||
|     void applyEnchantments(final ItemStack is, final Map<String, Integer> enchantments); | ||||
|  | ||||
|     Map<String, Integer> merge(final Map<String, Integer> first, final Map<String, Integer> second); | ||||
| } | ||||
| @@ -0,0 +1,131 @@ | ||||
| package nl.pim16aap2.armoredElytra.enchantment; | ||||
|  | ||||
| import nl.pim16aap2.armoredElytra.ArmoredElytra; | ||||
| import nl.pim16aap2.armoredElytra.util.Util; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.enchantments.Enchantment; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.inventory.meta.EnchantmentStorageMeta; | ||||
|  | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.logging.Level; | ||||
|  | ||||
| class VanillaEnchantmentPlatform implements IEnchantmentPlatform | ||||
| { | ||||
|     private Map<String, Integer> getNamedEnchantments(final Map<Enchantment, Integer> enchantments) | ||||
|     { | ||||
|         final Map<String, Integer> enchantmentsStr = new HashMap<>(enchantments.size()); | ||||
|         enchantments.forEach((k, v) -> enchantmentsStr.put(k.getName(), v)); | ||||
|         return enchantmentsStr; | ||||
|     } | ||||
|  | ||||
|     private Map<Enchantment, Integer> getEnchantments(final Map<String, Integer> enchantments) | ||||
|     { | ||||
|         final Map<Enchantment, Integer> enchantmentsStr = new HashMap<>(enchantments.size()); | ||||
|         enchantments.forEach((k, v) -> enchantmentsStr.put(Enchantment.getByName(k), v)); | ||||
|         return enchantmentsStr; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public EnchantmentContainer getEnchantmentsFromItem(final ItemStack is) | ||||
|     { | ||||
|         return new EnchantmentContainer(getNamedEnchantments(is.getEnchantments()), this); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public EnchantmentContainer getEnchantmentsFromBook(final ItemStack is) | ||||
|     { | ||||
|         if (!is.hasItemMeta()) | ||||
|             return new EnchantmentContainer(new HashMap<>(0), this); | ||||
|  | ||||
|         EnchantmentStorageMeta meta = (EnchantmentStorageMeta) is.getItemMeta(); | ||||
|         if (meta == null || !meta.hasStoredEnchants()) | ||||
|             return new EnchantmentContainer(new HashMap<>(0), this); | ||||
|  | ||||
|         return new EnchantmentContainer(getNamedEnchantments(meta.getStoredEnchants()), this); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void applyEnchantments(final ItemStack is, final Map<String, Integer> enchantments) | ||||
|     { | ||||
|         enchantments.forEach( | ||||
|             (enchantmentName, level) -> | ||||
|             { | ||||
|                 Enchantment enchantment = Enchantment.getByName(enchantmentName); | ||||
|                 if (enchantment == null) | ||||
|                 { | ||||
|                     Bukkit.getLogger().log(Level.INFO, "Failed to find enchantment: \"" + enchantmentName + "\""); | ||||
|                     return; | ||||
|                 } | ||||
|                 is.addUnsafeEnchantment(enchantment, level); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Map<String, Integer> merge(final Map<String, Integer> first, final Map<String, Integer> second) | ||||
|     { | ||||
|         if (second == null || second.isEmpty()) | ||||
|             return first; | ||||
|  | ||||
|         if (first == null || first.isEmpty()) | ||||
|             return second; | ||||
|  | ||||
|         Map<Enchantment, Integer> enchantments0 = getEnchantments(first); | ||||
|         Map<Enchantment, Integer> enchantments1 = getEnchantments(second); | ||||
|         Map<Enchantment, Integer> combined = new HashMap<>(enchantments0); | ||||
|  | ||||
|         for (Map.Entry<Enchantment, Integer> entry : enchantments1.entrySet()) | ||||
|         { | ||||
|             Integer enchantLevel = enchantments0.get(entry.getKey()); | ||||
|             if (enchantLevel != null) | ||||
|             { | ||||
|                 if (entry.getValue().equals(enchantLevel) && entry.getValue() < entry.getKey().getMaxLevel()) | ||||
|                     enchantLevel = entry.getValue() + 1; | ||||
|                 else if (entry.getValue() > enchantLevel) | ||||
|                     enchantLevel = entry.getValue(); | ||||
|  | ||||
|                 // If the enchantment level has changed, | ||||
|                 if (!enchantLevel.equals(enchantments0.get(entry.getKey()))) | ||||
|                 { | ||||
|                     combined.remove(entry.getKey()); | ||||
|                     combined.put(entry.getKey(), enchantLevel); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|                 combined.put(entry.getKey(), entry.getValue()); | ||||
|         } | ||||
|  | ||||
|         if (!ArmoredElytra.getInstance().getConfigLoader().allowMultipleProtectionEnchantments()) | ||||
|         { | ||||
|             // Get the protection enchantment rating for both enchantment sets. | ||||
|             int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0); | ||||
|             int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1); | ||||
|  | ||||
|             // If they have different protection enchantments, keep enchantment1's enchantments | ||||
|             // And remove the protection enchantment from enchantments0. | ||||
|             if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1) | ||||
|                 switch (protVal0) | ||||
|                 { | ||||
|                     case 1: | ||||
|                         combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         combined.remove(Enchantment.PROTECTION_EXPLOSIONS); | ||||
|                         break; | ||||
|                     case 4: | ||||
|                         combined.remove(Enchantment.PROTECTION_FALL); | ||||
|                         break; | ||||
|                     case 8: | ||||
|                         combined.remove(Enchantment.PROTECTION_FIRE); | ||||
|                         break; | ||||
|                     case 16: | ||||
|                         combined.remove(Enchantment.PROTECTION_PROJECTILE); | ||||
|                         break; | ||||
|                 } | ||||
|         } | ||||
|  | ||||
|         return getNamedEnchantments(combined); | ||||
|     } | ||||
| } | ||||
| @@ -5,6 +5,7 @@ import com.codingforcookies.armorequip.ArmorListener; | ||||
| import com.codingforcookies.armorequip.ArmorType; | ||||
| import com.codingforcookies.armorequip.DispenserArmorListener; | ||||
| import nl.pim16aap2.armoredElytra.ArmoredElytra; | ||||
| import nl.pim16aap2.armoredElytra.enchantment.EnchantmentManager; | ||||
| import nl.pim16aap2.armoredElytra.util.Action; | ||||
| import nl.pim16aap2.armoredElytra.util.AllowedToWearEnum; | ||||
| import nl.pim16aap2.armoredElytra.util.ArmorTier; | ||||
| @@ -24,11 +25,8 @@ import org.bukkit.event.inventory.InventoryType; | ||||
| import org.bukkit.event.inventory.PrepareAnvilEvent; | ||||
| import org.bukkit.inventory.AnvilInventory; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.inventory.meta.EnchantmentStorageMeta; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.Random; | ||||
| import java.util.logging.Level; | ||||
|  | ||||
| @@ -78,85 +76,6 @@ public class EventHandlers implements Listener | ||||
|             anvilInventory.getItem(2).setAmount(0); | ||||
|     } | ||||
|  | ||||
|     // Check if the enchantment is allowed on elytras. | ||||
|     private boolean isAllowedEnchantment(Enchantment enchant) | ||||
|     { | ||||
|         for (String s : plugin.getConfigLoader().allowedEnchantments()) | ||||
|             if (Enchantment.getByName(s) != null) | ||||
|                 if (Enchantment.getByName(s).equals(enchant)) | ||||
|                     return true; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     // Combine 2 maps of enchantments (and remove any invalid ones). | ||||
|     private Map<Enchantment, Integer> combineEnchantments(Map<Enchantment, Integer> enchantments0, | ||||
|                                                           Map<Enchantment, Integer> enchantments1) | ||||
|     { | ||||
|         enchantments0 = fixEnchantments(enchantments0); | ||||
|         Map<Enchantment, Integer> combined = new HashMap<>(fixEnchantments(enchantments0)); | ||||
|  | ||||
|         // If the second set of enchantments is null, the combined enchantments are just | ||||
|         // the first enchantments. | ||||
|         if (enchantments1 == null) | ||||
|             return combined; | ||||
|  | ||||
|         enchantments1 = fixEnchantments(enchantments1); | ||||
|         // Loop through the enchantments of item1. | ||||
|         for (Map.Entry<Enchantment, Integer> entry : enchantments1.entrySet()) | ||||
|         { | ||||
|             Integer enchantLevel = enchantments0.get(entry.getKey()); | ||||
|             if (enchantLevel != null) | ||||
|             { | ||||
|                 if (entry.getValue().equals(enchantLevel) && entry.getValue() < entry.getKey().getMaxLevel()) | ||||
|                     enchantLevel = entry.getValue() + 1; | ||||
|                 else if (entry.getValue() > enchantLevel) | ||||
|                     enchantLevel = entry.getValue(); | ||||
|  | ||||
|                 // If the enchantment level has changed, | ||||
|                 if (!enchantLevel.equals(enchantments0.get(entry.getKey()))) | ||||
|                 { | ||||
|                     combined.remove(entry.getKey()); | ||||
|                     combined.put(entry.getKey(), enchantLevel); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|                 combined.put(entry.getKey(), entry.getValue()); | ||||
|         } | ||||
|  | ||||
|         if (!plugin.getConfigLoader().allowMultipleProtectionEnchantments()) | ||||
|         { | ||||
|             // Get the protection enchantment rating for both enchantment sets. | ||||
|             int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0); | ||||
|             int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1); | ||||
|  | ||||
|             // If they have different protection enchantments, keep enchantment1's | ||||
|             // enchantments | ||||
|             // And remove the protection enchantment from enchantments0. Yes, this system | ||||
|             // only works | ||||
|             // If there is 1 protection enchantment on | ||||
|             if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1) | ||||
|                 switch (protVal0) | ||||
|                 { | ||||
|                     case 1: | ||||
|                         combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         combined.remove(Enchantment.PROTECTION_EXPLOSIONS); | ||||
|                         break; | ||||
|                     case 4: | ||||
|                         combined.remove(Enchantment.PROTECTION_FALL); | ||||
|                         break; | ||||
|                     case 8: | ||||
|                         combined.remove(Enchantment.PROTECTION_FIRE); | ||||
|                         break; | ||||
|                     case 16: | ||||
|                         combined.remove(Enchantment.PROTECTION_PROJECTILE); | ||||
|                         break; | ||||
|                 } | ||||
|         } | ||||
|         return combined; | ||||
|     } | ||||
|  | ||||
|     // Repair an Armored Elytra | ||||
|     private short repairItem(short curDur, ItemStack repairItem) | ||||
|     { | ||||
| @@ -182,32 +101,12 @@ public class EventHandlers implements Listener | ||||
|         return (short) (newDurability <= 0 ? 0 : newDurability); | ||||
|     } | ||||
|  | ||||
|     // Remove any disallowed enchantments in the map. | ||||
|     private Map<Enchantment, Integer> fixEnchantments(Map<Enchantment, Integer> enchantments) | ||||
|     { | ||||
|         Map<Enchantment, Integer> ret = new HashMap<>(enchantments); | ||||
|         for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) | ||||
|             if (!isAllowedEnchantment(entry.getKey())) | ||||
|                 ret.remove(entry.getKey()); | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     // Verify there aren't any disallowed enchantments in the map. | ||||
|     private int verifyEnchantments(Map<Enchantment, Integer> enchantments) | ||||
|     { | ||||
|         int ret = 0; | ||||
|         for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) | ||||
|             if (!isAllowedEnchantment(entry.getKey())) | ||||
|                 ++ret; | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
|     // Valid inputs: | ||||
|     //  - Elytra (armored or not)    + chestplate             -> Create Armored Elytra | ||||
|     //  - Elytra (armored)           + enchanted book         -> Enchant | ||||
|     //  - Elytra (armored)           + its repair item        -> Repair | ||||
|     //  - Elytra (armored)           + other elytra (armored) -> Combine (Enchant + Repair) | ||||
|     //  ! Elytra (armored, !leather) + leather                -> Block | ||||
|     //  ! Elytra (armored, !leather) + leather/membrane       -> Block | ||||
|     // | ||||
|     // Ignoring: | ||||
|     //  - Elytra (not armored)       + !chestplate            -> None | ||||
| @@ -288,8 +187,7 @@ public class EventHandlers implements Listener | ||||
|             ArmorTier newTier = ArmorTier.NONE; | ||||
|             ArmorTier curTier = ArmoredElytra.getInstance().getNbtEditor().getArmorTier(itemA); | ||||
|             short durability = 0; | ||||
|             Map<Enchantment, Integer> enchantments = itemA.getEnchantments(); | ||||
|             enchantments = fixEnchantments(enchantments); | ||||
|             EnchantmentManager enchantments = new EnchantmentManager(itemA); | ||||
|  | ||||
|             switch (action) | ||||
|             { | ||||
| @@ -302,22 +200,23 @@ public class EventHandlers implements Listener | ||||
|                     durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability() | ||||
|                         - itemB.getDurability()); | ||||
|                     durability = durability < 0 ? 0 : durability; | ||||
|                     enchantments = combineEnchantments(enchantments, itemB.getEnchantments()); | ||||
|                     enchantments.merge(new EnchantmentManager(itemB)); | ||||
|                     break; | ||||
|                 case CREATE: | ||||
|                     newTier = Util.armorToTier(itemB.getType()); | ||||
|                     durability = 0; | ||||
|                     enchantments = combineEnchantments(enchantments, itemB.getEnchantments()); | ||||
|                     enchantments.merge(new EnchantmentManager(itemB)); | ||||
|                     break; | ||||
|                 case ENCHANT: | ||||
|                     EnchantmentStorageMeta meta = (EnchantmentStorageMeta) itemB.getItemMeta(); | ||||
|                     newTier = curTier; | ||||
|                     durability = itemA.getDurability(); | ||||
|  | ||||
|                     // If there aren't any illegal enchantments on the book, continue as normal. | ||||
|                     // Otherwise... Block. | ||||
|                     if (verifyEnchantments(meta.getStoredEnchants()) != meta.getStoredEnchants().size()) | ||||
|                     EnchantmentManager enchantmentsB = new EnchantmentManager(itemB); | ||||
|                     if (enchantmentsB.getEnchantmentCount() > 0) | ||||
|                     { | ||||
|                         enchantments = combineEnchantments(enchantments, meta.getStoredEnchants()); | ||||
|                         enchantments.merge(enchantmentsB); | ||||
|                         break; | ||||
|                     } | ||||
|                     //$FALL-THROUGH$ | ||||
| @@ -332,8 +231,7 @@ public class EventHandlers implements Listener | ||||
|             if (plugin.playerHasCraftPerm(player, newTier)) | ||||
|             { | ||||
|                 result = new ItemStack(Material.ELYTRA, 1); | ||||
|                 if (enchantments != null) | ||||
|                     result.addUnsafeEnchantments(enchantments); | ||||
|                 enchantments.apply(result); | ||||
|                 result.setDurability(durability); | ||||
|  | ||||
|                 result = ArmoredElytra.getInstance().getNbtEditor() | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.LinkedHashSet; | ||||
| import java.util.List; | ||||
| import java.util.logging.Level; | ||||
|  | ||||
| @@ -28,7 +29,7 @@ public class ConfigLoader | ||||
|     private int DIAMONDS_TO_FULL; | ||||
|     private int NETHERITE_TO_FULL; | ||||
|     private boolean noFlightDurability; | ||||
|     private List<String> allowedEnchantments; | ||||
|     private LinkedHashSet<String> allowedEnchantments; | ||||
|     private boolean allowMultipleProtectionEnchantments; | ||||
|     private boolean craftingInSmithingTable; | ||||
|     private boolean bypassWearPerm; | ||||
| @@ -117,9 +118,11 @@ public class ConfigLoader | ||||
|  | ||||
|  | ||||
|         // Set default list of allowed enchantments. | ||||
|         allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS", | ||||
|         List<String> defaultAllowedEnchantments = new ArrayList<>( | ||||
|             Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS", | ||||
|                           "PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL", | ||||
|                           "THORNS", "BINDING_CURSE", "VANISHING_CURSE", "MENDING")); | ||||
|  | ||||
|         FileConfiguration config = plugin.getConfig(); | ||||
|  | ||||
|         unbreakable = addNewConfigOption(config, "unbreakable", false, unbreakableComment); | ||||
| @@ -133,8 +136,11 @@ public class ConfigLoader | ||||
| //        craftingInSmithingTable = addNewConfigOption(config, "craftingInSmithingTable", true, craftingInSmithingTableComment); | ||||
|         craftingInSmithingTable = false; | ||||
|  | ||||
|         allowedEnchantments = addNewConfigOption(config, "allowedEnchantments", allowedEnchantments, | ||||
|         defaultAllowedEnchantments = addNewConfigOption(config, "allowedEnchantments", defaultAllowedEnchantments, | ||||
|                                                         enchantmentsComment); | ||||
|         defaultAllowedEnchantments.replaceAll(String::toUpperCase); | ||||
|         allowedEnchantments = new LinkedHashSet<>(defaultAllowedEnchantments); | ||||
|  | ||||
|         allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false, | ||||
|                                                                  allowMultipleProtectionEnchantmentsComment); | ||||
|         checkForUpdates = addNewConfigOption(config, "checkForUpdates", true, updateComment); | ||||
| @@ -267,7 +273,7 @@ public class ConfigLoader | ||||
|         return noFlightDurability; | ||||
|     } | ||||
|  | ||||
|     public List<String> allowedEnchantments() | ||||
|     public LinkedHashSet<String> allowedEnchantments() | ||||
|     { | ||||
|         return allowedEnchantments; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 
				 Pim van der Loos
					Pim van der Loos