summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSenmori <thesenmori@gmail.com>2018-09-21 20:41:38 +1000
committermd_5 <git@md-5.net>2018-09-21 20:50:57 +1000
commitcbb4fc1673f278d61b5238df15aa1a1fb69655cc (patch)
treef1d6603a466f9f25f39645db8a89a9d9bbc3b210
parent4b9a93eccfefb73860fbbf6e6ea072676e26ef92 (diff)
downloadbukkit-cbb4fc1673f278d61b5238df15aa1a1fb69655cc.tar
bukkit-cbb4fc1673f278d61b5238df15aa1a1fb69655cc.tar.gz
bukkit-cbb4fc1673f278d61b5238df15aa1a1fb69655cc.tar.lz
bukkit-cbb4fc1673f278d61b5238df15aa1a1fb69655cc.tar.xz
bukkit-cbb4fc1673f278d61b5238df15aa1a1fb69655cc.zip
SPIGOT-1916: Attribute modifiers for ItemStacks
-rw-r--r--src/main/java/org/bukkit/attribute/AttributeModifier.java49
-rw-r--r--src/main/java/org/bukkit/inventory/meta/ItemMeta.java122
2 files changed, 168 insertions, 3 deletions
diff --git a/src/main/java/org/bukkit/attribute/AttributeModifier.java b/src/main/java/org/bukkit/attribute/AttributeModifier.java
index 3c0c4bc5..a3a69ffa 100644
--- a/src/main/java/org/bukkit/attribute/AttributeModifier.java
+++ b/src/main/java/org/bukkit/attribute/AttributeModifier.java
@@ -5,6 +5,7 @@ import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.util.NumberConversions;
/**
@@ -16,20 +17,25 @@ public class AttributeModifier implements ConfigurationSerializable {
private final String name;
private final double amount;
private final Operation operation;
+ private final EquipmentSlot slot;
public AttributeModifier(String name, double amount, Operation operation) {
this(UUID.randomUUID(), name, amount, operation);
}
public AttributeModifier(UUID uuid, String name, double amount, Operation operation) {
- Validate.notNull(uuid, "uuid");
- Validate.notEmpty(name, "Name cannot be empty");
- Validate.notNull(operation, "operation");
+ this(uuid, name, amount, operation, null);
+ }
+ public AttributeModifier(UUID uuid, String name, double amount, Operation operation, EquipmentSlot slot) {
+ Validate.notNull(uuid, "UUID cannot be null");
+ Validate.notEmpty(name, "Name cannot be empty");
+ Validate.notNull(operation, "Operation cannot be null");
this.uuid = uuid;
this.name = name;
this.amount = amount;
this.operation = operation;
+ this.slot = slot;
}
/**
@@ -68,6 +74,16 @@ public class AttributeModifier implements ConfigurationSerializable {
return operation;
}
+ /**
+ * Get the {@link EquipmentSlot} this AttributeModifier is active on,
+ * or null if this modifier is applicable for any slot.
+ *
+ * @return the slot
+ */
+ public EquipmentSlot getSlot() {
+ return slot;
+ }
+
@Override
public Map<String, Object> serialize() {
Map<String, Object> data = new HashMap<String, Object>();
@@ -75,10 +91,37 @@ public class AttributeModifier implements ConfigurationSerializable {
data.put("name", name);
data.put("operation", operation.ordinal());
data.put("amount", amount);
+ if (slot != null) {
+ data.put("slot", slot.name());
+ }
return data;
}
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof AttributeModifier)) {
+ return false;
+ }
+ AttributeModifier mod = (AttributeModifier) other;
+ boolean slots = (this.slot != null ? (this.slot == mod.slot) : mod.slot != null);
+ return this.uuid.equals(mod.uuid) && this.name.equals(mod.name) && this.amount == mod.amount && this.operation == mod.operation && slots;
+ }
+
+ @Override
+ public String toString() {
+ return "AttributeModifier{"
+ + "uuid=" + this.uuid.toString()
+ + ", name=" + this.name
+ + ", operation=" + this.operation.name()
+ + ", amount=" + this.amount
+ + ", slot=" + (this.slot != null ? this.slot.name() : "")
+ + "}";
+ }
+
public static AttributeModifier deserialize(Map<String, Object> args) {
+ if (args.containsKey("slot")) {
+ return new AttributeModifier(UUID.fromString((String) args.get("uuid")), (String) args.get("name"), NumberConversions.toDouble(args.get("amount")), Operation.values()[NumberConversions.toInt(args.get("operation"))], EquipmentSlot.valueOf((args.get("slot").toString().toUpperCase())));
+ }
return new AttributeModifier(UUID.fromString((String) args.get("uuid")), (String) args.get("name"), NumberConversions.toDouble(args.get("amount")), Operation.values()[NumberConversions.toInt(args.get("operation"))]);
}
diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
index 76d43266..73bdcebd 100644
--- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
+++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
@@ -1,11 +1,16 @@
package org.bukkit.inventory.meta;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import com.google.common.collect.Multimap;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.enchantments.Enchantment;
+import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemFlag;
/**
@@ -13,6 +18,8 @@ import org.bukkit.inventory.ItemFlag;
* <p>
* An implementation will handle the creation and application for ItemMeta.
* This class should not be implemented by a plugin in a live environment.
+ * <p>
+ * <b>Attribute related APIs are draft API</b>
*/
public interface ItemMeta extends Cloneable, ConfigurationSerializable {
@@ -194,6 +201,121 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable {
*/
void setUnbreakable(boolean unbreakable);
+ /**
+ * Checks for the existence of any AttributeModifiers.
+ *
+ * @return true if any AttributeModifiers exist
+ */
+ boolean 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
+ */
+ Multimap<Attribute, AttributeModifier> 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.
+ */
+ Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot 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
+ */
+ Collection<AttributeModifier> getAttributeModifiers(Attribute 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
+ */
+ boolean addAttributeModifier(Attribute attribute, AttributeModifier modifier);
+
+ /**
+ * 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
+ */
+ void setAttributeModifiers(Multimap<Attribute, AttributeModifier> attributeModifiers);
+
+ /**
+ * 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
+ */
+ boolean removeAttributeModifier(Attribute attribute);
+
+ /**
+ * 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.
+ */
+ boolean removeAttributeModifier(EquipmentSlot slot);
+
+ /**
+ * 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
+ *
+ * @see AttributeModifier#getUniqueId()
+ *
+ * @throws NullPointerException if the Attribute is null
+ * @throws NullPointerException if the AttributeModifier is null
+ */
+ boolean removeAttributeModifier(Attribute attribute, AttributeModifier modifier);
+
@SuppressWarnings("javadoc")
ItemMeta clone();
}