Solved How to enchant an item using enchantment table, without the table?

Discussion in 'Spigot Plugin Development' started by AuroraLS3, Jan 8, 2020.

  1. Hi.

    I want to create a fishing plugin that adds more treasure (because it gets boring after a while), but I'm in bit of a pickle.

    The Minecraft wiki says the following about enchantments on the treasure items:
    I'm wondering if there is a way to use the already existing enchantment code in some way (Is it possible to get EnchantmentOffers from somewhere?)
    A neat bonus would be if it would be possible to fire the enchant events too to get custom enchant plugins into the mix, but that's not at all necessary
     
  2. To my knowledge there is no API method for that so you have two options:
    1) Look into NMS and try to find how they do it (just follow the path from fishing to the enchantment)
    2) Look in the wiki and calculate the enchantments on your own.

    Firing the EnchantItemEvent might be a bit more tricky as it takes a InventoryView and a Block as constructor parameters so the plugins might have to handle the null values there. (Unless you somehow can get usable instances of those)
     
    • Like Like x 1
  3. @7smile7 is right, it's hardcoded. You can find the code that is (among others) responsible for the enchantment offers inside ContainerEnchantTable#a(IInventory), look especially at the lines 140++
     
  4. You might just be lucky.
    If you look at where the fishing result is being generated, Minecraft takes that out of a loot-table. Inside that loot-table, you will find the following line:
    Code (Text):
    "function": "minecraft:enchant_with_levels"
    so, in other words, I suppose there exists a function that does exactly that.
    However, if you simply want to modify the fishing result, you could also modify the Spigot-file (it's just a jar, it won't kill anything as long as you write propper JSON; the files are under spigot -> data -> minecraft -> loot_tables -> gameplay -> fishing).
    You could also get and set the loot table. Modifying spigot.jar is a bad idea since you could never update anything.
     
    • Useful Useful x 1
  5. Thanks guys, I'll look into the stuff you mentioned and see what I can do.
     
  6. Alright, so I went to EntityFishingHook, found the LootTable it is using, and then found
    Code (Text):
    LOGGER.warn("Datapack tried to redefine {} loot table, ignoring", LootTables.a);
    Which made me realize that I could just accomplish what I want with a datapack.
    And wohoo one exists https://www.planetminecraft.com/data-pack/fishing-datapack-more-items-to-catch-1-14/ - I modified this one to my liking

    ----

    Of course this doesn't help anybody who is looking how to enchant stuff so I still looked up how it works.

    The function mentioned by @Schottky (after deserialized) uses EnchantmentManager.a(Random, ItemStack, int, boolean) on line 279, which is a static function.

    You can call it like this:
    Code (Text):
    ItemStack itemStack;
    int levels; // This is what I assume, It might be something else than levels.
    boolean skipTreasureEnchants; // used in 'while(var7.isTreasure() && !var2)' so I assume it skips treasure enchants
    EnchantmentManager.a(new Random(), itemStack, levels, skipTreasureEnchants);
     
    #6 AuroraLS3, Jan 8, 2020
    Last edited: Jan 8, 2020
    • Winner Winner x 1