Transporting Enchants via Anvil with Enchanted Books and Items

Discussion in 'Plugin Development' started by Drkmaster83, Jan 2, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    Drkmaster83

    I know that I must listen to the PrepareCraftItemEvent, but it's my first time dealing with it (as well as with anvil recipes), and the JavaDocs didn't do much good for me either. Could a I get a bit of help? I'm not going to be one to ask for code, so yeah.

    I basically want to take a high level enchantment on an Enchanted Book (Let's say... Sharpness 500) and put it on a sword that's in the anvil. I need to transform the StoredEnchant into an UnsafeEnchantment.
     
  2. Offline

    fireblast709

    Maybe the InventoryClickEvent (as afaik the Crafting events are not called for anvils)
     
  3. Offline

    Drkmaster83

    And then I'd check if the inventory's type was anvil? Hm.... This is confusing @.@
     
  4. Offline

    fireblast709

    Yes, it would seem checking that and editing the slots would be the solution to your problem. (As I cannot find anything else atm)
     
  5. Offline

    Drkmaster83

    Crafting events involving anvils contain booleans for them. I'm having issues with taking the enchantments on the books and applying them with the same level and enchantments on another item.
     
  6. Offline

    Cjreek

    Try this:

    Code:java
    1. EnchantmentStorageMeta meta = (EnchantmentStorageMeta)book.getItemMeta();
    2. resultItem.addUnsafeEnchantments(meta.getStoredEnchants());
     
  7. Offline

    fireblast709

    that boolean could also mean you are dumping 2 of the same tools or armor in the workbench
     
  8. Offline

    Drkmaster83

    My current method:
    Code:
    @EventHandler
        public void onAnvil(PrepareItemCraftEvent e)
        {
            if(e.isRepair() == true)
            {
                CraftingInventory ci = (CraftingInventory) e.getInventory();
                ItemStack secondslot = (ItemStack) ci.getMatrix()[1];
                if(secondslot.getType() == Material.ENCHANTED_BOOK)
                {
                    EnchantmentStorageMeta bookMeta = (EnchantmentStorageMeta) secondslot.getItemMeta();
                    ItemStack resultItem = (ItemStack) ci.getResult();
                    resultItem.addUnsafeEnchantments(bookMeta.getStoredEnchants());
                }
            }
        }
    ^ Doesn't work.
     
  9. Offline

    Drkmaster83

  10. Offline

    fireblast709

    If you want to use it in the workbench like that, create a Shapeless recipe
     
  11. Offline

    Drkmaster83

    I'm attempting to do the InventoryClickEvent now, but I keep getting an ArrayIndexOutOfBoundsException at the part where I try to .getItem(2);
    Code:
    @EventHandler
        public void onAnvil(InventoryClickEvent e)
        {
            if(e.getInventory().getType().equals(InventoryType.ANVIL))
            {
                if(e.getInventory().contains(Material.ENCHANTED_BOOK))
                {
                    AnvilInventory ai = (AnvilInventory) e.getInventory();
                    if(e.getInventory().getItem(1).getType() == Material.ENCHANTED_BOOK)
                    {
                        EnchantmentStorageMeta meta = (EnchantmentStorageMeta) e.getInventory().getItem(1).getItemMeta();
                        e.getInventory().getItem(2).addUnsafeEnchantments(meta.getStoredEnchants());
                    }
                    else
                    {
                        log.warning("FAIL");
                        return;
                    }
                }
                else
                {
                    log.warning("FAIL");
                }
            }
           
        }
     
  12. Offline

    Cjreek

    Hi,

    @Drkmaster83

    It took a little bit longer but I got it kinda working:

    Code:java
    1. @EventHandler
    2. public void onAnvil(InventoryClickEvent e)
    3. {
    4. if(e.getInventory().getType().equals(InventoryType.ANVIL))
    5. {
    6. AnvilInventory ai = (AnvilInventory) e.getInventory();
    7. if(ai.getItem(1) != null && ai.getItem(1).getType() == Material.ENCHANTED_BOOK)
    8. {
    9. if(ai.getItem(1).getType() == Material.ENCHANTED_BOOK)
    10. {
    11. EnchantmentStorageMeta meta = (EnchantmentStorageMeta) e.getInventory().getItem(1).getItemMeta();
    12. e.getCurrentItem().addUnsafeEnchantments(meta.getStoredEnchants());
    13. }
    14. }
    15. }
    16. }
    17.  


    The preview of the crafting result is still knockback II (if you put in a book with knockback >= 2) but if you take it, the result is enchanted with the correct level.
    I dont't think it's possible to get the preview right...
     
  13. Offline

    Drkmaster83

    I doubt it is, you'd probably have to modify the data of the getItem(2) ItemStack, but when you get that, it causes an exception. Even then, it's difficult to modify ItemMeta names when it comes to enchantments. Maybe you could erase all enchantments, add the unsafeEnchantments, then set the lore to enchantment name + level... Too complication. Thanks for your help, regardless.

    Cjreek
    P.S. This enables all items to be enchanted with normal repairing (Sharpness 5 on armor), I'm not quite sure I want that. Also, this allows any item you put in the first slot to be enchanted with whatever's on the book. You never added a check for that.
     
  14. Offline

    Cjreek

    Well just use a for-loop and check every stored enchantment like so:

    Code:java
    1. for (Enchantment ench: meta.getStoredEnchants())
    2. {
    3. if (ench.canEnchantItem(e.getCurrentItem()))
    4. e.getCurrentItem().addUnsafeEnchantment(ench);
    5. }


    On the other hand the anvil doesn't even show a result for those combinations.
    If you put a chestplate and an enchanted book (sharpness) in your anvil you'll get no result
    (except you're in creative mode I think).
     
Thread Status:
Not open for further replies.

Share This Page