From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sun, 14 Jul 2019 19:52:47 -0500
Subject: [PATCH] Mending mends most damages equipment first


diff --git a/src/main/java/net/minecraft/server/EnchantmentManager.java b/src/main/java/net/minecraft/server/EnchantmentManager.java
index 7b263594304a9b745f583fe7178ac16936cbd93b..33e2dc3a1003fe95fa71999fc24df84131238a6a 100644
--- a/src/main/java/net/minecraft/server/EnchantmentManager.java
+++ b/src/main/java/net/minecraft/server/EnchantmentManager.java
@@ -251,7 +251,30 @@ public class EnchantmentManager {
         return getEnchantmentLevel(Enchantments.CHANNELING, itemstack) > 0;
     }
 
-    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; } // Paper - OBFHELPER
+    // Purpur start
+    @Nullable
+    public static Entry<EnumItemSlot, ItemStack> getMostDamagedEquipment(Enchantment enchantment, EntityLiving entityliving) {
+        Map<EnumItemSlot, ItemStack> map = enchantment.a(entityliving);
+        if (map.isEmpty()) {
+            return null;
+        }
+        Entry<EnumItemSlot, ItemStack> item = null;
+        float maxPercent = 0F;
+        for (Entry<EnumItemSlot, ItemStack> entry : map.entrySet()) {
+            ItemStack itemstack = entry.getValue();
+            if (!itemstack.isEmpty() && itemstack.isDamaged() && getEnchantmentLevel(enchantment, itemstack) > 0) {
+                float percent = itemstack.getDamagePercent();
+                if (item == null || percent > maxPercent) {
+                    item = entry;
+                    maxPercent = percent;
+                }
+            }
+        }
+        return item;
+    }
+    // Purpur end
+
+    public static @javax.annotation.Nonnull ItemStack getRandomEquippedItemWithEnchant(Enchantment enchantment, EntityLiving entityliving) { Entry<EnumItemSlot, ItemStack> entry = enchantment == Enchantments.MENDING && entityliving.world.purpurConfig.useBetterMending ? getMostDamagedEquipment(enchantment, entityliving) : b(enchantment, entityliving); return entry != null ? entry.getValue() : ItemStack.NULL_ITEM; } // Paper - OBFHELPER
     @Nullable public static Entry<EnumItemSlot, ItemStack> b(Enchantment enchantment, EntityLiving entityliving) {
         return a(enchantment, entityliving, (itemstack) -> {
             return true;
diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
index 4a94ce72d559263ef5fa4fb16dc286f531f51d55..4aee11c980105a523bdcb35470053aae51b002df 100644
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java
+++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
@@ -221,7 +221,7 @@ public class EntityExperienceOrb extends Entity {
             if (this.d == 0 && entityhuman.bu == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper
                 entityhuman.bu = 2;
                 entityhuman.receive(this, 1);
-                Entry<EnumItemSlot, ItemStack> entry = EnchantmentManager.a(Enchantments.MENDING, (EntityLiving) entityhuman, ItemStack::f);
+                Entry<EnumItemSlot, ItemStack> entry = world.purpurConfig.useBetterMending ? EnchantmentManager.getMostDamagedEquipment(Enchantments.MENDING, entityhuman) : EnchantmentManager.a(Enchantments.MENDING, entityhuman, ItemStack::isDamaged); // Purpur
 
                 if (entry != null) {
                     ItemStack itemstack = (ItemStack) entry.getValue();
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
index 7f3df9ba37076c0a982803148d21b0985f62f12c..e747ee83f1a69a4a4bad87e720abc9b085fb6149 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -413,10 +413,19 @@ public final class ItemStack {
         }
     }
 
+    public boolean isDamaged() { return f(); } // Purpur - OBFHELPER
     public boolean f() {
         return this.e() && this.getDamage() > 0;
     }
 
+    public float getDamagePercent() {
+        if (isDamaged()) {
+            return (float) getDamage() / (float) getItem().getMaxDurability();
+        } else {
+            return 0F;
+        }
+    }
+
     public int getDamage() {
         return this.tag == null ? 0 : this.tag.getInt("Damage");
     }
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 5eae6c99e35d53f5340bc81034823a2f1ed85544..66e74ee74b56e25ca46704ca6cec403f15126c33 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -112,6 +112,7 @@ public class PurpurWorldConfig {
         idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList);
     }
 
+    public boolean useBetterMending = false;
     public boolean boatEjectPlayersOnLand = false;
     public boolean disableDropsOnCrammingDeath = false;
     public boolean entitiesPickUpLootBypassMobGriefing = false;
@@ -119,6 +120,7 @@ public class PurpurWorldConfig {
     public double tridentLoyaltyVoidReturnHeight = 0.0D;
     public double voidDamageHeight = -64.0D;
     private void miscGameplayMechanicsSettings() {
+        useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
         boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
         disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
         entitiesPickUpLootBypassMobGriefing = getBoolean("gameplay-mechanics.entities-pick-up-loot-bypass-mob-griefing", entitiesPickUpLootBypassMobGriefing);
