Switch to NamespacedKeys for enchantments
- Switched to using NamespacedKeys for enchantments instead of their names. This means that all properly registered custom enchantments are supported in one go. - Removed the overengineered enchantment platform stuff. That was built with the idea that every custom enchantment plugin would have their own way of implementing custom enchantments. However, now that I found out that custom enchantments can just be registered using NamespacedKeys, none of this is required anymore.
This commit is contained in:
parent
9d737eeed5
commit
03d0f9492e
@ -20,13 +20,16 @@ import nl.pim16aap2.armoredElytra.util.messages.Messages;
|
|||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class ArmoredElytra extends JavaPlugin implements Listener
|
public class ArmoredElytra extends JavaPlugin implements Listener
|
||||||
@ -35,6 +38,7 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
|||||||
.get(Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]);
|
.get(Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]);
|
||||||
|
|
||||||
private static ArmoredElytra INSTANCE;
|
private static ArmoredElytra INSTANCE;
|
||||||
|
private final Set<Enchantment> allowedEnchantments = new HashSet<>();
|
||||||
private Messages messages;
|
private Messages messages;
|
||||||
private ConfigLoader config;
|
private ConfigLoader config;
|
||||||
|
|
||||||
@ -107,8 +111,8 @@ public class ArmoredElytra extends JavaPlugin implements Listener
|
|||||||
|
|
||||||
// Log all allowed enchantments.
|
// Log all allowed enchantments.
|
||||||
myLogger(Level.INFO, ("Allowed enchantments:"));
|
myLogger(Level.INFO, ("Allowed enchantments:"));
|
||||||
for (final String s : config.allowedEnchantments())
|
for (final Enchantment enchantment : config.allowedEnchantments())
|
||||||
myLogger(Level.INFO, " - " + s);
|
myLogger(Level.INFO, " - " + enchantment.toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
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 + "]";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
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 List<EnchantmentContainer> containers = new ArrayList<>();
|
|
||||||
private Integer count = null;
|
|
||||||
|
|
||||||
public EnchantmentManager(final ItemStack is)
|
|
||||||
{
|
|
||||||
EnchantmentPlatformManager.get().getPlatforms().forEach(platform ->
|
|
||||||
containers.add(platform.getEnchantments(is)));
|
|
||||||
|
|
||||||
Collection<String> filter = ArmoredElytra.getInstance().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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +1,15 @@
|
|||||||
package nl.pim16aap2.armoredElytra.handlers;
|
package nl.pim16aap2.armoredElytra.handlers;
|
||||||
|
|
||||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||||
import nl.pim16aap2.armoredElytra.enchantment.EnchantmentManager;
|
|
||||||
import nl.pim16aap2.armoredElytra.util.Action;
|
import nl.pim16aap2.armoredElytra.util.Action;
|
||||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||||
|
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
|
||||||
import nl.pim16aap2.armoredElytra.util.Util;
|
import nl.pim16aap2.armoredElytra.util.Util;
|
||||||
import nl.pim16aap2.armoredElytra.util.XMaterial;
|
import nl.pim16aap2.armoredElytra.util.XMaterial;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
@ -90,7 +91,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle all anvil related stuff for this plugin.
|
// Handle all anvil related stuff for this plugin.
|
||||||
@EventHandler
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
private void onAnvilInventoryOpen(PrepareAnvilEvent event)
|
private void onAnvilInventoryOpen(PrepareAnvilEvent event)
|
||||||
{
|
{
|
||||||
Player player = (Player) event.getView().getPlayer();
|
Player player = (Player) event.getView().getPlayer();
|
||||||
@ -115,7 +116,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
|||||||
ArmorTier newTier = ArmorTier.NONE;
|
ArmorTier newTier = ArmorTier.NONE;
|
||||||
ArmorTier curTier = ArmoredElytra.getInstance().getNbtEditor().getArmorTier(itemA);
|
ArmorTier curTier = ArmoredElytra.getInstance().getNbtEditor().getArmorTier(itemA);
|
||||||
short durability = 0;
|
short durability = 0;
|
||||||
EnchantmentManager enchantments = new EnchantmentManager(itemA);
|
EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemA, plugin);
|
||||||
|
|
||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
@ -128,12 +129,12 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
|||||||
durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability()
|
durability = (short) (-itemA.getType().getMaxDurability() - itemA.getDurability()
|
||||||
- itemB.getDurability());
|
- itemB.getDurability());
|
||||||
durability = durability < 0 ? 0 : durability;
|
durability = durability < 0 ? 0 : durability;
|
||||||
enchantments.merge(new EnchantmentManager(itemB));
|
enchantments.merge(EnchantmentContainer.getEnchantments(itemB, plugin));
|
||||||
break;
|
break;
|
||||||
case CREATE:
|
case CREATE:
|
||||||
newTier = Util.armorToTier(itemB.getType());
|
newTier = Util.armorToTier(itemB.getType());
|
||||||
durability = 0;
|
durability = 0;
|
||||||
enchantments.merge(new EnchantmentManager(itemB));
|
enchantments.merge(EnchantmentContainer.getEnchantments(itemB, plugin));
|
||||||
break;
|
break;
|
||||||
case ENCHANT:
|
case ENCHANT:
|
||||||
newTier = curTier;
|
newTier = curTier;
|
||||||
@ -141,7 +142,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
|||||||
|
|
||||||
// If there aren't any illegal enchantments on the book, continue as normal.
|
// If there aren't any illegal enchantments on the book, continue as normal.
|
||||||
// Otherwise... Block.
|
// Otherwise... Block.
|
||||||
EnchantmentManager enchantmentsB = new EnchantmentManager(itemB);
|
EnchantmentContainer enchantmentsB = EnchantmentContainer.getEnchantments(itemB, plugin);
|
||||||
if (enchantmentsB.getEnchantmentCount() > 0)
|
if (enchantmentsB.getEnchantmentCount() > 0)
|
||||||
{
|
{
|
||||||
enchantments.merge(enchantmentsB);
|
enchantments.merge(enchantmentsB);
|
||||||
@ -159,7 +160,7 @@ public class AnvilHandler extends ArmoredElytraHandler implements Listener
|
|||||||
if (plugin.playerHasCraftPerm(player, newTier))
|
if (plugin.playerHasCraftPerm(player, newTier))
|
||||||
{
|
{
|
||||||
result = new ItemStack(Material.ELYTRA, 1);
|
result = new ItemStack(Material.ELYTRA, 1);
|
||||||
enchantments.apply(result);
|
enchantments.applyEnchantments(result);
|
||||||
result.setDurability(durability);
|
result.setDurability(durability);
|
||||||
|
|
||||||
result = ArmoredElytra.getInstance().getNbtEditor()
|
result = ArmoredElytra.getInstance().getNbtEditor()
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package nl.pim16aap2.armoredElytra.handlers;
|
package nl.pim16aap2.armoredElytra.handlers;
|
||||||
|
|
||||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||||
import nl.pim16aap2.armoredElytra.enchantment.EnchantmentManager;
|
|
||||||
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
import nl.pim16aap2.armoredElytra.util.ArmorTier;
|
||||||
|
import nl.pim16aap2.armoredElytra.util.EnchantmentContainer;
|
||||||
import nl.pim16aap2.armoredElytra.util.Util;
|
import nl.pim16aap2.armoredElytra.util.Util;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -40,7 +40,7 @@ public class SmithingTableHandler extends ArmoredElytraHandler implements Listen
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
final ArmorTier newTier = Util.armorToTier(itemStackB.getType());
|
final ArmorTier newTier = Util.armorToTier(itemStackB.getType());
|
||||||
final EnchantmentManager enchantments = new EnchantmentManager(itemStackA);
|
EnchantmentContainer enchantments = EnchantmentContainer.getEnchantments(itemStackA, plugin);
|
||||||
final Player player = (Player) event.getView().getPlayer();
|
final Player player = (Player) event.getView().getPlayer();
|
||||||
|
|
||||||
final ItemStack result;
|
final ItemStack result;
|
||||||
@ -49,7 +49,7 @@ public class SmithingTableHandler extends ArmoredElytraHandler implements Listen
|
|||||||
result = ArmoredElytra.getInstance().getNbtEditor()
|
result = ArmoredElytra.getInstance().getNbtEditor()
|
||||||
.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), newTier,
|
.addArmorNBTTags(new ItemStack(Material.ELYTRA, 1), newTier,
|
||||||
plugin.getConfigLoader().unbreakable());
|
plugin.getConfigLoader().unbreakable());
|
||||||
enchantments.apply(result);
|
enchantments.applyEnchantments(result);
|
||||||
event.setResult(result);
|
event.setResult(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package nl.pim16aap2.armoredElytra.util;
|
|||||||
|
|
||||||
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@ -29,7 +31,7 @@ public class ConfigLoader
|
|||||||
private int DIAMONDS_TO_FULL;
|
private int DIAMONDS_TO_FULL;
|
||||||
private int NETHERITE_TO_FULL;
|
private int NETHERITE_TO_FULL;
|
||||||
private boolean noFlightDurability;
|
private boolean noFlightDurability;
|
||||||
private LinkedHashSet<String> allowedEnchantments;
|
private LinkedHashSet<Enchantment> allowedEnchantments;
|
||||||
private boolean allowMultipleProtectionEnchantments;
|
private boolean allowMultipleProtectionEnchantments;
|
||||||
private boolean craftingInSmithingTable;
|
private boolean craftingInSmithingTable;
|
||||||
private boolean bypassWearPerm;
|
private boolean bypassWearPerm;
|
||||||
@ -70,8 +72,9 @@ public class ConfigLoader
|
|||||||
"List of enchantments that are allowed to be put on an armored elytra.",
|
"List of enchantments that are allowed to be put on an armored elytra.",
|
||||||
"If you do not want to allow any enchantments at all, remove them all and add \"NONE\"",
|
"If you do not want to allow any enchantments at all, remove them all and add \"NONE\"",
|
||||||
"You can find supported enchantments here:",
|
"You can find supported enchantments here:",
|
||||||
"https://hub.spigotmc.org/javadocs/spigot/org/bukkit/enchantments/Enchantment.html",
|
"https://github.com/PimvanderLoos/ArmoredElytra/blob/master/vanillaEnchantments",
|
||||||
"Note that only 1 protection enchantment (PROTECTION_FIRE, PROTECTION_ENVIRONMENTAL etc) can be active on an elytra."
|
"If you install additional enchantment plugins, you can add their enchantments as well.",
|
||||||
|
"Just add their 'NamespacedKey'. Ask the enchantment plugin dev for more info if you need it."
|
||||||
};
|
};
|
||||||
String[] updateComment =
|
String[] updateComment =
|
||||||
{
|
{
|
||||||
@ -119,9 +122,10 @@ public class ConfigLoader
|
|||||||
|
|
||||||
// Set default list of allowed enchantments.
|
// Set default list of allowed enchantments.
|
||||||
List<String> defaultAllowedEnchantments = new ArrayList<>(
|
List<String> defaultAllowedEnchantments = new ArrayList<>(
|
||||||
Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS",
|
Arrays.asList("minecraft:unbreaking", "minecraft:fire_protection", "minecraft:blast_protection",
|
||||||
"PROTECTION_PROJECTILE", "PROTECTION_ENVIRONMENTAL",
|
"minecraft:projectile_protection", "minecraft:protection",
|
||||||
"THORNS", "BINDING_CURSE", "VANISHING_CURSE", "MENDING"));
|
"minecraft:thorns", "minecraft:binding_curse", "minecraft:vanishing_curse",
|
||||||
|
"minecraft:mending"));
|
||||||
|
|
||||||
FileConfiguration config = plugin.getConfig();
|
FileConfiguration config = plugin.getConfig();
|
||||||
|
|
||||||
@ -145,8 +149,26 @@ public class ConfigLoader
|
|||||||
|
|
||||||
defaultAllowedEnchantments = addNewConfigOption(config, "allowedEnchantments", defaultAllowedEnchantments,
|
defaultAllowedEnchantments = addNewConfigOption(config, "allowedEnchantments", defaultAllowedEnchantments,
|
||||||
enchantmentsComment);
|
enchantmentsComment);
|
||||||
defaultAllowedEnchantments.replaceAll(String::toUpperCase);
|
|
||||||
allowedEnchantments = new LinkedHashSet<>(defaultAllowedEnchantments);
|
allowedEnchantments = new LinkedHashSet<>();
|
||||||
|
defaultAllowedEnchantments.forEach(
|
||||||
|
fullKey ->
|
||||||
|
{
|
||||||
|
String[] keyParts = fullKey.split(":", 2);
|
||||||
|
if (keyParts.length < 2)
|
||||||
|
{
|
||||||
|
Bukkit.getLogger().warning("\"" + fullKey + "\" is not a valid NamespacedKey!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NamespacedKey key = new NamespacedKey(keyParts[0], keyParts[1]);
|
||||||
|
Enchantment enchantment = Enchantment.getByKey(key);
|
||||||
|
if (enchantment == null)
|
||||||
|
{
|
||||||
|
Bukkit.getLogger().warning("The enchantment \"" + fullKey + "\" could not be found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
allowedEnchantments.add(enchantment);
|
||||||
|
});
|
||||||
|
|
||||||
allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false,
|
allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false,
|
||||||
allowMultipleProtectionEnchantmentsComment);
|
allowMultipleProtectionEnchantmentsComment);
|
||||||
@ -280,7 +302,7 @@ public class ConfigLoader
|
|||||||
return noFlightDurability;
|
return noFlightDurability;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedHashSet<String> allowedEnchantments()
|
public LinkedHashSet<Enchantment> allowedEnchantments()
|
||||||
{
|
{
|
||||||
return allowedEnchantments;
|
return allowedEnchantments;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,228 @@
|
|||||||
|
package nl.pim16aap2.armoredElytra.util;
|
||||||
|
|
||||||
|
import nl.pim16aap2.armoredElytra.ArmoredElytra;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.enchantments.Enchantment;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class EnchantmentContainer
|
||||||
|
{
|
||||||
|
private Map<Enchantment, Integer> enchantments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link EnchantmentContainer} from a map of enchantments.
|
||||||
|
*
|
||||||
|
* @param enchantments The enchantments.
|
||||||
|
* @param plugin The {@link ArmoredElytra} instance to use for obtaining the list of allowed enchantments. See
|
||||||
|
* {@link ConfigLoader#allowedEnchantments()}.
|
||||||
|
*/
|
||||||
|
public EnchantmentContainer(final Map<Enchantment, Integer> enchantments, final ArmoredElytra plugin)
|
||||||
|
{
|
||||||
|
this(enchantments);
|
||||||
|
this.filter(plugin.getConfigLoader().allowedEnchantments());
|
||||||
|
}
|
||||||
|
|
||||||
|
private EnchantmentContainer(final Map<Enchantment, Integer> enchantments)
|
||||||
|
{
|
||||||
|
this.enchantments = new HashMap<>(enchantments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the enchantments from an item.
|
||||||
|
*
|
||||||
|
* @param is The item.
|
||||||
|
* @param plugin The {@link ArmoredElytra} instance to use.
|
||||||
|
* @return A new {@link EnchantmentContainer} with the enchantments from the item.
|
||||||
|
*/
|
||||||
|
public static EnchantmentContainer getEnchantments(final ItemStack is, final ArmoredElytra plugin)
|
||||||
|
{
|
||||||
|
return is.getType() == Material.ENCHANTED_BOOK ?
|
||||||
|
getEnchantmentsFromBook(is, plugin) :
|
||||||
|
getEnchantmentsFromItem(is, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the enchantments from an item that is not a book.
|
||||||
|
*
|
||||||
|
* @param is The item.
|
||||||
|
* @param plugin The {@link ArmoredElytra} instance to use.
|
||||||
|
* @return A new {@link EnchantmentContainer} with the enchantments from the item.
|
||||||
|
*/
|
||||||
|
private static EnchantmentContainer getEnchantmentsFromItem(final ItemStack is, final ArmoredElytra plugin)
|
||||||
|
{
|
||||||
|
return new EnchantmentContainer(is.getEnchantments(), plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the enchantments from a book.
|
||||||
|
*
|
||||||
|
* @param is The book.
|
||||||
|
* @param plugin The {@link ArmoredElytra} instance to use.
|
||||||
|
* @return A new enchantment container with the enchantments from the book.
|
||||||
|
*/
|
||||||
|
private static EnchantmentContainer getEnchantmentsFromBook(final ItemStack is, final ArmoredElytra plugin)
|
||||||
|
{
|
||||||
|
if (!is.hasItemMeta())
|
||||||
|
return new EnchantmentContainer(new HashMap<>(0), plugin);
|
||||||
|
|
||||||
|
final EnchantmentStorageMeta meta = (EnchantmentStorageMeta) is.getItemMeta();
|
||||||
|
if (meta == null || !meta.hasStoredEnchants())
|
||||||
|
return new EnchantmentContainer(new HashMap<>(0), plugin);
|
||||||
|
|
||||||
|
return new EnchantmentContainer(meta.getStoredEnchants(), plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the total number of enchantments in this container.
|
||||||
|
*
|
||||||
|
* @return The total number of enchantments in this container.
|
||||||
|
*/
|
||||||
|
public int getEnchantmentCount()
|
||||||
|
{
|
||||||
|
return enchantments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public void filter(final Collection<Enchantment> allowed)
|
||||||
|
{
|
||||||
|
if (!enchantments.isEmpty())
|
||||||
|
enchantments.keySet().retainAll(allowed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the enchantments to an itemstack.
|
||||||
|
*
|
||||||
|
* @param is The itemstack to apply the enchantments to.
|
||||||
|
*/
|
||||||
|
public void applyEnchantments(final ItemStack is)
|
||||||
|
{
|
||||||
|
is.addUnsafeEnchantments(enchantments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges this container with another one.
|
||||||
|
*/
|
||||||
|
public void merge(EnchantmentContainer other)
|
||||||
|
{
|
||||||
|
enchantments = merge(this.enchantments, other.enchantments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of enchantments in this container.
|
||||||
|
*/
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return enchantments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this container is empty.
|
||||||
|
*
|
||||||
|
* @return True if there are exactly 0 enchantments in this container.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return enchantments.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges two enchantment containers.
|
||||||
|
*
|
||||||
|
* @param first The first enchantment container.
|
||||||
|
* @param second The second enchantment container. In case of conflicts, this will take precedence.
|
||||||
|
* @return The new map of enchantments.
|
||||||
|
*/
|
||||||
|
public static EnchantmentContainer merge(final EnchantmentContainer first, final EnchantmentContainer second)
|
||||||
|
{
|
||||||
|
return new EnchantmentContainer(merge(first.enchantments, second.enchantments));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges two maps of enchantments.
|
||||||
|
*
|
||||||
|
* @param first The first maps of enchantments.
|
||||||
|
* @param second The second maps of enchantments. In case of conflicts, this will take precedence.
|
||||||
|
* @return The new map of enchantments.
|
||||||
|
*/
|
||||||
|
private static Map<Enchantment, Integer> merge(final Map<Enchantment, Integer> first,
|
||||||
|
final Map<Enchantment, Integer> second)
|
||||||
|
{
|
||||||
|
if (second == null || second.isEmpty())
|
||||||
|
return first;
|
||||||
|
|
||||||
|
if (first == null || first.isEmpty())
|
||||||
|
return second;
|
||||||
|
|
||||||
|
final Map<Enchantment, Integer> combined = new HashMap<>(first);
|
||||||
|
for (Map.Entry<Enchantment, Integer> entry : second.entrySet())
|
||||||
|
{
|
||||||
|
Integer enchantLevel = first.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(first.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(first);
|
||||||
|
int protVal1 = Util.getProtectionEnchantmentsVal(second);
|
||||||
|
|
||||||
|
// 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 combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 + "]";
|
||||||
|
}
|
||||||
|
}
|
38
vanillaEnchantments
Normal file
38
vanillaEnchantments
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
minecraft:feather_falling
|
||||||
|
minecraft:frost_walker
|
||||||
|
minecraft:unbreaking
|
||||||
|
minecraft:projectile_protection
|
||||||
|
minecraft:knockback
|
||||||
|
minecraft:respiration
|
||||||
|
minecraft:punch
|
||||||
|
minecraft:protection
|
||||||
|
minecraft:blast_protection
|
||||||
|
minecraft:lure
|
||||||
|
minecraft:impaling
|
||||||
|
minecraft:smite
|
||||||
|
minecraft:silk_touch
|
||||||
|
minecraft:infinity
|
||||||
|
minecraft:thorns
|
||||||
|
minecraft:luck_of_the_sea
|
||||||
|
minecraft:multishot
|
||||||
|
minecraft:vanishing_curse
|
||||||
|
minecraft:fire_aspect
|
||||||
|
minecraft:depth_strider
|
||||||
|
minecraft:flame
|
||||||
|
minecraft:piercing
|
||||||
|
minecraft:fire_protection
|
||||||
|
minecraft:sharpness
|
||||||
|
minecraft:power
|
||||||
|
minecraft:sweeping
|
||||||
|
minecraft:aqua_affinity
|
||||||
|
minecraft:binding_curse
|
||||||
|
minecraft:bane_of_arthropods
|
||||||
|
minecraft:soul_speed
|
||||||
|
minecraft:looting
|
||||||
|
minecraft:efficiency
|
||||||
|
minecraft:mending
|
||||||
|
minecraft:riptide
|
||||||
|
minecraft:quick_charge
|
||||||
|
minecraft:fortune
|
||||||
|
minecraft:loyalty
|
||||||
|
minecraft:channeling
|
Loading…
Reference in New Issue
Block a user