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;
+ }
}