From 2fd01200b0c2ca7122de07e8f33fce8324941c1f Mon Sep 17 00:00:00 2001 From: LotusRPG Date: Fri, 13 Feb 2026 18:06:33 +0100 Subject: [PATCH] Handle durability via Divinity stats while preserving vanilla bar - Vanilla durability bar is shown correctly - Divinity lore durability is used as main source - Mending event handled to sync values --- .../object/ItemDurabilityListener.java | 50 +++++++++++++++++++ .../attributes/stats/DurabilityStat.java | 29 ++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/main/java/studio/magemonkey/divinity/manager/listener/object/ItemDurabilityListener.java b/src/main/java/studio/magemonkey/divinity/manager/listener/object/ItemDurabilityListener.java index 42c3ee8d..40245cb9 100644 --- a/src/main/java/studio/magemonkey/divinity/manager/listener/object/ItemDurabilityListener.java +++ b/src/main/java/studio/magemonkey/divinity/manager/listener/object/ItemDurabilityListener.java @@ -1,5 +1,8 @@ package studio.magemonkey.divinity.manager.listener.object; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.event.player.PlayerItemMendEvent; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.LivingEntity; @@ -113,4 +116,51 @@ public void onDuraHoe(PlayerInteractEvent e) { } } } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onMend(PlayerItemMendEvent e) { + + ItemStack item = e.getItem(); + + if (!ItemStats.hasStat(item, null, TypedStat.Type.DURABILITY)) return; + + double[] durability = duraStat.getRaw(item); + if (durability == null) return; + + if (duraStat.isUnbreakable(item)) return; + + double current = durability[0]; + double max = durability[1]; + + int vanillaMax = item.getType().getMaxDurability(); + if (vanillaMax <= 0) return; + + int repair = e.getRepairAmount(); + + double customRepair = ((double) repair / vanillaMax) * max; + + double newValue = current + customRepair; + + if (newValue > max) { + newValue = max; + } + + newValue = Math.round(newValue * 100.0) / 100.0; + + duraStat.add(item, new double[]{newValue, max}, -1); + duraStat.syncVanillaBar(item, newValue, max); + + e.setCancelled(true); + + Damageable damageable = (Damageable) item.getItemMeta(); + + int vanillaDamage = damageable.getDamage(); + + if (vanillaDamage == 0) { + duraStat.add(item, new double[]{max, max}, -1); + duraStat.syncVanillaBar(item, max, max); + e.setCancelled(true); + return; + } + } } diff --git a/src/main/java/studio/magemonkey/divinity/stats/items/attributes/stats/DurabilityStat.java b/src/main/java/studio/magemonkey/divinity/stats/items/attributes/stats/DurabilityStat.java index 347a1e7c..ba7a33bf 100644 --- a/src/main/java/studio/magemonkey/divinity/stats/items/attributes/stats/DurabilityStat.java +++ b/src/main/java/studio/magemonkey/divinity/stats/items/attributes/stats/DurabilityStat.java @@ -1,5 +1,7 @@ package studio.magemonkey.divinity.stats.items.attributes.stats; + +import org.bukkit.inventory.meta.Damageable; import org.bukkit.NamespacedKey; import org.bukkit.Sound; import org.bukkit.enchantments.Enchantment; @@ -155,7 +157,14 @@ public boolean reduceDurability( } } - return this.add(item, new double[]{lose, max}, -1); + boolean result = this.add(item, new double[]{lose, max}, -1); + + if (result) { + syncVanillaBar(item, lose, max); + } + + return result; + } @Override @@ -163,4 +172,22 @@ public boolean reduceDurability( public String formatValue(@NotNull ItemStack item, double[] values) { return EngineCfg.getDurabilityFormat((int) values[0], (int) values[1]); } + public void syncVanillaBar(@NotNull ItemStack item, double current, double maxCustom) { + + ItemMeta meta = item.getItemMeta(); + if (!(meta instanceof org.bukkit.inventory.meta.Damageable)) return; + + org.bukkit.inventory.meta.Damageable damageable = + (org.bukkit.inventory.meta.Damageable) meta; + + int maxVanilla = item.getType().getMaxDurability(); + if (maxVanilla <= 0) return; + + double percent = current / maxCustom; + int vanillaDamage = (int) ((1.0 - percent) * maxVanilla); + + damageable.setDamage(vanillaDamage); + item.setItemMeta((ItemMeta) damageable); } + +} \ No newline at end of file