From 212c942316db1e9700fe2033ee486c7c0c1e2bac Mon Sep 17 00:00:00 2001 From: granny Date: Thu, 3 Oct 2024 18:35:01 -0700 Subject: [PATCH] delegate itemstack convenience methods --- .../0017-ItemStack-convenience-methods.patch | 155 +++------ .../0297-ItemStack-convenience-methods.patch | 296 ++++++++++++++++++ 2 files changed, 337 insertions(+), 114 deletions(-) create mode 100644 patches/server/0297-ItemStack-convenience-methods.patch diff --git a/patches/api/0017-ItemStack-convenience-methods.patch b/patches/api/0017-ItemStack-convenience-methods.patch index ea8d80441..3e7296342 100644 --- a/patches/api/0017-ItemStack-convenience-methods.patch +++ b/patches/api/0017-ItemStack-convenience-methods.patch @@ -50,10 +50,10 @@ index de469f32dd9a01e0e2fde016044a783dde0c5b98..c7fa497381c5c5d57fda8b9c1ef26f2e + // Purpur end } diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6b589f23c 100644 +index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..4414381ac942c040480d53b03565b160eb85c444 100644 --- a/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -19,6 +19,17 @@ import org.bukkit.inventory.meta.ItemMeta; +@@ -19,6 +19,13 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,15 +63,11 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.bukkit.block.data.BlockData; -+import org.bukkit.inventory.meta.BlockDataMeta; -+import org.bukkit.inventory.meta.Repairable; -+import org.bukkit.persistence.PersistentDataContainer; -+import org.bukkit.persistence.PersistentDataHolder; +// Purpur end /** * Represents a stack of items. -@@ -1137,4 +1148,551 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat +@@ -1137,4 +1144,482 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player); } // Paper end - expose itemstack tooltip lines @@ -87,7 +83,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @NotNull + public String getDisplayName() { -+ return getItemMeta().getDisplayName(); ++ return this.craftDelegate.getDisplayName(); + } + + /** @@ -96,9 +92,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @param name the name to set + */ + public void setDisplayName(@Nullable String name) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setDisplayName(name); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setDisplayName(name); + } + + /** @@ -107,7 +101,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this has a display name + */ + public boolean hasDisplayName() { -+ return hasItemMeta() && getItemMeta().hasDisplayName(); ++ return this.craftDelegate.hasDisplayName(); + } + + /** @@ -120,7 +114,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @NotNull + public String getLocalizedName() { -+ return getItemMeta().getLocalizedName(); ++ return this.craftDelegate.getLocalizedName(); + } + + /** @@ -129,9 +123,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @param name the name to set + */ + public void setLocalizedName(@Nullable String name) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setLocalizedName(name); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setLocalizedName(name); + } + + /** @@ -140,7 +132,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this has a localized name + */ + public boolean hasLocalizedName() { -+ return hasItemMeta() && getItemMeta().hasLocalizedName(); ++ return this.craftDelegate.hasLocalizedName(); + } + + /** @@ -149,7 +141,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this has lore + */ + public boolean hasLore() { -+ return hasItemMeta() && getItemMeta().hasLore(); ++ return this.craftDelegate.hasLore(); + } + + /** @@ -159,7 +151,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this enchantment exists for this meta + */ + public boolean hasEnchant(@NotNull Enchantment ench) { -+ return hasItemMeta() && getItemMeta().hasEnchant(ench); ++ return this.craftDelegate.hasEnchant(ench); + } + + /** @@ -169,7 +161,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return The level that the specified enchantment has, or 0 if none + */ + public int getEnchantLevel(@NotNull Enchantment ench) { -+ return getItemMeta().getEnchantLevel(ench); ++ return this.craftDelegate.getEnchantLevel(ench); + } + + /** @@ -180,7 +172,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @NotNull + public Map getEnchants() { -+ return getItemMeta().getEnchants(); ++ return this.craftDelegate.getEnchants(); + } + + /** @@ -194,10 +186,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * otherwise + */ + public boolean addEnchant(@NotNull Enchantment ench, int level, boolean ignoreLevelRestriction) { -+ ItemMeta itemMeta = getItemMeta(); -+ boolean result = itemMeta.addEnchant(ench, level, ignoreLevelRestriction); -+ setItemMeta(itemMeta); -+ return result; ++ return this.craftDelegate.addEnchant(ench, level, ignoreLevelRestriction); + } + + /** @@ -208,10 +197,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * otherwise + */ + public boolean removeEnchant(@NotNull Enchantment ench) { -+ ItemMeta itemMeta = getItemMeta(); -+ boolean result = itemMeta.removeEnchant(ench); -+ setItemMeta(itemMeta); -+ return result; ++ return this.craftDelegate.removeEnchant(ench); + } + + /** @@ -220,7 +206,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if an enchantment exists on this meta + */ + public boolean hasEnchants() { -+ return hasItemMeta() && getItemMeta().hasEnchants(); ++ return this.craftDelegate.hasEnchants(); + } + + /** @@ -231,7 +217,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if the enchantment conflicts, false otherwise + */ + public boolean hasConflictingEnchant(@NotNull Enchantment ench) { -+ return hasItemMeta() && getItemMeta().hasConflictingEnchant(ench); ++ return this.craftDelegate.hasConflictingEnchant(ench); + } + + /** @@ -243,9 +229,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @param data the data to set, or null to clear + */ + public void setCustomModelData(@Nullable Integer data) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setCustomModelData(data); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setCustomModelData(data); + } + + /** @@ -260,7 +244,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return the localized name that is set + */ + public int getCustomModelData() { -+ return getItemMeta().getCustomModelData(); ++ return this.craftDelegate.getCustomModelData(); + } + + /** @@ -272,7 +256,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this has custom model data + */ + public boolean hasCustomModelData() { -+ return hasItemMeta() && getItemMeta().hasCustomModelData(); ++ return this.craftDelegate.hasCustomModelData(); + } + + /** @@ -281,7 +265,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return whether block data is already attached + */ + public boolean hasBlockData() { -+ return hasItemMeta() && ((BlockDataMeta) getItemMeta()).hasBlockData(); ++ return this.craftDelegate.hasBlockData(); + } + + /** @@ -296,7 +280,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @NotNull + public BlockData getBlockData(@NotNull Material material) { -+ return ((BlockDataMeta) getItemMeta()).getBlockData(material); ++ return this.craftDelegate.getBlockData(material); + } + + /** @@ -307,9 +291,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * this item. + */ + public void setBlockData(@NotNull BlockData blockData) { -+ ItemMeta itemMeta = getItemMeta(); -+ ((BlockDataMeta) itemMeta).setBlockData(blockData); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setBlockData(blockData); + } + + /** @@ -318,7 +300,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return the repair penalty + */ + public int getRepairCost() { -+ return ((Repairable) getItemMeta()).getRepairCost(); ++ return this.craftDelegate.getRepairCost(); + } + + /** @@ -327,9 +309,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @param cost repair penalty + */ + public void setRepairCost(int cost) { -+ ItemMeta itemMeta = getItemMeta(); -+ ((Repairable) itemMeta).setRepairCost(cost); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setRepairCost(cost); + } + + /** @@ -338,7 +318,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this has a repair penalty + */ + public boolean hasRepairCost() { -+ return hasItemMeta() && ((Repairable) getItemMeta()).hasRepairCost(); ++ return this.craftDelegate.hasRepairCost(); + } + + /** @@ -348,7 +328,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if the unbreakable tag is true + */ + public boolean isUnbreakable() { -+ return hasItemMeta() && getItemMeta().isUnbreakable(); ++ return this.craftDelegate.isUnbreakable(); + } + + /** @@ -357,9 +337,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @param unbreakable true if set unbreakable + */ + public void setUnbreakable(boolean unbreakable) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setUnbreakable(unbreakable); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setUnbreakable(unbreakable); + } + + /** @@ -368,7 +346,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if any AttributeModifiers exist + */ + public boolean hasAttributeModifiers() { -+ return hasItemMeta() && getItemMeta().hasAttributeModifiers(); ++ return this.craftDelegate.hasAttributeModifiers(); + } + + /** @@ -381,7 +359,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @Nullable + public Multimap getAttributeModifiers() { -+ return getItemMeta().getAttributeModifiers(); ++ return this.craftDelegate.getAttributeModifiers(); + } + + /** @@ -400,7 +378,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @NotNull + public Multimap getAttributeModifiers(@Nullable EquipmentSlot slot) { -+ return getItemMeta().getAttributeModifiers(slot); ++ return this.craftDelegate.getAttributeModifiers(slot); + } + + /** @@ -414,7 +392,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + */ + @Nullable + public Collection getAttributeModifiers(@NotNull Attribute attribute) { -+ return getItemMeta().getAttributeModifiers(attribute); ++ return this.craftDelegate.getAttributeModifiers(attribute); + } + + /** @@ -434,10 +412,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @throws IllegalArgumentException if AttributeModifier already exists + */ + public boolean addAttributeModifier(@NotNull Attribute attribute, @NotNull AttributeModifier modifier) { -+ ItemMeta itemMeta = getItemMeta(); -+ boolean result = itemMeta.addAttributeModifier(attribute, modifier); -+ setItemMeta(itemMeta); -+ return result; ++ return this.craftDelegate.addAttributeModifier(attribute, modifier); + } + + /** @@ -451,9 +426,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * and their AttributeModifiers + */ + public void setAttributeModifiers(@Nullable Multimap attributeModifiers) { -+ ItemMeta itemMeta = getItemMeta(); -+ itemMeta.setAttributeModifiers(attributeModifiers); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setAttributeModifiers(attributeModifiers); + } + + /** @@ -468,10 +441,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @throws NullPointerException if Attribute is null + */ + public boolean removeAttributeModifier(@NotNull Attribute attribute) { -+ ItemMeta itemMeta = getItemMeta(); -+ boolean result = itemMeta.removeAttributeModifier(attribute); -+ setItemMeta(itemMeta); -+ return result; ++ return this.craftDelegate.removeAttributeModifier(attribute); + } + + /** @@ -486,10 +456,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * EquipmentSlot. + */ + public boolean removeAttributeModifier(@Nullable EquipmentSlot slot) { -+ ItemMeta itemMeta = getItemMeta(); -+ boolean result = itemMeta.removeAttributeModifier(slot); -+ setItemMeta(itemMeta); -+ return result; ++ return this.craftDelegate.removeAttributeModifier(slot); + } + + /** @@ -506,10 +473,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @see AttributeModifier#getUniqueId() + */ + public boolean removeAttributeModifier(@NotNull Attribute attribute, @NotNull AttributeModifier modifier) { -+ ItemMeta itemMeta = getItemMeta(); -+ boolean result = itemMeta.removeAttributeModifier(attribute, modifier); -+ setItemMeta(itemMeta); -+ return result; ++ return this.craftDelegate.removeAttributeModifier(attribute, modifier); + } + + /** @@ -518,7 +482,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return true if this has damage + */ + public boolean hasDamage() { -+ return hasItemMeta() && ((Damageable) getItemMeta()).hasDamage(); ++ return this.craftDelegate.hasDamage(); + } + + /** @@ -527,7 +491,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return the damage + */ + public int getDamage() { -+ return ((Damageable) getItemMeta()).getDamage(); ++ return this.craftDelegate.getDamage(); + } + + /** @@ -536,9 +500,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @param damage item damage + */ + public void setDamage(int damage) { -+ ItemMeta itemMeta = getItemMeta(); -+ ((Damageable) itemMeta).setDamage(damage); -+ setItemMeta(itemMeta); ++ this.craftDelegate.setDamage(damage); + } + + /** @@ -584,42 +546,7 @@ index b59222b8c262545d100a9fd28b3bf1d2a4cf4eb0..44a26a768c11f60241010391211a19f6 + * @return True if damage broke the item + */ + public boolean damage(int amount, boolean ignoreUnbreaking) { -+ Damageable damageable = (Damageable) getItemMeta(); -+ if (amount > 0) { -+ int unbreaking = getEnchantLevel(Enchantment.UNBREAKING); -+ int reduce = 0; -+ for (int i = 0; unbreaking > 0 && i < amount; ++i) { -+ if (reduceDamage(java.util.concurrent.ThreadLocalRandom.current(), unbreaking)) { -+ ++reduce; -+ } -+ } -+ amount -= reduce; -+ if (amount <= 0) { -+ return isBroke(damageable.getDamage()); -+ } -+ } -+ int damage = damageable.getDamage() + amount; -+ damageable.setDamage(damage); -+ setItemMeta((ItemMeta) damageable); -+ return isBroke(damage); -+ } -+ -+ public boolean isBroke(int damage) { -+ if (damage > getType().getMaxDurability()) { -+ if (getAmount() > 0) { -+ // ensure it "breaks" -+ setAmount(0); -+ } -+ return true; -+ } -+ return false; -+ } -+ -+ private boolean reduceDamage(java.util.Random random, int unbreaking) { -+ if (getType().isArmor()) { -+ return random.nextFloat() < 0.6F; -+ } -+ return random.nextInt(unbreaking + 1) > 0; ++ return this.craftDelegate.damage(amount, ignoreUnbreaking); + } + // Purpur end } diff --git a/patches/server/0297-ItemStack-convenience-methods.patch b/patches/server/0297-ItemStack-convenience-methods.patch new file mode 100644 index 000000000..62eca1dd2 --- /dev/null +++ b/patches/server/0297-ItemStack-convenience-methods.patch @@ -0,0 +1,296 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: granny +Date: Thu, 3 Oct 2024 18:33:14 -0700 +Subject: [PATCH] ItemStack convenience methods + + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +index f84e07fa0876bb6da0f99f4de6cb811f897adca2..090c485990f11ad72597bcd7473f7b439f7a6d86 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +@@ -543,4 +543,285 @@ public final class CraftItemStack extends ItemStack { + return this.pdcView; + } + // Paper end - pdc ++ ++ // Purpur start ++ @Override ++ public String getDisplayName() { ++ return getItemMeta().getDisplayName(); ++ } ++ ++ @Override ++ public void setDisplayName(String name) { ++ ItemMeta itemMeta = getItemMeta(); ++ itemMeta.setDisplayName(name); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public boolean hasDisplayName() { ++ return hasItemMeta() && getItemMeta().hasDisplayName(); ++ } ++ ++ @Override ++ public String getLocalizedName() { ++ return getItemMeta().getLocalizedName(); ++ } ++ ++ @Override ++ public void setLocalizedName(String name) { ++ ItemMeta itemMeta = getItemMeta(); ++ itemMeta.setLocalizedName(name); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public boolean hasLocalizedName() { ++ return hasItemMeta() && getItemMeta().hasLocalizedName(); ++ } ++ ++ @Override ++ public boolean hasLore() { ++ return hasItemMeta() && getItemMeta().hasLore(); ++ } ++ ++ @Override ++ public boolean hasEnchant(Enchantment ench) { ++ return hasItemMeta() && getItemMeta().hasEnchant(ench); ++ } ++ ++ @Override ++ public int getEnchantLevel(Enchantment ench) { ++ return getItemMeta().getEnchantLevel(ench); ++ } ++ ++ @Override ++ public Map getEnchants() { ++ return getItemMeta().getEnchants(); ++ } ++ ++ @Override ++ public boolean addEnchant(Enchantment ench, int level, boolean ignoreLevelRestriction) { ++ ItemMeta itemMeta = getItemMeta(); ++ boolean result = itemMeta.addEnchant(ench, level, ignoreLevelRestriction); ++ setItemMeta(itemMeta); ++ return result; ++ } ++ ++ @Override ++ public boolean removeEnchant(Enchantment ench) { ++ ItemMeta itemMeta = getItemMeta(); ++ boolean result = itemMeta.removeEnchant(ench); ++ setItemMeta(itemMeta); ++ return result; ++ } ++ ++ @Override ++ public boolean hasEnchants() { ++ return hasItemMeta() && getItemMeta().hasEnchants(); ++ } ++ ++ @Override ++ public boolean hasConflictingEnchant(Enchantment ench) { ++ return hasItemMeta() && getItemMeta().hasConflictingEnchant(ench); ++ } ++ ++ @Override ++ public void setCustomModelData(Integer data) { ++ ItemMeta itemMeta = getItemMeta(); ++ itemMeta.setCustomModelData(data); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public int getCustomModelData() { ++ return getItemMeta().getCustomModelData(); ++ } ++ ++ @Override ++ public boolean hasCustomModelData() { ++ return hasItemMeta() && getItemMeta().hasCustomModelData(); ++ } ++ ++ @Override ++ public boolean hasBlockData() { ++ return hasItemMeta() && ((org.bukkit.inventory.meta.BlockDataMeta) getItemMeta()).hasBlockData(); ++ } ++ ++ @Override ++ public org.bukkit.block.data.BlockData getBlockData(Material material) { ++ return ((org.bukkit.inventory.meta.BlockDataMeta) getItemMeta()).getBlockData(material); ++ } ++ ++ @Override ++ public void setBlockData(org.bukkit.block.data.BlockData blockData) { ++ ItemMeta itemMeta = getItemMeta(); ++ ((org.bukkit.inventory.meta.BlockDataMeta) itemMeta).setBlockData(blockData); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public int getRepairCost() { ++ return ((org.bukkit.inventory.meta.Repairable) getItemMeta()).getRepairCost(); ++ } ++ ++ @Override ++ public void setRepairCost(int cost) { ++ ItemMeta itemMeta = getItemMeta(); ++ ((org.bukkit.inventory.meta.Repairable) itemMeta).setRepairCost(cost); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public boolean hasRepairCost() { ++ return hasItemMeta() && ((org.bukkit.inventory.meta.Repairable) getItemMeta()).hasRepairCost(); ++ } ++ ++ @Override ++ public boolean isUnbreakable() { ++ return hasItemMeta() && getItemMeta().isUnbreakable(); ++ } ++ ++ @Override ++ public void setUnbreakable(boolean unbreakable) { ++ ItemMeta itemMeta = getItemMeta(); ++ itemMeta.setUnbreakable(unbreakable); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public boolean hasAttributeModifiers() { ++ return hasItemMeta() && getItemMeta().hasAttributeModifiers(); ++ } ++ ++ @Override ++ public com.google.common.collect.Multimap getAttributeModifiers() { ++ return getItemMeta().getAttributeModifiers(); ++ } ++ ++ @Override ++ public com.google.common.collect.Multimap getAttributeModifiers(org.bukkit.inventory.EquipmentSlot slot) { ++ return getItemMeta().getAttributeModifiers(slot); ++ } ++ ++ @Override ++ public java.util.Collection getAttributeModifiers(org.bukkit.attribute.Attribute attribute) { ++ return getItemMeta().getAttributeModifiers(attribute); ++ } ++ ++ @Override ++ public boolean addAttributeModifier(org.bukkit.attribute.Attribute attribute, org.bukkit.attribute.AttributeModifier modifier) { ++ ItemMeta itemMeta = getItemMeta(); ++ boolean result = itemMeta.addAttributeModifier(attribute, modifier); ++ setItemMeta(itemMeta); ++ return result; ++ } ++ ++ @Override ++ public void setAttributeModifiers(com.google.common.collect.Multimap attributeModifiers) { ++ ItemMeta itemMeta = getItemMeta(); ++ itemMeta.setAttributeModifiers(attributeModifiers); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public boolean removeAttributeModifier(org.bukkit.attribute.Attribute attribute) { ++ ItemMeta itemMeta = getItemMeta(); ++ boolean result = itemMeta.removeAttributeModifier(attribute); ++ setItemMeta(itemMeta); ++ return result; ++ } ++ ++ @Override ++ public boolean removeAttributeModifier(org.bukkit.inventory.EquipmentSlot slot) { ++ ItemMeta itemMeta = getItemMeta(); ++ boolean result = itemMeta.removeAttributeModifier(slot); ++ setItemMeta(itemMeta); ++ return result; ++ } ++ ++ @Override ++ public boolean removeAttributeModifier(org.bukkit.attribute.Attribute attribute, org.bukkit.attribute.AttributeModifier modifier) { ++ ItemMeta itemMeta = getItemMeta(); ++ boolean result = itemMeta.removeAttributeModifier(attribute, modifier); ++ setItemMeta(itemMeta); ++ return result; ++ } ++ ++ @Override ++ public boolean hasDamage() { ++ return hasItemMeta() && ((org.bukkit.inventory.meta.Damageable) getItemMeta()).hasDamage(); ++ } ++ ++ @Override ++ public int getDamage() { ++ return ((org.bukkit.inventory.meta.Damageable) getItemMeta()).getDamage(); ++ } ++ ++ @Override ++ public void setDamage(int damage) { ++ ItemMeta itemMeta = getItemMeta(); ++ ((org.bukkit.inventory.meta.Damageable) itemMeta).setDamage(damage); ++ setItemMeta(itemMeta); ++ } ++ ++ @Override ++ public void repair() { ++ repair(1); ++ } ++ ++ @Override ++ public boolean damage() { ++ return damage(1); ++ } ++ ++ @Override ++ public void repair(int amount) { ++ damage(-amount); ++ } ++ ++ @Override ++ public boolean damage(int amount) { ++ return damage(amount, false); ++ } ++ ++ @Override ++ public boolean damage(int amount, boolean ignoreUnbreaking) { ++ org.bukkit.inventory.meta.Damageable damageable = (org.bukkit.inventory.meta.Damageable) getItemMeta(); ++ if (amount > 0) { ++ int unbreaking = getEnchantLevel(Enchantment.UNBREAKING); ++ int reduce = 0; ++ for (int i = 0; unbreaking > 0 && i < amount; ++i) { ++ if (reduceDamage(java.util.concurrent.ThreadLocalRandom.current(), unbreaking)) { ++ ++reduce; ++ } ++ } ++ amount -= reduce; ++ if (amount <= 0) { ++ return isBroke(damageable.getDamage()); ++ } ++ } ++ int damage = damageable.getDamage() + amount; ++ damageable.setDamage(damage); ++ setItemMeta((ItemMeta) damageable); ++ return isBroke(damage); ++ } ++ ++ private boolean isBroke(int damage) { ++ if (damage > getType().getMaxDurability()) { ++ if (getAmount() > 0) { ++ // ensure it "breaks" ++ setAmount(0); ++ } ++ return true; ++ } ++ return false; ++ } ++ ++ private boolean reduceDamage(java.util.Random random, int unbreaking) { ++ if (getType().isArmor()) { ++ return random.nextFloat() < 0.6F; ++ } ++ return random.nextInt(unbreaking + 1) > 0; ++ } ++ // Purpur end + }