mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
Upstream has released updates that appears to apply and compile correctly Paper Changes: c8028d1c Fix data version check for ItemStack serialization (#3394) 9254a80a Fix race condition reintroduced in Prioritize class loader patch 6f196fe7 Add Raw Byte ItemStack Serialization df43f828 Allow server startup for those poor people running <1G Xmx 3c9b65ef Fix cases where no-tick < tick view distance 72f89a07 Workaround for Client Lag Spikes (MC-162253) 3f941c0c Add option for console having all permissions d2ae4658 Add permission for command blocks 9f8ae5cb Prioritise own classes where possible 74466412 Check portal restrictions when entering end gateways fc9cf84d Fix NPE when temp ip bans expire (#3373) 16bd420d Add missing mob goals for API (#3367) b5c4e2f6 Ensure no-tick view is not smaller than ticking VD 52564b1f Expand Pathfinding API with more options dde65481 Fix usage of vanilla goals 7797aebe Drop Leads from nether portals - Fixes #3226 511b6bc2 Reduce MutableInt and Vec3d allocations, use ArrayDeque 84673141 Optimize NibbleArray to use pooled buffers 897dd2c8 Foundational work for Future Memory usage improvements bb4002d8 Handle CraftPlayer#setSpectatorTarget better 4ae08959 Fix collision checks on spawning hanging entities and null on async chunk loads c2f8d1ef Protect Bedrock and End Portal/Frames from being destroyed 827cc632 Updated Upstream (Bukkit/CraftBukkit/Spigot) 92f680ed Fix Pathfinding and obscure glitchy buggy 0 tick farms 7a7c4292 Optimize Pathfinder - Remove Streams / Optimized collections fc917d16 Optimize Hoppers - Major performance improvement 14ad77c6 Fix PotionEffect API Ignoring Icon bug eb3ce8a2 Fix EntityRaider picking up items when they shouldn't be able 1ea9ada0 Add a TELEPORT ticket when changing dimensions 8e9459ea Fix missing flag pass for isUrgent 7befec44 Potential bed api (#3339) 27945a6b Optimize WorldBorder collision checks and air 55e17a85 Wait for Async Tasks during shutdown b5905256 Ensure Entity AABB's are never invalid a054aa6f Properly remove Entities from current chunk c894ddfd Fix teleporting onto a chunk line 57d6cc01 Send LOGIN protocol packets immediately - Fix disconnect during async prelogin cd93e54d Don't use our modified chunk checks for collision in world gen b4003ef1 Allow loading entities current chunk if needed to fix collision checks e5f64896 Add Urgent API for Async Chunks API and use it for Async Teleport ad8e59dc Ensure chunks loaded on respawn for suffocation check
690 lines
22 KiB
Diff
690 lines
22 KiB
Diff
From c7218d4100f7de38fbfc643e4705908adf1c41bd Mon Sep 17 00:00:00 2001
|
|
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
|
Date: Sun, 15 Mar 2020 20:52:12 -0500
|
|
Subject: [PATCH] Add ItemStack convenience methods
|
|
|
|
---
|
|
src/main/java/org/bukkit/Material.java | 32 +
|
|
.../java/org/bukkit/inventory/ItemStack.java | 619 ++++++++++++++++++
|
|
2 files changed, 651 insertions(+)
|
|
|
|
diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java
|
|
index 1f2dbd68c..f2be0d0ce 100644
|
|
--- a/src/main/java/org/bukkit/Material.java
|
|
+++ b/src/main/java/org/bukkit/Material.java
|
|
@@ -7995,4 +7995,36 @@ public enum Material implements Keyed {
|
|
// </editor-fold>
|
|
}
|
|
}
|
|
+
|
|
+ // Purpur start
|
|
+ public boolean isArmor() {
|
|
+ switch (this) {
|
|
+ // <editor-fold defaultstate="collapsed" desc="isarmor">
|
|
+ case LEATHER_BOOTS:
|
|
+ case LEATHER_CHESTPLATE:
|
|
+ case LEATHER_HELMET:
|
|
+ case LEATHER_LEGGINGS:
|
|
+ case CHAINMAIL_BOOTS:
|
|
+ case CHAINMAIL_CHESTPLATE:
|
|
+ case CHAINMAIL_HELMET:
|
|
+ case CHAINMAIL_LEGGINGS:
|
|
+ case IRON_BOOTS:
|
|
+ case IRON_CHESTPLATE:
|
|
+ case IRON_HELMET:
|
|
+ case IRON_LEGGINGS:
|
|
+ case GOLDEN_BOOTS:
|
|
+ case GOLDEN_CHESTPLATE:
|
|
+ case GOLDEN_HELMET:
|
|
+ case GOLDEN_LEGGINGS:
|
|
+ case DIAMOND_BOOTS:
|
|
+ case DIAMOND_CHESTPLATE:
|
|
+ case DIAMOND_HELMET:
|
|
+ case DIAMOND_LEGGINGS:
|
|
+ case TURTLE_HELMET:
|
|
+ return true;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ // Purpur end
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
|
index a8ade268c..cdc62301e 100644
|
|
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
|
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
|
@@ -17,6 +17,18 @@ import org.bukkit.inventory.meta.ItemMeta;
|
|
import org.bukkit.material.MaterialData;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
+// Purpur start
|
|
+import com.google.common.collect.Multimap;
|
|
+import java.util.Collection;
|
|
+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;
|
|
+import com.destroystokyo.paper.Namespaced;
|
|
+// Purpur end
|
|
|
|
/**
|
|
* Represents a stack of items.
|
|
@@ -783,4 +795,611 @@ public class ItemStack implements Cloneable, ConfigurationSerializable {
|
|
return itemMeta.hasItemFlag(flag);
|
|
}
|
|
// Paper end
|
|
+
|
|
+ // Purpur start
|
|
+ /**
|
|
+ * Gets the display name that is set.
|
|
+ * <p>
|
|
+ * Plugins should check that hasDisplayName() returns <code>true</code>
|
|
+ * before calling this method.
|
|
+ *
|
|
+ * @return the display name that is set
|
|
+ */
|
|
+ @NotNull
|
|
+ public String getDisplayName() {
|
|
+ return getItemMeta().getDisplayName();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the display name.
|
|
+ *
|
|
+ * @param name the name to set
|
|
+ */
|
|
+ public void setDisplayName(@Nullable String name) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setDisplayName(name);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for existence of a display name.
|
|
+ *
|
|
+ * @return true if this has a display name
|
|
+ */
|
|
+ public boolean hasDisplayName() {
|
|
+ return getItemMeta().hasDisplayName();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Gets the localized display name that is set.
|
|
+ * <p>
|
|
+ * Plugins should check that hasLocalizedName() returns <code>true</code>
|
|
+ * before calling this method.
|
|
+ *
|
|
+ * @return the localized name that is set
|
|
+ */
|
|
+ @NotNull
|
|
+ public String getLocalizedName() {
|
|
+ return getItemMeta().getLocalizedName();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the localized name.
|
|
+ *
|
|
+ * @param name the name to set
|
|
+ */
|
|
+ public void setLocalizedName(@Nullable String name) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setLocalizedName(name);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for existence of a localized name.
|
|
+ *
|
|
+ * @return true if this has a localized name
|
|
+ */
|
|
+ public boolean hasLocalizedName() {
|
|
+ return getItemMeta().hasLocalizedName();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for existence of lore.
|
|
+ *
|
|
+ * @return true if this has lore
|
|
+ */
|
|
+ public boolean hasLore() {
|
|
+ return getItemMeta().hasLore();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for existence of the specified enchantment.
|
|
+ *
|
|
+ * @param ench enchantment to check
|
|
+ * @return true if this enchantment exists for this meta
|
|
+ */
|
|
+ public boolean hasEnchant(@NotNull Enchantment ench) {
|
|
+ return getItemMeta().hasEnchant(ench);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for the level of the specified enchantment.
|
|
+ *
|
|
+ * @param ench enchantment to check
|
|
+ * @return The level that the specified enchantment has, or 0 if none
|
|
+ */
|
|
+ public int getEnchantLevel(@NotNull Enchantment ench) {
|
|
+ return getItemMeta().getEnchantLevel(ench);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Returns a copy the enchantments in this ItemMeta. <br>
|
|
+ * Returns an empty map if none.
|
|
+ *
|
|
+ * @return An immutable copy of the enchantments
|
|
+ */
|
|
+ @NotNull
|
|
+ public Map<Enchantment, Integer> getEnchants() {
|
|
+ return getItemMeta().getEnchants();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Adds the specified enchantment to this item meta.
|
|
+ *
|
|
+ * @param ench Enchantment to add
|
|
+ * @param level Level for the enchantment
|
|
+ * @param ignoreLevelRestriction this indicates the enchantment should be
|
|
+ * applied, ignoring the level limit
|
|
+ * @return true if the item meta changed as a result of this call, false
|
|
+ * 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;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Removes the specified enchantment from this item meta.
|
|
+ *
|
|
+ * @param ench Enchantment to remove
|
|
+ * @return true if the item meta changed as a result of this call, false
|
|
+ * otherwise
|
|
+ */
|
|
+ public boolean removeEnchant(@NotNull Enchantment ench) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ boolean result = itemMeta.removeEnchant(ench);
|
|
+ setItemMeta(itemMeta);
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for the existence of any enchantments.
|
|
+ *
|
|
+ * @return true if an enchantment exists on this meta
|
|
+ */
|
|
+ public boolean hasEnchants() {
|
|
+ return getItemMeta().hasEnchants();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks if the specified enchantment conflicts with any enchantments in
|
|
+ * this ItemMeta.
|
|
+ *
|
|
+ * @param ench enchantment to test
|
|
+ * @return true if the enchantment conflicts, false otherwise
|
|
+ */
|
|
+ public boolean hasConflictingEnchant(@NotNull Enchantment ench) {
|
|
+ return getItemMeta().hasConflictingEnchant(ench);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the custom model data.
|
|
+ * <p>
|
|
+ * CustomModelData is an integer that may be associated client side with a
|
|
+ * custom item model.
|
|
+ *
|
|
+ * @param data the data to set, or null to clear
|
|
+ */
|
|
+ public void setCustomModelData(@Nullable Integer data) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setCustomModelData(data);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Gets the custom model data that is set.
|
|
+ * <p>
|
|
+ * CustomModelData is an integer that may be associated client side with a
|
|
+ * custom item model.
|
|
+ * <p>
|
|
+ * Plugins should check that hasCustomModelData() returns <code>true</code>
|
|
+ * before calling this method.
|
|
+ *
|
|
+ * @return the localized name that is set
|
|
+ */
|
|
+ public int getCustomModelData() {
|
|
+ return getItemMeta().getCustomModelData();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for existence of custom model data.
|
|
+ * <p>
|
|
+ * CustomModelData is an integer that may be associated client side with a
|
|
+ * custom item model.
|
|
+ *
|
|
+ * @return true if this has custom model data
|
|
+ */
|
|
+ public boolean hasCustomModelData() {
|
|
+ return getItemMeta().hasCustomModelData();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Returns whether the item has block data currently attached to it.
|
|
+ *
|
|
+ * @return whether block data is already attached
|
|
+ */
|
|
+ public boolean hasBlockData() {
|
|
+ return ((BlockDataMeta) getItemMeta()).hasBlockData();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Returns the currently attached block data for this item or creates a new
|
|
+ * one if one doesn't exist.
|
|
+ *
|
|
+ * The state is a copy, it must be set back (or to another item) with
|
|
+ * {@link #setBlockData(BlockData)}
|
|
+ *
|
|
+ * @param material the material we wish to get this data in the context of
|
|
+ * @return the attached data or new data
|
|
+ */
|
|
+ @NotNull
|
|
+ public BlockData getBlockData(@NotNull Material material) {
|
|
+ return ((BlockDataMeta) getItemMeta()).getBlockData(material);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Attaches a copy of the passed block data to the item.
|
|
+ *
|
|
+ * @param blockData the block data to attach to the block.
|
|
+ * @throws IllegalArgumentException if the blockData is null or invalid for
|
|
+ * this item.
|
|
+ */
|
|
+ public void setBlockData(@NotNull BlockData blockData) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ ((BlockDataMeta) itemMeta).setBlockData(blockData);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Gets the repair penalty
|
|
+ *
|
|
+ * @return the repair penalty
|
|
+ */
|
|
+ public int getRepairCost() {
|
|
+ return ((Repairable) getItemMeta()).getRepairCost();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the repair penalty
|
|
+ *
|
|
+ * @param cost repair penalty
|
|
+ */
|
|
+ public void setRepairCost(int cost) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ ((Repairable) itemMeta).setRepairCost(cost);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks to see if this has a repair penalty
|
|
+ *
|
|
+ * @return true if this has a repair penalty
|
|
+ */
|
|
+ public boolean hasRepairCost() {
|
|
+ return ((Repairable) getItemMeta()).hasRepairCost();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Return if the unbreakable tag is true. An unbreakable item will not lose
|
|
+ * durability.
|
|
+ *
|
|
+ * @return true if the unbreakable tag is true
|
|
+ */
|
|
+ public boolean isUnbreakable() {
|
|
+ return getItemMeta().isUnbreakable();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the unbreakable tag. An unbreakable item will not lose durability.
|
|
+ *
|
|
+ * @param unbreakable true if set unbreakable
|
|
+ */
|
|
+ public void setUnbreakable(boolean unbreakable) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setUnbreakable(unbreakable);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for the existence of any AttributeModifiers.
|
|
+ *
|
|
+ * @return true if any AttributeModifiers exist
|
|
+ */
|
|
+ public boolean hasAttributeModifiers() {
|
|
+ return getItemMeta().hasAttributeModifiers();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Return an immutable copy of all Attributes and
|
|
+ * their modifiers in this ItemMeta.<br>
|
|
+ * Returns null if none exist.
|
|
+ *
|
|
+ * @return an immutable {@link Multimap} of Attributes
|
|
+ * and their AttributeModifiers, or null if none exist
|
|
+ */
|
|
+ @Nullable
|
|
+ public Multimap<Attribute, AttributeModifier> getAttributeModifiers() {
|
|
+ return getItemMeta().getAttributeModifiers();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Return an immutable copy of all {@link Attribute}s and their
|
|
+ * {@link AttributeModifier}s for a given {@link EquipmentSlot}.<br>
|
|
+ * Any {@link AttributeModifier} that does have have a given
|
|
+ * {@link EquipmentSlot} will be returned. This is because
|
|
+ * AttributeModifiers without a slot are active in any slot.<br>
|
|
+ * If there are no attributes set for the given slot, an empty map
|
|
+ * will be returned.
|
|
+ *
|
|
+ * @param slot the {@link EquipmentSlot} to check
|
|
+ * @return the immutable {@link Multimap} with the
|
|
+ * respective Attributes and modifiers, or an empty map
|
|
+ * if no attributes are set.
|
|
+ */
|
|
+ @NotNull
|
|
+ public Multimap<Attribute, AttributeModifier> getAttributeModifiers(@Nullable EquipmentSlot slot) {
|
|
+ return getItemMeta().getAttributeModifiers(slot);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Return an immutable copy of all {@link AttributeModifier}s
|
|
+ * for a given {@link Attribute}
|
|
+ *
|
|
+ * @param attribute the {@link Attribute}
|
|
+ * @return an immutable collection of {@link AttributeModifier}s
|
|
+ * or null if no AttributeModifiers exist for the Attribute.
|
|
+ * @throws NullPointerException if Attribute is null
|
|
+ */
|
|
+ @Nullable
|
|
+ public Collection<AttributeModifier> getAttributeModifiers(@NotNull Attribute attribute) {
|
|
+ return getItemMeta().getAttributeModifiers(attribute);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Add an Attribute and it's Modifier.
|
|
+ * AttributeModifiers can now support {@link EquipmentSlot}s.
|
|
+ * If not set, the {@link AttributeModifier} will be active in ALL slots.
|
|
+ * <br>
|
|
+ * Two {@link AttributeModifier}s that have the same {@link java.util.UUID}
|
|
+ * cannot exist on the same Attribute.
|
|
+ *
|
|
+ * @param attribute the {@link Attribute} to modify
|
|
+ * @param modifier the {@link AttributeModifier} specifying the modification
|
|
+ * @return true if the Attribute and AttributeModifier were
|
|
+ * successfully added
|
|
+ * @throws NullPointerException if Attribute is null
|
|
+ * @throws NullPointerException if AttributeModifier is null
|
|
+ * @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;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Set all {@link Attribute}s and their {@link AttributeModifier}s.
|
|
+ * To clear all currently set Attributes and AttributeModifiers use
|
|
+ * null or an empty Multimap.
|
|
+ * If not null nor empty, this will filter all entries that are not-null
|
|
+ * and add them to the ItemStack.
|
|
+ *
|
|
+ * @param attributeModifiers the new Multimap containing the Attributes
|
|
+ * and their AttributeModifiers
|
|
+ */
|
|
+ public void setAttributeModifiers(@Nullable Multimap<Attribute, AttributeModifier> attributeModifiers) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setAttributeModifiers(attributeModifiers);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Remove all {@link AttributeModifier}s associated with the given
|
|
+ * {@link Attribute}.
|
|
+ * This will return false if nothing was removed.
|
|
+ *
|
|
+ * @param attribute attribute to remove
|
|
+ * @return true if all modifiers were removed from a given
|
|
+ * Attribute. Returns false if no attributes were
|
|
+ * removed.
|
|
+ * @throws NullPointerException if Attribute is null
|
|
+ */
|
|
+ public boolean removeAttributeModifier(@NotNull Attribute attribute) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ boolean result = itemMeta.removeAttributeModifier(attribute);
|
|
+ setItemMeta(itemMeta);
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Remove all {@link Attribute}s and {@link AttributeModifier}s for a
|
|
+ * given {@link EquipmentSlot}.<br>
|
|
+ * If the given {@link EquipmentSlot} is null, this will remove all
|
|
+ * {@link AttributeModifier}s that do not have an EquipmentSlot set.
|
|
+ *
|
|
+ * @param slot the {@link EquipmentSlot} to clear all Attributes and
|
|
+ * their modifiers for
|
|
+ * @return true if all modifiers were removed that match the given
|
|
+ * EquipmentSlot.
|
|
+ */
|
|
+ public boolean removeAttributeModifier(@Nullable EquipmentSlot slot) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ boolean result = itemMeta.removeAttributeModifier(slot);
|
|
+ setItemMeta(itemMeta);
|
|
+ return result;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Remove a specific {@link Attribute} and {@link AttributeModifier}.
|
|
+ * AttributeModifiers are matched according to their {@link java.util.UUID}.
|
|
+ *
|
|
+ * @param attribute the {@link Attribute} to remove
|
|
+ * @param modifier the {@link AttributeModifier} to remove
|
|
+ * @return if any attribute modifiers were remove
|
|
+ *
|
|
+ * @throws NullPointerException if the Attribute is null
|
|
+ * @throws NullPointerException if the AttributeModifier is null
|
|
+ *
|
|
+ * @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;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Returns a custom tag container capable of storing tags on the object.
|
|
+ *
|
|
+ * Note that the tags stored on this container are all stored under their
|
|
+ * own custom namespace therefore modifying default tags using this
|
|
+ * {@link PersistentDataHolder} is impossible.
|
|
+ *
|
|
+ * @return the persistent metadata container
|
|
+ */
|
|
+ @NotNull
|
|
+ public PersistentDataContainer getPersistentDataContainer() {
|
|
+ return getItemMeta().getPersistentDataContainer();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks to see if this item has damage
|
|
+ *
|
|
+ * @return true if this has damage
|
|
+ */
|
|
+ public boolean hasDamage() {
|
|
+ return ((Damageable) getItemMeta()).hasDamage();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Gets the damage
|
|
+ *
|
|
+ * @return the damage
|
|
+ */
|
|
+ public int getDamage() {
|
|
+ return ((Damageable) getItemMeta()).getDamage();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the damage
|
|
+ *
|
|
+ * @param damage item damage
|
|
+ */
|
|
+ public void setDamage(int damage) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ ((Damageable) itemMeta).setDamage(damage);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Gets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
|
|
+ *
|
|
+ * @return Set of {@link com.destroystokyo.paper.Namespaced}
|
|
+ */
|
|
+ @NotNull
|
|
+ public Set<Namespaced> getDestroyableKeys() {
|
|
+ return getItemMeta().getDestroyableKeys();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
|
|
+ *
|
|
+ * @param canDestroy Collection of {@link com.destroystokyo.paper.Namespaced}
|
|
+ */
|
|
+ public void setDestroyableKeys(@NotNull Collection<Namespaced> canDestroy) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setDestroyableKeys(canDestroy);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Gets the collection of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
|
|
+ *
|
|
+ * @return Set of {@link com.destroystokyo.paper.Namespaced}
|
|
+ */
|
|
+ @NotNull
|
|
+ public Set<Namespaced> getPlaceableKeys() {
|
|
+ return getItemMeta().getPlaceableKeys();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Sets the set of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
|
|
+ *
|
|
+ * @param canPlaceOn Collection of {@link com.destroystokyo.paper.Namespaced}
|
|
+ */
|
|
+ @NotNull
|
|
+ public void setPlaceableKeys(@NotNull Collection<Namespaced> canPlaceOn) {
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ itemMeta.setPlaceableKeys(canPlaceOn);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for the existence of any keys that the item can be placed on
|
|
+ *
|
|
+ * @return true if this item has placeable keys
|
|
+ */
|
|
+ public boolean hasPlaceableKeys() {
|
|
+ return getItemMeta().hasPlaceableKeys();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Checks for the existence of any keys that the item can destroy
|
|
+ *
|
|
+ * @return true if this item has destroyable keys
|
|
+ */
|
|
+ public boolean hasDestroyableKeys() {
|
|
+ return getItemMeta().hasDestroyableKeys();
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Repairs this item by 1 durability
|
|
+ */
|
|
+ public void repair() {
|
|
+ repair(1);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Damages this item by 1 durability
|
|
+ */
|
|
+ public void damage() {
|
|
+ damage(1);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Repairs this item's durability by amount
|
|
+ *
|
|
+ * @param amount Amount of durability to repair
|
|
+ */
|
|
+ public void repair(int amount) {
|
|
+ damage(-amount);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Damages this item's durability by amount
|
|
+ *
|
|
+ * @param amount Amount of durability to damage
|
|
+ */
|
|
+ public void damage(int amount) {
|
|
+ damage(amount, false);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Damages this item's durability by amount
|
|
+ *
|
|
+ * @param amount Amount of durability to damage
|
|
+ * @param ignoreUnbreaking Ignores unbreaking enchantment
|
|
+ */
|
|
+ public void damage(int amount, boolean ignoreUnbreaking) {
|
|
+ if (amount > 0) {
|
|
+ int unbreaking = getEnchantLevel(Enchantment.DURABILITY);
|
|
+ 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;
|
|
+ }
|
|
+ }
|
|
+ ItemMeta itemMeta = getItemMeta();
|
|
+ Damageable damageable = (Damageable) itemMeta;
|
|
+ damageable.setDamage(damageable.getDamage() + amount);
|
|
+ setItemMeta(itemMeta);
|
|
+ }
|
|
+
|
|
+ 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
|
|
}
|
|
--
|
|
2.24.0
|
|
|