papermc/Spigot-Server-Patches/0185-Ability-to-apply-mending-to-XP-API.patch
Aikar f5265d6688
Updated Upstream (Bukkit/CraftBukkit/Spigot)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
6ff65c82 SPIGOT-5908: CompassMeta for new lodestone compass data

CraftBukkit Changes:
3b9cf0f8 Improve code formatting
008f039f SPIGOT-5913: MOTD no longer supports new line character
b8b65eb7 SPIGOT-5908: CompassMeta for new lodestone compass data

Spigot Changes:
4d9262cf Rebuild patches
d27f7952 SPIGOT-5912: Outdated client message shows outdated server message
2020-07-01 02:11:46 -04:00

87 lines
4.2 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.
diff --git a/src/main/java/net/minecraft/server/EnchantmentManager.java b/src/main/java/net/minecraft/server/EnchantmentManager.java
index cea65c1d80a7bd303cf28a6fe2bd73d542a19557..92ceb8bb7d7c47e395dfdcfe6d01f807c048ddc1 100644
--- a/src/main/java/net/minecraft/server/EnchantmentManager.java
+++ b/src/main/java/net/minecraft/server/EnchantmentManager.java
@@ -251,6 +251,11 @@ public class EnchantmentManager {
return getEnchantmentLevel(Enchantments.CHANNELING, itemstack) > 0;
}
+ // Paper - OBFHELPER
+ public static @javax.annotation.Nonnull ItemStack getRandomEquippedItemWithEnchant(Enchantment enchantment, EntityLiving entityliving) {
+ Entry<EnumItemSlot, ItemStack> entry = b(enchantment, entityliving);
+ return entry != null ? entry.getValue() : ItemStack.NULL_ITEM;
+ }
@Nullable
public static Entry<EnumItemSlot, ItemStack> b(Enchantment enchantment, EntityLiving entityliving) {
return a(enchantment, entityliving, (itemstack) -> {
diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
index e7fb982913f391bafd608c4626086cd9cab7fad7..7f2d8de12473c5413bbfc10ea0947d6a30802645 100644
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java
+++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
@@ -249,10 +249,12 @@ public class EntityExperienceOrb extends Entity {
}
}
+ public int durToXp(int i) { return b(i); } // Paper OBFHELPER
private int b(int i) {
return i / 2;
}
+ public int xpToDur(int i) { return c(i); } // Paper OBFHELPER
private int c(int i) {
return i * 2;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index cc920cb20a7c1c77257e0219137775b362dfe602..0857e46a3b1e5cfa59907f092d0b174745c2c558 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1058,8 +1058,37 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return GameMode.getByValue(getHandle().playerInteractManager.getGameMode().getId());
}
+ // Paper start
@Override
- public void giveExp(int exp) {
+ public int applyMending(int amount) {
+ EntityPlayer handle = getHandle();
+ // Logic copied from EntityExperienceOrb and remapped to unobfuscated methods/properties
+ net.minecraft.server.ItemStack itemstack = net.minecraft.server.EnchantmentManager.getRandomEquippedItemWithEnchant(net.minecraft.server.Enchantments.MENDING, handle);
+ if (!itemstack.isEmpty() && itemstack.getItem().usesDurability()) {
+
+ net.minecraft.server.EntityExperienceOrb orb = net.minecraft.server.EntityTypes.EXPERIENCE_ORB.create(handle.world);
+ orb.value = amount;
+ orb.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM;
+ orb.setPositionRaw(handle.locX(), handle.locY(), handle.locZ());
+
+ int i = Math.min(orb.xpToDur(amount), itemstack.getDamage());
+ org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, i);
+ i = event.getRepairAmount();
+ orb.dead = true;
+ if (!event.isCancelled()) {
+ amount -= orb.durToXp(i);
+ itemstack.setDamage(itemstack.getDamage() - i);
+ }
+ }
+ return amount;
+ }
+
+ @Override
+ public void giveExp(int exp, boolean applyMending) {
+ if (applyMending) {
+ exp = this.applyMending(exp);
+ }
+ // Paper end
getHandle().giveExp(exp);
}