From 1fea5e0411f534a68fa296014eb57f801c1f44d2 Mon Sep 17 00:00:00 2001 From: Mowstyl Date: Fri, 16 Aug 2024 23:37:25 +0200 Subject: [PATCH] Now firing events before changing durability --- .../nossr50/skills/axes/AxesManager.java | 3 +- .../skills/excavation/ExcavationManager.java | 2 +- .../nossr50/skills/mining/MiningManager.java | 2 +- .../nossr50/skills/repair/RepairManager.java | 5 +- .../woodcutting/WoodcuttingManager.java | 13 +--- .../gmail/nossr50/util/skills/SkillUtils.java | 66 +++++++++++++------ 6 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java b/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java index 1ce677e18..c826b4050 100644 --- a/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java +++ b/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java @@ -15,7 +15,6 @@ import com.gmail.nossr50.util.random.ProbabilityUtil; import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.skills.RankUtils; -import com.gmail.nossr50.util.skills.SkillUtils; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.EntityEquipment; @@ -127,7 +126,7 @@ public class AxesManager extends SkillManager { for (ItemStack armor : equipment.getArmorContents()) { if (armor != null && ItemUtils.isArmor(armor)) { if (isSkillRNGSuccessful(SubSkillType.AXES_ARMOR_IMPACT, mmoPlayer, mmoPlayer.getAttackStrength())) { - handleArmorDurabilityChange(armor, durabilityDamage, 1); + handleArmorDurabilityChange(target, armor, durabilityDamage, 1); } } } diff --git a/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java b/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java index 0bb822438..d8286bd3a 100644 --- a/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java +++ b/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java @@ -119,6 +119,6 @@ public class ExcavationManager extends SkillManager { excavationBlockCheck(blockState); excavationBlockCheck(blockState); - SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage()); + SkillUtils.handleDurabilityChange(getPlayer(), getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage()); } } diff --git a/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java b/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java index 937389730..c88975107 100644 --- a/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java +++ b/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java @@ -95,7 +95,7 @@ public class MiningManager extends SkillManager { } if (mmoPlayer.getAbilityMode(mcMMO.p.getSkillTools().getSuperAbility(skill))) { - SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage()); + SkillUtils.handleDurabilityChange(getPlayer(), getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage()); } if (!mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType()) || !canDoubleDrop()) diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java index 0e022ec86..ec26bc067 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java @@ -23,7 +23,10 @@ import com.gmail.nossr50.util.text.StringUtils; import org.bukkit.Material; import org.bukkit.SoundCategory; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ExperienceOrb; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerItemMendEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -197,7 +200,7 @@ public class RepairManager extends SkillManager { } // Repair the item! - item.setDurability(newDurability); + SkillUtils.applyDurabilityChange(player, item, newDurability); } private float getPercentageRepaired(short startDurability, short newDurability, short totalDurability) { diff --git a/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java b/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java index 09ddaa8bc..ff384aeaa 100644 --- a/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java +++ b/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java @@ -18,13 +18,11 @@ import com.gmail.nossr50.util.random.ProbabilityUtil; import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.SkillUtils; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; @@ -250,16 +248,7 @@ public class WoodcuttingManager extends SkillManager { } } - // Call PlayerItemDamageEvent first to make sure it's not cancelled - //TODO: Put this event stuff in handleDurabilityChange - final PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, inHand, durabilityLoss); - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) { - return true; - } - - SkillUtils.handleDurabilityChange(inHand, durabilityLoss); + SkillUtils.handleDurabilityChange(player, inHand, durabilityLoss); int durability = meta instanceof Damageable ? ((Damageable) meta).getDamage(): 0; return (durability < (mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability())); } diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java index a6186d369..9bf3f07a9 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java @@ -20,11 +20,13 @@ import com.gmail.nossr50.util.text.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Recipe; -import org.bukkit.inventory.ShapedRecipe; -import org.bukkit.inventory.ShapelessRecipe; +import org.bukkit.event.player.PlayerItemDamageEvent; +import org.bukkit.event.player.PlayerItemMendEvent; +import org.bukkit.inventory.*; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.jetbrains.annotations.NotNull; @@ -225,8 +227,8 @@ public final class SkillUtils { } } - public static void handleDurabilityChange(ItemStack itemStack, int durabilityModifier) { - handleDurabilityChange(itemStack, durabilityModifier, 1.0); + public static void handleDurabilityChange(LivingEntity holder, ItemStack itemStack, int durabilityModifier) { + handleDurabilityChange(holder, itemStack, durabilityModifier, 1.0, false); } /** @@ -236,16 +238,50 @@ public final class SkillUtils { * @param durabilityModifier the amount to modify the durability by * @param maxDamageModifier the amount to adjust the max damage by */ - public static void handleDurabilityChange(ItemStack itemStack, double durabilityModifier, double maxDamageModifier) { + public static void handleDurabilityChange(LivingEntity holder, ItemStack itemStack, double durabilityModifier, double maxDamageModifier) { + handleDurabilityChange(holder, itemStack, durabilityModifier, maxDamageModifier, false); + } + + public static void applyDurabilityChange(Player player, ItemStack itemStack, int finalDurability) { + int damage = finalDurability - itemStack.getDurability(); + + // Call PlayerItemDamageEvent first to make sure it's not cancelled + if (damage > 0) { // Damaged item + PlayerItemDamageEvent event = new PlayerItemDamageEvent(player, itemStack, finalDurability); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled() && event.getDamage() != 0) { + itemStack.setDurability((short) (itemStack.getDurability() + event.getDamage())); + } + } else if (damage < 0) { // Repaired item + damage = -damage; + ExperienceOrb auxOrb = (ExperienceOrb) player.getWorld().spawnEntity(player.getLocation(), EntityType.EXPERIENCE_ORB); + auxOrb.setExperience(damage / 2); + PlayerItemMendEvent event = new PlayerItemMendEvent(player, itemStack, itemStack.getType().getEquipmentSlot(), auxOrb, damage); + if (!event.isCancelled() && event.getRepairAmount() != 0) { + itemStack.setDurability((short) (itemStack.getDurability() - event.getRepairAmount())); + } + // Cleanup + auxOrb.remove(); + } + } + + private static void handleDurabilityChange(LivingEntity holder, ItemStack itemStack, double durabilityModifier, double maxDamageModifier, boolean isArmor) { if (itemStack.hasItemMeta() && itemStack.getItemMeta().isUnbreakable()) { return; } Material type = itemStack.getType(); short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability(); - durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1), maxDurability * maxDamageModifier); + durabilityModifier = durabilityModifier * ((isArmor ? 0.6 : 0) + ((isArmor ? 0.4 : 1) / (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1))); + durabilityModifier = (int) Math.min(durabilityModifier, maxDurability * maxDamageModifier); - itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability)); + short finalDurability = (short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability); + if (holder instanceof Player player) { + applyDurabilityChange(player, itemStack, finalDurability); + } + else { + itemStack.setDurability(finalDurability); + } } private static boolean isLocalizedSkill(String skillName) { @@ -266,16 +302,8 @@ public final class SkillUtils { * @param durabilityModifier the amount to modify the durability by * @param maxDamageModifier the amount to adjust the max damage by */ - public static void handleArmorDurabilityChange(ItemStack itemStack, double durabilityModifier, double maxDamageModifier) { - if (itemStack.hasItemMeta() && itemStack.getItemMeta().isUnbreakable()) { - return; - } - - Material type = itemStack.getType(); - short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability(); - durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1)), maxDurability * maxDamageModifier); - - itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability)); + public static void handleArmorDurabilityChange(LivingEntity holder, ItemStack itemStack, double durabilityModifier, double maxDamageModifier) { + handleDurabilityChange(holder, itemStack, durabilityModifier, maxDamageModifier, true); } @Nullable