Anvil Unsafe Enchantments Not Working! Please Help!

Discussion in 'Spigot Plugin Development' started by plumppuffypig, Apr 14, 2017.

  1. Hello everyone! Sorry to bother you, but as you can tell from the title, I need help.
    I have created a quick plugin that will allow players to add Unsafe enchantments from books to weapons, which works wonderfully.

    However, it is also supposed to allow players to combine enchantments to make unsafe enchantments (ex. Sharpness 5 + Sharpness 5 = Sharpness 6)

    For some reason, half of the time it works fine, but every sometimes it will not combine the enchantments at all!
    (ex. Sharpness 2 + Sharpness 2 = Sharpness 2)

    Here's my code:
    Code (Text):

    package com.plumppuffyproductions.superAnvil;

    import java.util.Map;

    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.PrepareAnvilEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.EnchantmentStorageMeta;
    import org.bukkit.plugin.java.JavaPlugin;

    public class Main extends JavaPlugin implements Listener{
       
        @Override
        public void onEnable(){
            Bukkit.getPluginManager().registerEvents(this, this);
        }
       
        @Override
        public void onDisable(){
           
        }
       
        @EventHandler
        public void onAnvil(PrepareAnvilEvent e){
            if(e.getInventory().getItem(0) != null && e.getInventory().getItem(1) != null && e.getInventory().getItem(2) != null)
            {
                ItemStack result = e.getResult();
                ItemStack left = e.getInventory().getItem(2);
                ItemStack right = e.getInventory().getItem(1);
                if(left.getType() == right.getType()){
                    for(Enchantment enchantment : left.getEnchantments().keySet()){
                        if(right.containsEnchantment(enchantment) && right.getEnchantmentLevel(enchantment) == left.getEnchantmentLevel(enchantment)){
                            getServer().broadcastMessage("running");
                            result.addUnsafeEnchantment(enchantment, right.getEnchantmentLevel(enchantment) + 1);
                            getServer().broadcastMessage(enchantment.getName());
                        }
                    }
                   
                    e.setResult(result);
                }
                else if(left.getType() == Material.ENCHANTED_BOOK)
                {
                    EnchantmentStorageMeta bookmeta = (EnchantmentStorageMeta) left.getItemMeta();
                    Map<Enchantment, Integer> enchantments = bookmeta.getStoredEnchants();
                    result.addUnsafeEnchantments(enchantments);
                    result.addUnsafeEnchantments(left.getEnchantments());
                    e.setResult(result);
                }
            }
        }
    }

     

    Thanks in advance for helping!
     
  2. Hmm.. I'm not sure why it would work some of the time if this is the problem, but maybe try clearing the enchantments of the Result itemstack before running the for loop? I.e.
    Code (Java):
    result.getEnchantments().clear();
    If the .getEnchantments method just returns a copy of the map, this would be pointless, but it's worth a try.
     
  3. Thanks for the Suggestion, but that wouldn't work at all because of the reason you stated. Also, even if I try it, the clear line throws a "java.lang.UnsupportedOperationException"
     
  4. It may be the first line. When an event is fired, the state of things in the event are from BEFORE the event has taken place. That's why you are able to cancel events. So for example, if you click an item into an inventory, the event you get will show the slot as null because the item hasn't been placed yet. You're checking that all 3 slots aren't null. Try taking out the check for the result slot.

    I know this event isn't cancellable, but this still might be the case?
     
  5. Hmmm. I understand where you are coming from. Let me test it.

    Okay, it still didn't work. Nothing seems to have changed.

    After some testing, I found that on the times that it doesn't work, it runs all the way up to "right.getEnchantmentLevel(enchantment) == left.getEnchantmentLevel(enchantment)". and for some reason, that sometimes returns false. I tried broadcasting the level values and for some reason, it is sometimes returning 6 for the level of the left item even though I am combining two sharpness five swords.
     
  6. AHA
    I found the problem!

    I am so sorry this is entirely my fault.

    For those of you who are wondering, I just realized that I swapped the slots of the left and right variables with the result slot. The correct values would be left: 0, right: 1, and result: 2

    Thanks so much for your help!
     
    • Like Like x 1