diff --git a/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/src/main/java/net/Indyuce/mmoitems/MMOItems.java index ee41ac27..5f621727 100644 --- a/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -95,7 +95,7 @@ public class MMOItems extends LuminePlugin { private VaultSupport vaultSupport; private RPGHandler rpgPlugin; - private static final int MYTHICLIB_COMPATIBILITY_INDEX = 7; + private static final int MYTHICLIB_COMPATIBILITY_INDEX = 8; public MMOItems() { plugin = this; } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java index b04b1752..56ed45f0 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/util/DurabilityItem.java @@ -13,7 +13,6 @@ import net.Indyuce.mmoitems.api.event.item.CustomDurabilityRepair; import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem; import net.Indyuce.mmoitems.api.item.util.LoreUpdate; import net.Indyuce.mmoitems.api.player.PlayerData; -import net.Indyuce.mmoitems.stat.data.DoubleData; import net.Indyuce.mmoitems.stat.data.UpgradeData; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -23,8 +22,8 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.util.Objects; import java.util.Random; /** @@ -38,213 +37,188 @@ import java.util.Random; * @author indyuce */ public class DurabilityItem { - private final NBTItem nbtItem; - @Nullable - private final Player player; - private final int maxDurability, unbreakingLevel, initialDurability; - private final boolean barHidden; + private final NBTItem nbtItem; + private final int maxDurability, unbreakingLevel, initialDurability; + private final boolean barHidden; + private final Player player; - private int durability; + private int durability; - private static final Random RANDOM = new Random(); + private static final Random RANDOM = new Random(); - /** - * Use to handle durability changes for MMOItems - * without using heavy MMOItem class methods. - * - * @param player Player holding the item - * @param item Item with durability - */ - public DurabilityItem(@Nullable Player player, @NotNull ItemStack item) { - this(player, NBTItem.get(item)); - } + /** + * Use to handle durability changes for MMOItems + * without using heavy MMOItem class methods. + * + * @param player Player holding the item + * @param item Item with durability + */ + public DurabilityItem(@NotNull Player player, @NotNull ItemStack item) { + this(player, NBTItem.get(item)); + } - /** - * Use to handle durability changes for MMOItems - * without using heavy MMOItem class methods - * - * @param player Player holding the item - * @param item Item with durability - */ - public DurabilityItem(@Nullable Player player, @NotNull NBTItem item) { - /*Validate.notNull(this.player = player, "Player cannot be null");*/ - this.player = player; - Validate.notNull(nbtItem = item, "Item cannot be null"); + /** + * Use to handle durability changes for MMOItems + * without using heavy MMOItem class methods + * + * @param player Player holding the item + * @param nbtItem Item with durability + */ + public DurabilityItem(@NotNull Player player, @NotNull NBTItem nbtItem) { + this.player = Objects.requireNonNull(player, "Player cannot be null"); + this.nbtItem = Objects.requireNonNull(nbtItem, "Item cannot be null"); - maxDurability = nbtItem.getInteger("MMOITEMS_MAX_DURABILITY"); - initialDurability = durability = nbtItem.hasTag("MMOITEMS_DURABILITY") ? nbtItem.getInteger("MMOITEMS_DURABILITY") : maxDurability; - barHidden = nbtItem.getBoolean("MMOITEMS_DURABILITY_BAR"); + maxDurability = nbtItem.getInteger("MMOITEMS_MAX_DURABILITY"); + initialDurability = durability = nbtItem.hasTag("MMOITEMS_DURABILITY") ? nbtItem.getInteger("MMOITEMS_DURABILITY") : maxDurability; + barHidden = nbtItem.getBoolean("MMOITEMS_DURABILITY_BAR"); - unbreakingLevel = (nbtItem.getItem().getItemMeta() != null && nbtItem.getItem().getItemMeta().hasEnchant(Enchantment.DURABILITY)) ? - nbtItem.getItem().getItemMeta().getEnchantLevel(Enchantment.DURABILITY) : - 0; - } + unbreakingLevel = (nbtItem.getItem().getItemMeta() != null && nbtItem.getItem().getItemMeta().hasEnchant(Enchantment.DURABILITY)) ? + nbtItem.getItem().getItemMeta().getEnchantLevel(Enchantment.DURABILITY) : 0; + } - @Nullable public Player getPlayer() { - return player; - } + public Player getPlayer() { + return player; + } - public int getMaxDurability() { - return maxDurability; - } + public int getMaxDurability() { + return maxDurability; + } - public int getDurability() { - return durability; - } + public int getDurability() { + return durability; + } - // If the green vanilla durability bar should show - public boolean isBarHidden() { - return barHidden; - } + public boolean isBarHidden() { + return barHidden; + } - /** - * @deprecated Not used anymore - */ - @Deprecated - public boolean isUnbreakable() { - return nbtItem.getBoolean("Unbreakable"); - } + public int getUnbreakingLevel() { + return unbreakingLevel; + } - public int getUnbreakingLevel() { - return unbreakingLevel; - } + public NBTItem getNBTItem() { + return nbtItem; + } - public NBTItem getNBTItem() { - return nbtItem; - } + public boolean isBroken() { + return durability <= 0; + } - public boolean isBroken() { - return nbtItem.hasTag("MMOITEMS_DURABILITY") && durability <= 0; - } + public boolean isLostWhenBroken() { + return nbtItem.getBoolean("MMOITEMS_WILL_BREAK"); + } - public boolean isLostWhenBroken() { - return nbtItem.getBoolean("MMOITEMS_WILL_BREAK"); - } - public boolean isDowngradedWhenBroken() { - return nbtItem.getBoolean("MMOITEMS_BREAK_DOWNGRADE"); - } + public boolean isDowngradedWhenBroken() { + return nbtItem.getBoolean("MMOITEMS_BREAK_DOWNGRADE"); + } - /** - * Assuming you already called {@link #isDowngradedWhenBroken()}, when the item is - * being broken. This method will downgrade the item for one level and apply changes to - * the stored {@link #getNBTItem()}. - * - * If the item cannot be downgraded (due to not having upgrade data / reaching minimum - * upgrades), this method will return null, no change will be made to the - * NBTItem, and you should break the item. - * - * @return If the item could not be downgraded, and thus should break, will be null. - * If the item was successfully downgraded, this will uuuh, will return the NBTItem of - * the downgraded version. - */ - @Nullable public ItemStack shouldBreakWhenDowngraded() { - ItemTag uTag = ItemTag.getTagAtPath(ItemStats.UPGRADE.getNBTPath(), getNBTItem(), SupportedNBTTagValues.STRING); - if (uTag == null) { return null; } + /** + * @return If the item actually supports custom durability. It is completely + * disabled when the player is in creative mode just like vanilla durability. + */ + public boolean isValid() { + return maxDurability > 0 && player.getGameMode() != GameMode.CREATIVE; + } - try { + public DurabilityItem addDurability(int gain) { + Validate.isTrue(gain > 0, "Durability gain must be greater than 0"); - // Read data - UpgradeData data = new UpgradeData(new JsonParser().parse((String) uTag.getValue()).getAsJsonObject()); + CustomDurabilityRepair event = new CustomDurabilityRepair(this, gain); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) + return this; - // If it cannot be downgraded (reached min), DEATH - if (data.getLevel() <= data.getMin()) { return null; } + durability = Math.min(durability + gain, maxDurability); + return this; + } - // Downgrading operation - LiveMMOItem mmo = new LiveMMOItem(getNBTItem()); + public DurabilityItem decreaseDurability(int loss) { + Validate.isTrue(loss > 0, "Loss must be greater than 0"); - // Remove one level - mmo.getUpgradeTemplate().upgradeTo(mmo, data.getLevel() - 1); + /* + * Calculate the chance of the item not losing any durability because of + * the vanilla unbreaking enchantment ; an item with unbreaking X has 1 + * 1 chance out of (X + 1) to lose a durability point, that's 50% chance + * -> 33% chance -> 25% chance -> 20% chance... + */ + if (getUnbreakingLevel() > 0 && RANDOM.nextInt(getUnbreakingLevel()) != 0) + return this; - // Build NBT - NBTItem preRet = mmo.newBuilder().buildNBT(); + CustomDurabilityDamage event = new CustomDurabilityDamage(this, loss); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) + return this; - // Set durability to zero (full repair) - DurabilityItem dur = new DurabilityItem(getPlayer(), preRet); - dur.addDurability(dur.getMaxDurability()); + durability = Math.max(0, Math.min(durability - loss, maxDurability)); - // Yes - return dur.toItem(); + // Play sound when item breaks + if (isBroken()) { + player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1); + PlayerData.get(player).getInventory().scheduleUpdate(); + } - } catch (JsonSyntaxException |IllegalStateException exception) { return null; } - } + return this; + } - /** - * Since - * - * @return If the item actually supports custom durability. - */ - public boolean isValid() { - return maxDurability > 0 && player != null && player.getGameMode() != GameMode.CREATIVE; - } + /** + * This method not only generates the newest item version taking into account + * 1) item damage + * 2) item breaking + * 3) item downgrade + * + * @return Newest version of the damaged item + */ + public ItemStack toItem() { - public DurabilityItem addDurability(int gain) { - Validate.isTrue(gain > 0, "Durability gain must be greater than 0"); + // No modification needs to be done + if (durability == initialDurability) + return nbtItem.getItem(); - CustomDurabilityRepair event = new CustomDurabilityRepair(this, gain); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) - return this; + // Checks for possible downgrade + ItemTag uTag = ItemTag.getTagAtPath(ItemStats.UPGRADE.getNBTPath(), getNBTItem(), SupportedNBTTagValues.STRING); + if (uTag != null) + try { + UpgradeData data = new UpgradeData(new JsonParser().parse((String) uTag.getValue()).getAsJsonObject()); - durability = Math.min(durability + gain, maxDurability); - return this; - } + // If it cannot be downgraded (reached min), DEATH + if (data.getLevel() <= data.getMin()) + return null; - public DurabilityItem decreaseDurability(int loss) { - CustomDurabilityDamage event = new CustomDurabilityDamage(this, loss); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) - return this; + // Remove one level and FULLY repair item + LiveMMOItem mmo = new LiveMMOItem(getNBTItem()); + mmo.getUpgradeTemplate().upgradeTo(mmo, data.getLevel() - 1); + NBTItem preRet = mmo.newBuilder().buildNBT(); + preRet.addTag(new ItemTag("MMOITEMS_DURABILITY", maxDurability)); + return preRet.toItem(); - /* - * Calculate the chance of the item not losing any durability because of - * the vanilla unbreaking enchantment ; an item with unbreaking X has 1 - * 1 chance out of (X + 1) to lose a durability point, that's 50% chance - * -> 33% chance -> 25% chance -> 20% chance... - */ - if (getUnbreakingLevel() > 0 && RANDOM.nextInt(getUnbreakingLevel()) > 0) - return this; + } catch (JsonSyntaxException | IllegalStateException ignored) { + // Nothing + } - durability = Math.max(0, Math.min(durability - loss, maxDurability)); + /* + * Cross multiplication to display the current item durability on the + * item durability bar. (1 - ratio) because minecraft works with item + * damage, and item damage is the complementary of the remaining + * durability. + * + * Make sure the vanilla bar displays at least 1 damage for display + * issues. Also makes sure the item can be mended using the vanilla + * enchant. + */ + if (!barHidden) { + int damage = (durability == maxDurability) ? 0 : Math.max(1, (int) ((1. - ((double) durability / maxDurability)) * nbtItem.getItem().getType().getMaxDurability())); + nbtItem.addTag(new ItemTag("Damage", damage)); + } - // When the item breaks - if (durability <= 0 && player != null) { - player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 1); - PlayerData.get(player).getInventory().scheduleUpdate(); - } + nbtItem.addTag(new ItemTag("MMOITEMS_DURABILITY", durability)); - return this; - } + // Apply the NBT tags + ItemStack item = nbtItem.toItem(); - public ItemStack toItem() { - - // No modification needs to be done - if (durability == initialDurability) - return nbtItem.getItem(); - - /* - * Cross multiplication to display the current item durability on the - * item durability bar. (1 - ratio) because minecraft works with item - * damage, and item damage is the complementary of the remaining - * durability. - * - * Make sure the vanilla bar displays at least 1 damage for display - * issues. Also makes sure the item can be mended using the vanilla - * enchant. - */ - if (!barHidden) { - int damage = (durability == maxDurability) ? 0 - : Math.max(1, (int) ((1. - ((double) durability / maxDurability)) * nbtItem.getItem().getType().getMaxDurability())); - nbtItem.addTag(new ItemTag("Damage", damage)); } - - nbtItem.addTag(new ItemTag("MMOITEMS_DURABILITY", durability)); - - // Apply the NBT tags - ItemStack item = nbtItem.toItem(); - - // Item lore update - String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("durability").replace("#m", String.valueOf(maxDurability))); - String old = format.replace("#c", String.valueOf(initialDurability)); - String replaced = format.replace("#c", String.valueOf(durability)); - return new LoreUpdate(item, old, replaced).updateLore(); - } + // Item lore update + String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("durability").replace("#m", String.valueOf(maxDurability))); + String old = format.replace("#c", String.valueOf(initialDurability)); + String replaced = format.replace("#c", String.valueOf(durability)); + return new LoreUpdate(item, old, replaced).updateLore(); + } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/util/UntargetedDurabilityItem.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/util/UntargetedDurabilityItem.java index 0f512a4b..a6a26a8e 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/util/UntargetedDurabilityItem.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/util/UntargetedDurabilityItem.java @@ -1,72 +1,38 @@ package net.Indyuce.mmoitems.api.interaction.util; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; -import io.lumine.mythic.lib.api.item.ItemTag; -import io.lumine.mythic.lib.api.item.SupportedNBTTagValues; +import io.lumine.mythic.lib.api.item.NBTItem; import io.lumine.mythic.lib.api.player.EquipmentSlot; -import net.Indyuce.mmoitems.ItemStats; -import net.Indyuce.mmoitems.stat.data.UpgradeData; import org.bukkit.entity.Player; -import io.lumine.mythic.lib.api.item.NBTItem; -import org.bukkit.inventory.ItemStack; - public class UntargetedDurabilityItem extends DurabilityItem { - private final EquipmentSlot slot; + private final EquipmentSlot slot; - /* - * Allows to handle custom durability for target weapons when they are - * left/right click while using the same durability system for both weapon - * types - */ - public UntargetedDurabilityItem(Player player, NBTItem item, EquipmentSlot slot) { - super(player, item); + /** + * Allows to handle custom durability for target weapons when + * they are left/right clicked while using the same durability + * system for both weapon types + */ + public UntargetedDurabilityItem(Player player, NBTItem item, EquipmentSlot slot) { + super(player, item); - this.slot = slot; - } + this.slot = slot; + } - @Override - public UntargetedDurabilityItem decreaseDurability(int loss) { - return (UntargetedDurabilityItem) super.decreaseDurability(loss); - } + @Override + public UntargetedDurabilityItem decreaseDurability(int loss) { + return (UntargetedDurabilityItem) super.decreaseDurability(loss); + } - public void update() { + public void inventoryUpdate() { - // Cannot update null player - if (getPlayer() == null) { return; } + if (isBroken() && isLostWhenBroken()) { + if (slot == EquipmentSlot.OFF_HAND) + getPlayer().getInventory().setItemInOffHand(null); + else + getPlayer().getInventory().setItemInMainHand(null); + return; + } - // If it broke (funny) - if (isBroken()) { - - // Attempt to counter by downgrading - if (isDowngradedWhenBroken()) { - - ItemStack counterUpgraded = shouldBreakWhenDowngraded(); - if (counterUpgraded != null) { - - // Edit item - getNBTItem().getItem().setItemMeta(counterUpgraded.getItemMeta()); - - // No more - return; - } - } - - // Still here? Remove if lost when broken - if (isLostWhenBroken()) { - - // Delete item - if (slot == EquipmentSlot.OFF_HAND) { - getPlayer().getInventory().setItemInOffHand(null); - - } else { getPlayer().getInventory().setItemInMainHand(null); } - - // No more - return; - } - } - - getNBTItem().getItem().setItemMeta(toItem().getItemMeta()); - } + getNBTItem().getItem().setItemMeta(toItem().getItemMeta()); + } } diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java index a1cae78b..dbb94ca2 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Crossbow.java @@ -26,17 +26,17 @@ public class Crossbow extends UntargetedWeapon { if (getPlayer().getGameMode() != GameMode.CREATIVE && !getPlayer().getInventory().containsAtLeast(new ItemStack(Material.ARROW), 1)) return; + UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); + if (durItem.isBroken()) + return; + PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; - UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); - if (durItem.isBroken()) - return; - if (durItem.isValid()) - durItem.decreaseDurability(1).update(); + durItem.decreaseDurability(1).inventoryUpdate(); // consume arrow // has to be after the CD check diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java index 98dc9c10..ca063502 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Lute.java @@ -35,17 +35,18 @@ public class Lute extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { - PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); - double attackSpeed = 1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); - if (!applyWeaponCosts(attackSpeed, CooldownType.ATTACK)) - return; UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); if (durItem.isBroken()) return; + PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); + double attackSpeed = 1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")); + if (!applyWeaponCosts(attackSpeed, CooldownType.ATTACK)) + return; + if (durItem.isValid()) - durItem.decreaseDurability(1).update(); + durItem.decreaseDurability(1).inventoryUpdate(); double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 7); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java index 84a58f05..45fb5996 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Musket.java @@ -28,18 +28,18 @@ public class Musket extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { - PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); - - if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), - CooldownType.ATTACK)) - return; UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); if (durItem.isBroken()) return; + PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); + if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), + CooldownType.ATTACK)) + return; + if (durItem.isValid()) - durItem.decreaseDurability(1).update(); + durItem.decreaseDurability(1).inventoryUpdate(); double attackDamage = stats.getStat("ATTACK_DAMAGE"); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java index 5916b8be..53e17991 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Staff.java @@ -32,17 +32,17 @@ public class Staff extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { + UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); + if (durItem.isBroken()) + return; + PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; - UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); - if (durItem.isBroken()) - return; - if (durItem.isValid()) - durItem.decreaseDurability(1).update(); + durItem.decreaseDurability(1).inventoryUpdate(); double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 1); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); diff --git a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java index 7980a1f6..99871db8 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java +++ b/src/main/java/net/Indyuce/mmoitems/api/interaction/weapon/untargeted/Whip.java @@ -29,17 +29,17 @@ public class Whip extends UntargetedWeapon { @Override public void untargetedAttack(EquipmentSlot slot) { + UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); + if (durItem.isBroken()) + return; + PlayerMetadata stats = getPlayerData().getStats().newTemporary(slot); if (!applyWeaponCosts(1 / getValue(stats.getStat("ATTACK_SPEED"), MMOItems.plugin.getConfig().getDouble("default.attack-speed")), CooldownType.ATTACK)) return; - UntargetedDurabilityItem durItem = new UntargetedDurabilityItem(getPlayer(), getNBTItem(), slot); - if (durItem.isBroken()) - return; - if (durItem.isValid()) - durItem.decreaseDurability(1).update(); + durItem.decreaseDurability(1).inventoryUpdate(); double attackDamage = getValue(stats.getStat("ATTACK_DAMAGE"), 7); double range = getValue(getNBTItem().getStat(ItemStats.RANGE.getId()), MMOItems.plugin.getConfig().getDouble("default.range")); diff --git a/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/ReadMMOItem.java b/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/ReadMMOItem.java index 01ca00fd..8dee73f5 100644 --- a/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/ReadMMOItem.java +++ b/src/main/java/net/Indyuce/mmoitems/api/item/mmoitem/ReadMMOItem.java @@ -1,9 +1,8 @@ package net.Indyuce.mmoitems.api.item.mmoitem; +import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.ItemStats; import net.Indyuce.mmoitems.api.Type; -import io.lumine.mythic.lib.api.item.NBTItem; -import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; @@ -15,7 +14,7 @@ public abstract class ReadMMOItem extends MMOItem { /** * This class is used when reading an MMOItem from an ItemStack (the * opposite of ItemStackBuilder, like an ItemStackReader) - * + * * @param item * The NBTItem being read to generate an MMOItem */ @@ -29,19 +28,11 @@ public abstract class ReadMMOItem extends MMOItem { public int getDamage() { // Does it use custom durability? - if (hasData(ItemStats.MAX_DURABILITY)) { + if (hasData(ItemStats.MAX_DURABILITY)) + return getNBT().hasTag("MMOITEMS_DURABILITY") ? getNBT().getInteger("MMOITEMS_MAX_DURABILITY") - getNBT().getInteger("MMOITEMS_DURABILITY") : 0; - // Use the correct class - DurabilityItem dItem = new DurabilityItem(null, getNBT()); - - int max = dItem.getMaxDurability(); - int current = dItem.getDurability(); - - // Difference - return max - current; - - // Its using vanilla durability-yo - } else { + // Its using vanilla durability-yo + else { // Uh use the item stack I guess ItemStack asStack = getNBT().getItem(); diff --git a/src/main/java/net/Indyuce/mmoitems/listener/DurabilityListener.java b/src/main/java/net/Indyuce/mmoitems/listener/DurabilityListener.java index 4c108857..b1ab9499 100644 --- a/src/main/java/net/Indyuce/mmoitems/listener/DurabilityListener.java +++ b/src/main/java/net/Indyuce/mmoitems/listener/DurabilityListener.java @@ -22,145 +22,115 @@ import java.util.Arrays; import java.util.List; public class DurabilityListener implements Listener { - private final List ignoredCauses = Arrays.asList(DamageCause.DROWNING, DamageCause.SUICIDE, DamageCause.FALL, DamageCause.VOID, - DamageCause.FIRE_TICK, DamageCause.SUFFOCATION, DamageCause.POISON, DamageCause.WITHER, DamageCause.STARVATION, DamageCause.MAGIC); + private final List ignoredCauses = Arrays.asList(DamageCause.DROWNING, DamageCause.SUICIDE, DamageCause.FALL, DamageCause.VOID, + DamageCause.FIRE_TICK, DamageCause.SUFFOCATION, DamageCause.POISON, DamageCause.WITHER, DamageCause.STARVATION, DamageCause.MAGIC); - private final EquipmentSlot[] armorSlots = { EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET }; + private final EquipmentSlot[] armorSlots = {EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET}; - /** - * Handles custom durability for non-'vanilla durability' items - */ - @EventHandler(ignoreCancelled = true) - public void playerDamage(EntityDamageEvent event) { - if (event.getEntityType() != EntityType.PLAYER || ignoredCauses.contains(event.getCause())) - return; + /** + * Handles custom durability for non-'vanilla durability' items + */ + @EventHandler(ignoreCancelled = true) + public void playerDamage(EntityDamageEvent event) { + if (event.getEntityType() != EntityType.PLAYER || ignoredCauses.contains(event.getCause())) + return; - Player player = (Player) event.getEntity(); - int damage = Math.max((int) event.getDamage() / 4, 1); - for (EquipmentSlot slot : armorSlots) - if (hasItem(player, slot)) - handleVanillaDamage(player.getInventory().getItem(slot), player, slot, damage); - } + Player player = (Player) event.getEntity(); + int damage = Math.max((int) event.getDamage() / 4, 1); + for (EquipmentSlot slot : armorSlots) + if (hasItem(player, slot)) + handleVanillaDamage(player.getInventory().getItem(slot), player, slot, damage); + } - @EventHandler(ignoreCancelled = true) - public void playerMeleeAttack(EntityDamageByEntityEvent event) { - if (event.getDamage() == 0 || event.getCause() != DamageCause.ENTITY_ATTACK || !(event.getEntity() instanceof LivingEntity) - || !(event.getDamager() instanceof Player) || event.getEntity().hasMetadata("NPC") || event.getDamager().hasMetadata("NPC")) - return; - Player player = (Player) event.getDamager(); - ItemStack item = player.getInventory().getItemInMainHand(); + @EventHandler(ignoreCancelled = true) + public void playerMeleeAttack(EntityDamageByEntityEvent event) { + if (event.getDamage() == 0 || event.getCause() != DamageCause.ENTITY_ATTACK || !(event.getEntity() instanceof LivingEntity) + || !(event.getDamager() instanceof Player) || event.getEntity().hasMetadata("NPC") || event.getDamager().hasMetadata("NPC")) + return; + Player player = (Player) event.getDamager(); + ItemStack item = player.getInventory().getItemInMainHand(); - handleVanillaDamage(item, player, EquipmentSlot.HAND, 1); - } + handleVanillaDamage(item, player, EquipmentSlot.HAND, 1); + } - @EventHandler(ignoreCancelled = true) - public void playerBowAttack(EntityShootBowEvent event) { - if (!(event.getEntity() instanceof Player)) - return; - Player player = (Player) event.getEntity(); - ItemStack item = event.getBow(); + @EventHandler(ignoreCancelled = true) + public void playerBowAttack(EntityShootBowEvent event) { + if (!(event.getEntity() instanceof Player)) + return; + Player player = (Player) event.getEntity(); + ItemStack item = event.getBow(); - handleVanillaDamage(item, player, EquipmentSlot.HAND, 1); - } + handleVanillaDamage(item, player, EquipmentSlot.HAND, 1); + } - @EventHandler(ignoreCancelled = true) - public void itemDamage(PlayerItemDamageEvent event) { - DurabilityItem item = new DurabilityItem(event.getPlayer(), event.getItem()); + @EventHandler(ignoreCancelled = true) + public void itemDamage(PlayerItemDamageEvent event) { + DurabilityItem item = new DurabilityItem(event.getPlayer(), event.getItem()); + if (item.isValid()) { - if (item.isValid()) { + // Calculate item durability loss + item.decreaseDurability(event.getDamage()); - // Calculate item durability loss - item.decreaseDurability(event.getDamage()); + /* + * If the item is broken and if it is meant to be lost when broken, + * do NOT cancel the event and make sure the item is destroyed + */ + if (item.isBroken()) { - /* - * If the item is broken and if it is meant to be lost when broken, - * do NOT cancel the event and make sure the item is destroyed - */ - if (item.isBroken()) { + // Still here? Remove if lost when broken + if (item.isLostWhenBroken()) { - // Attempt to counter by downgrading - if (item.isDowngradedWhenBroken()) { + // Delete item + event.setDamage(999); - ItemStack counterUpgraded = item.shouldBreakWhenDowngraded(); - if (counterUpgraded != null) { + // Allow event to proceed + return; + } + } - // Counter Event - event.setCancelled(true); - event.getItem().setItemMeta(counterUpgraded.getItemMeta()); + event.setCancelled(true); + event.getItem().setItemMeta(item.toItem().getItemMeta()); + } + } - // No more - return; - } - } - - // Still here? Remove if lost when broken - if (item.isLostWhenBroken()) { - - // Delete item - event.setDamage(999); - - // Allow event to proceed - return; - } - } - - event.setCancelled(true); - event.getItem().setItemMeta(item.toItem().getItemMeta()); - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void mendEvent(PlayerItemMendEvent event) { - DurabilityItem durItem = new DurabilityItem(event.getPlayer(), event.getItem()); - if (durItem.isValid()) { - event.getItem().setItemMeta(durItem.addDurability(event.getRepairAmount()).toItem().getItemMeta()); - event.setCancelled(true); - } - } + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void mendEvent(PlayerItemMendEvent event) { + DurabilityItem durItem = new DurabilityItem(event.getPlayer(), event.getItem()); + if (durItem.isValid()) { + event.getItem().setItemMeta(durItem.addDurability(event.getRepairAmount()).toItem().getItemMeta()); + event.setCancelled(true); + } + } /** * This method is for all the items which have 0 max durability * i.E which are not breakable hence the {@link Material#getMaxDurability()} call */ - private void handleVanillaDamage(ItemStack stack, Player player, EquipmentSlot slot, int damage) { - DurabilityItem item = new DurabilityItem(player, stack); + private void handleVanillaDamage(ItemStack stack, Player player, EquipmentSlot slot, int damage) { + DurabilityItem item = new DurabilityItem(player, stack); - if (item.isValid() && stack.getType().getMaxDurability() == 0) { - item.decreaseDurability(damage); + if (item.isValid() && stack.getType().getMaxDurability() == 0) { + item.decreaseDurability(damage); - if (item.isBroken()) { + if (item.isBroken()) { - // Attempt to counter by downgrading - if (item.isDowngradedWhenBroken()) { + // Still here? Remove if lost when broken + if (item.isLostWhenBroken()) { - ItemStack counterUpgraded = item.shouldBreakWhenDowngraded(); - if (counterUpgraded != null) { + // Delete item + player.getInventory().setItem(slot, null); + player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0f, 1.0f); - // Edit item - player.getInventory().getItem(slot).setItemMeta(counterUpgraded.getItemMeta()); + // No more + return; + } + } - // No more - return; - } - } + player.getInventory().getItem(slot).setItemMeta(item.toItem().getItemMeta()); + } + } - // Still here? Remove if lost when broken - if (item.isLostWhenBroken()) { - - // Delete item - player.getInventory().setItem(slot, null); - player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0f, 1.0f); - - // No more - return; - } - } - - player.getInventory().getItem(slot).setItemMeta(item.toItem().getItemMeta()); - } - } - - private boolean hasItem(Player player, EquipmentSlot slot) { - return player.getInventory().getItem(slot) != null && player.getInventory().getItem(slot).getType() != Material.AIR; - } + private boolean hasItem(Player player, EquipmentSlot slot) { + return player.getInventory().getItem(slot) != null && player.getInventory().getItem(slot).getType() != Material.AIR; + } }