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
 | 
			
		||||
@@ -72,16 +71,20 @@ public class ArmorListener implements Listener
 | 
			
		||||
                    equipping = false;
 | 
			
		||||
                if (newArmorType.equals(ArmorType.HELMET) &&
 | 
			
		||||
                    (equipping ? isAirOrNull(e.getWhoClicked().getInventory().getHelmet()) :
 | 
			
		||||
                        !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())))
 | 
			
		||||
                                                             isAirOrNull(e.getWhoClicked().getInventory().getBoots()) :
 | 
			
		||||
                                                             !isAirOrNull(e.getWhoClicked().getInventory().getBoots())))
 | 
			
		||||
                {
 | 
			
		||||
                    ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(),
 | 
			
		||||
                                                                          EquipMethod.SHIFT_CLICK, newArmorType,
 | 
			
		||||
@@ -118,16 +121,12 @@ public class ArmorListener implements Listener
 | 
			
		||||
                        newArmorType = ArmorType
 | 
			
		||||
                            .matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
 | 
			
		||||
                }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                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());
 | 
			
		||||
            }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem()))
 | 
			
		||||
                        // unequip with no new item going into the slot.
 | 
			
		||||
                        newArmorType = ArmorType.matchType(e.getCurrentItem());
 | 
			
		||||
                }
 | 
			
		||||
            if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot())
 | 
			
		||||
            {
 | 
			
		||||
                EquipMethod method = EquipMethod.PICK_DROP;
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -251,7 +241,7 @@ public class ArmorListener implements Listener
 | 
			
		||||
                ArmorType type = ArmorType.matchType(oldArmor);
 | 
			
		||||
                Bukkit.getServer().getPluginManager().callEvent(new ArmorEquipEvent(p, EquipMethod.DEATH,
 | 
			
		||||
                                                                                    type, oldArmor, null));
 | 
			
		||||
            // No way to cancel a death event.
 | 
			
		||||
                // No way to cancel a death event.
 | 
			
		||||
            }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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",
 | 
			
		||||
                                                            "PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL",
 | 
			
		||||
                                                            "THORNS", "BINDING_CURSE", "VANISHING_CURSE", "MENDING"));
 | 
			
		||||
        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,
 | 
			
		||||
                                                 enchantmentsComment);
 | 
			
		||||
        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