Event before Mending enchantment

Discussion in 'Spigot Plugin Development' started by chrismin1302, May 6, 2017.

  1. EDIT: This event has been since added to Spigot! (not by me though) Please check out the PlayerItemMendEvent here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerItemMendEvent.html

    For my Custom Items API's Fake Durability System, I am trying to add Mending Support. However, there is one big issue. Mending is applied to the items that have the enchantment before the PlayerExpChangeEvent. This is a big problem because if Vanilla Items were used by the player, they would be repaired before the Custom Items would start being repaired. So, what I'm looking for is an event or some kind of way to detect the XP Orb being picked up / colliding with the player and then calculating Mending for both Vanillaand Custom Items. Looking at Spigot Source Code, there is no event before PlayerExpChangeEvent or any event about entities colliding, appart fron vehicles.
    Any help or ideas are very much appreciated.
    #1 chrismin1302, May 6, 2017
    Last edited: Sep 18, 2018
    • Like Like x 1
  2. No, sorry. I might have not explained it well. I'll simplify it a bit:
    I want to stop mending from working. When XP is collected, I want to have the true amount that was collected, and I can figure out the rest on my own.
    Right now, when XP is collected, Mending is applied before I can check how much XP was picked up.
    Thank you for your response!
  3. Bump! Still looking for a solution, no matter how hard it might be to implement.
  4. I'll keep on bumping...
  5. Choco


    If this is of any significance, net.minecraft.server.<version>.EntityExperienceOrb#d(EntityHuman) is the method that handles the pickup of experience orbs, and also applies the mending effect:
    Code (Java):
        public void d(final EntityHuman entityhuman) {
            if (!this.world.isClientSide && this.c == 0 && entityhuman.bz == 0) {
                entityhuman.bz = 2;
                entityhuman.receive(this, 1);
                // NOTE: This is where "Mending" takes effect. Enchantments#C is "mending"
                final ItemStack itemstack = EnchantmentManager.b(Enchantments.C, entityhuman);
                if (!itemstack.isEmpty() && itemstack.h()) {
                    final int i = Math.min(this.d(this.value), itemstack.i());
                    this.value -= this.b(i);
                    itemstack.setData(itemstack.i() - i);
                // NOTE: This is where the mending stops. PlayerExpChangeEvent takes effect afterwards
                if (this.value > 0) {
                    entityhuman.giveExp(CraftEventFactory.callPlayerExpChangeEvent(entityhuman, this.value).getAmount());
    As far as I'm aware, there may not be a way to determine the amount of experience that the orb contains unless you were to check before it was being picked up (before #d()) is called. I'm not sure where or when #d() is called in the code (I have no time to look at the moment), but with a bit of digging, I'm sure you could find something. It seems hard coded, however, so you may not have any luck
    • Like Like x 1
  6. Thank you for responding. I had already looked at the Source Code and knew that this method existed, but I couldn't find where it was used earlier on in the code. I'll look again when I get the time.
  7. Bump! Still nothing... I might have to give up on this one.
  8. You'll need a custom patch for the spigot server.
  9. What if I submit a Mending Event to be added to Spigot/Bukkit? I can check how the XP Event is handled and try to create an event in my own. I'd be more than fine with learning how to do that properly.
    Also, could I make my own class to replace the Vanilla Class after theserver has loaded? I remember there was some way to do that with the Bytecode but it's a very bodgy solution.
  10. As long as are fine with signing a NDA for spigot, if you haven't already, then go for it.