Mending mends most damages equipment first

This commit is contained in:
William Blake Galbreath
2025-01-05 19:16:43 -08:00
committed by granny
parent 1f36eb12ed
commit 3e4de1e628
5 changed files with 87 additions and 130 deletions

View File

@@ -1,129 +0,0 @@
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/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java
index 23b47d90fd35659d9eaa661e808a7f89b29614cf..f1eb74a43881400f23f3750c909f999b35c2f5ce 100644
--- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -353,7 +353,7 @@ public class ExperienceOrb extends Entity {
}
private int repairPlayerItems(ServerPlayer player, int amount) {
- Optional<EnchantedItemInUse> optional = EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged);
+ Optional<EnchantedItemInUse> optional = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged); // Purpur - Add option to mend the most damaged equipment first
if (optional.isPresent()) {
ItemStack itemstack = ((EnchantedItemInUse) optional.get()).itemStack();
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index 731d2bf4a5861bfe10496162d367e003f40b2d50..122859ba52e9719f98111a9c543dab27abac39b5 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -686,6 +686,26 @@ public final class ItemStack implements DataComponentHolder {
return this.isDamageableItem() && this.getDamageValue() > 0;
}
+ // Purpur start - Add option to mend the most damaged equipment first
+ public float getDamagePercent() {
+ if (this.has(DataComponents.UNBREAKABLE)) {
+ return 0.0F;
+ }
+
+ final int maxDamage = this.getOrDefault(DataComponents.MAX_DAMAGE, 0);
+ if (maxDamage == 0) {
+ return 0.0F;
+ }
+
+ final int damage = this.getOrDefault(DataComponents.DAMAGE, 0);
+ if (damage == 0) {
+ return 0.0F;
+ }
+
+ return (float) damage / maxDamage;
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
+
public int getDamageValue() {
return Mth.clamp((Integer) this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage());
}
diff --git a/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
index 64c315372277300e58ce413210f47eed5b6e1d6c..2c1799e8c9009a6ab24c24e7363d5a87e41f0c35 100644
--- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java
+++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
@@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap.Entry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -588,4 +589,48 @@ public class EnchantmentHelper {
return getItemEnchantmentLevel(getEnchantmentHolder(enchantment), stack);
}
// Purpur end - Enchantment convenience methods
+
+ // Purpur start - Add option to mend the most damaged equipment first
+ public static Optional<EnchantedItemInUse> getMostDamagedItemWith(DataComponentType<?> componentType, LivingEntity entity) {
+ ItemStack maxStack = null;
+ EquipmentSlot maxSlot = null;
+ float maxPercent = 0.0F;
+
+ equipmentSlotLoop:
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
+ ItemStack stack = entity.getItemBySlot(equipmentSlot);
+
+ // do not even check enchantments for item with lower or equal damage percent
+ float percent = stack.getDamagePercent();
+ if (percent <= maxPercent) {
+ continue;
+ }
+
+ ItemEnchantments itemEnchantments = stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
+
+ for (Entry<Holder<Enchantment>> entry : itemEnchantments.entrySet()) {
+ Enchantment enchantment = entry.getKey().value();
+
+ net.minecraft.core.component.DataComponentMap effects = enchantment.effects();
+ if (!effects.has(componentType)) {
+ // try with another enchantment
+ continue;
+ }
+
+ if (enchantment.matchingSlot(equipmentSlot)) {
+ maxStack = stack;
+ maxSlot = equipmentSlot;
+ maxPercent = percent;
+
+ // check another slot now
+ continue equipmentSlotLoop;
+ }
+ }
+ }
+
+ return maxStack != null
+ ? Optional.of(new EnchantedItemInUse(maxStack, maxSlot, entity))
+ : Optional.empty();
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 3e78e57f29e98db2dde7d650b65ee23f99238ff7..6b7a6a7889353f9557c6e3bfa8ff8caf66416c1b 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -96,11 +96,13 @@ public class PurpurWorldConfig {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
}
+ public boolean useBetterMending = false;
public boolean boatEjectPlayersOnLand = false;
public boolean disableDropsOnCrammingDeath = false;
public boolean milkCuresBadOmen = true;
public double tridentLoyaltyVoidReturnHeight = 0.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);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -339,7 +_,7 @@
}
private int repairPlayerItems(ServerPlayer player, int value) {
- Optional<EnchantedItemInUse> randomItemWith = EnchantmentHelper.getRandomItemWith(
+ Optional<EnchantedItemInUse> randomItemWith = level().purpurConfig.useBetterMending ? EnchantmentHelper.getMostDamagedItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, player) : EnchantmentHelper.getRandomItemWith( // Purpur - Add option to mend the most damaged equipment first
EnchantmentEffectComponents.REPAIR_WITH_XP, player, ItemStack::isDamaged
);
if (randomItemWith.isPresent()) {

View File

@@ -0,0 +1,29 @@
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -627,6 +_,26 @@
return this.isDamageableItem() && this.getDamageValue() > 0;
}
+ // Purpur start - Add option to mend the most damaged equipment first
+ public float getDamagePercent() {
+ if (this.has(DataComponents.UNBREAKABLE)) {
+ return 0.0F;
+ }
+
+ final int maxDamage = this.getOrDefault(DataComponents.MAX_DAMAGE, 0);
+ if (maxDamage == 0) {
+ return 0.0F;
+ }
+
+ final int damage = this.getOrDefault(DataComponents.DAMAGE, 0);
+ if (damage == 0) {
+ return 0.0F;
+ }
+
+ return (float) damage / maxDamage;
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
+
public int getDamageValue() {
return Mth.clamp(this.getOrDefault(DataComponents.DAMAGE, Integer.valueOf(0)), 0, this.getMaxDamage());
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java --- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java
+++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java +++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
@@ -602,4 +_,14 @@ @@ -602,4 +_,58 @@
interface EnchantmentVisitor { interface EnchantmentVisitor {
void accept(Holder<Enchantment> enchantment, int level); void accept(Holder<Enchantment> enchantment, int level);
} }
@@ -14,4 +14,48 @@
+ return getItemEnchantmentLevel(getEnchantmentHolder(enchantment), stack); + return getItemEnchantmentLevel(getEnchantmentHolder(enchantment), stack);
+ } + }
+ // Purpur end - Enchantment convenience methods + // Purpur end - Enchantment convenience methods
+
+ // Purpur start - Add option to mend the most damaged equipment first
+ public static Optional<EnchantedItemInUse> getMostDamagedItemWith(DataComponentType<?> componentType, LivingEntity entity) {
+ ItemStack maxStack = null;
+ EquipmentSlot maxSlot = null;
+ float maxPercent = 0.0F;
+
+ equipmentSlotLoop:
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
+ ItemStack stack = entity.getItemBySlot(equipmentSlot);
+
+ // do not even check enchantments for item with lower or equal damage percent
+ float percent = stack.getDamagePercent();
+ if (percent <= maxPercent) {
+ continue;
+ }
+
+ ItemEnchantments itemEnchantments = stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
+
+ for (Entry<Holder<Enchantment>> entry : itemEnchantments.entrySet()) {
+ Enchantment enchantment = entry.getKey().value();
+
+ net.minecraft.core.component.DataComponentMap effects = enchantment.effects();
+ if (!effects.has(componentType)) {
+ // try with another enchantment
+ continue;
+ }
+
+ if (enchantment.matchingSlot(equipmentSlot)) {
+ maxStack = stack;
+ maxSlot = equipmentSlot;
+ maxPercent = percent;
+
+ // check another slot now
+ continue equipmentSlotLoop;
+ }
+ }
+ }
+
+ return maxStack != null
+ ? Optional.of(new EnchantedItemInUse(maxStack, maxSlot, entity))
+ : Optional.empty();
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
} }

View File

@@ -84,11 +84,13 @@ public class PurpurWorldConfig {
armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight); armorstandStepHeight = (float) getDouble("gameplay-mechanics.armorstand.step-height", armorstandStepHeight);
} }
public boolean useBetterMending = false;
public boolean boatEjectPlayersOnLand = false; public boolean boatEjectPlayersOnLand = false;
public boolean disableDropsOnCrammingDeath = false; public boolean disableDropsOnCrammingDeath = false;
public boolean milkCuresBadOmen = true; public boolean milkCuresBadOmen = true;
public double tridentLoyaltyVoidReturnHeight = 0.0D; public double tridentLoyaltyVoidReturnHeight = 0.0D;
private void miscGameplayMechanicsSettings() { private void miscGameplayMechanicsSettings() {
useBetterMending = getBoolean("gameplay-mechanics.use-better-mending", useBetterMending);
boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand); boatEjectPlayersOnLand = getBoolean("gameplay-mechanics.boat.eject-players-on-land", boatEjectPlayersOnLand);
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath); disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen);