62 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			62 lines
		
	
	
	
		
			3.3 KiB
			
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | 
						|
From: Aikar <aikar@aikar.co>
 | 
						|
Date: Wed, 20 Dec 2017 17:36:49 -0500
 | 
						|
Subject: [PATCH] Ability to apply mending to XP API
 | 
						|
 | 
						|
This allows plugins that give players the ability to apply the experience
 | 
						|
points to the Item Mending formula, which will repair an item instead
 | 
						|
of giving the player experience points.
 | 
						|
 | 
						|
Both an API To standalone mend, and apply mending logic to .giveExp has been added.
 | 
						|
 | 
						|
== AT ==
 | 
						|
public net.minecraft.world.entity.ExperienceOrb durabilityToXp(I)I
 | 
						|
public net.minecraft.world.entity.ExperienceOrb xpToDurability(I)I
 | 
						|
 | 
						|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 | 
						|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
						|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 | 
						|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
 | 
						|
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
 | 
						|
     }
 | 
						|
 
 | 
						|
     @Override
 | 
						|
-    public void giveExp(int exp) {
 | 
						|
+    // Paper start
 | 
						|
+    public int applyMending(int amount) {
 | 
						|
+        ServerPlayer handle = this.getHandle();
 | 
						|
+        // Logic copied from EntityExperienceOrb and remapped to unobfuscated methods/properties
 | 
						|
+
 | 
						|
+        final Optional<net.minecraft.world.item.enchantment.EnchantedItemInUse> stackEntry = net.minecraft.world.item.enchantment.EnchantmentHelper
 | 
						|
+            .getRandomItemWith(net.minecraft.world.item.enchantment.EnchantmentEffectComponents.REPAIR_WITH_XP, handle, net.minecraft.world.item.ItemStack::isDamaged);
 | 
						|
+        final net.minecraft.world.item.ItemStack itemstack = stackEntry.map(net.minecraft.world.item.enchantment.EnchantedItemInUse::itemStack).orElse(net.minecraft.world.item.ItemStack.EMPTY);
 | 
						|
+        if (!itemstack.isEmpty() && itemstack.getItem().components().has(net.minecraft.core.component.DataComponents.MAX_DAMAGE)) {
 | 
						|
+            net.minecraft.world.entity.ExperienceOrb orb = net.minecraft.world.entity.EntityType.EXPERIENCE_ORB.create(handle.level());
 | 
						|
+            orb.value = amount;
 | 
						|
+            orb.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM;
 | 
						|
+            orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ());
 | 
						|
+
 | 
						|
+            final int possibleDurabilityFromXp = net.minecraft.world.item.enchantment.EnchantmentHelper.modifyDurabilityToRepairFromXp(
 | 
						|
+                handle.serverLevel(), itemstack, amount
 | 
						|
+            );
 | 
						|
+            int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue());
 | 
						|
+            org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.get().inSlot(), i);
 | 
						|
+            i = event.getRepairAmount();
 | 
						|
+            orb.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN);
 | 
						|
+            if (!event.isCancelled()) {
 | 
						|
+                amount -= i * amount / possibleDurabilityFromXp;
 | 
						|
+                itemstack.setDamageValue(itemstack.getDamageValue() - i);
 | 
						|
+            }
 | 
						|
+        }
 | 
						|
+        return amount;
 | 
						|
+    }
 | 
						|
+
 | 
						|
+    @Override
 | 
						|
+    public void giveExp(int exp, boolean applyMending) {
 | 
						|
+        if (applyMending) {
 | 
						|
+            exp = this.applyMending(exp);
 | 
						|
+        }
 | 
						|
+        // Paper end
 | 
						|
         this.getHandle().giveExperiencePoints(exp);
 | 
						|
     }
 | 
						|
 
 |