From a5be7e19c2d5ba08d2df9f1190990b826e197f63 Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 1 Mar 2016 08:30:03 +1100 Subject: Add Attribute and AttributeModifier API. Thanks to __0x277F and Meeh on #spigot-dev for implementation advice. --- .../java/org/bukkit/attribute/Attributable.java | 16 ++++ src/main/java/org/bukkit/attribute/Attribute.java | 48 ++++++++++ .../org/bukkit/attribute/AttributeInstance.java | 60 ++++++++++++ .../org/bukkit/attribute/AttributeModifier.java | 103 +++++++++++++++++++++ src/main/java/org/bukkit/entity/LivingEntity.java | 3 +- 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/bukkit/attribute/Attributable.java create mode 100644 src/main/java/org/bukkit/attribute/Attribute.java create mode 100644 src/main/java/org/bukkit/attribute/AttributeInstance.java create mode 100644 src/main/java/org/bukkit/attribute/AttributeModifier.java (limited to 'src') diff --git a/src/main/java/org/bukkit/attribute/Attributable.java b/src/main/java/org/bukkit/attribute/Attributable.java new file mode 100644 index 00000000..155f13f1 --- /dev/null +++ b/src/main/java/org/bukkit/attribute/Attributable.java @@ -0,0 +1,16 @@ +package org.bukkit.attribute; + +/** + * Represents an object which may contain attributes. + */ +public interface Attributable { + + /** + * Gets the specified attribute instance from the object. This instance will + * be backed directly to the object and any changes will be visible at once. + * + * @param attribute the attribute to get + * @return the attribute instance or null if not applicable to this object + */ + AttributeInstance getAttribute(Attribute attribute); +} diff --git a/src/main/java/org/bukkit/attribute/Attribute.java b/src/main/java/org/bukkit/attribute/Attribute.java new file mode 100644 index 00000000..38bea1e7 --- /dev/null +++ b/src/main/java/org/bukkit/attribute/Attribute.java @@ -0,0 +1,48 @@ +package org.bukkit.attribute; + +/** + * Types of attributes which may be present on an {@link Attributable}. + */ +public enum Attribute { + + /** + * Maximum health of an Entity. + */ + GENERIC_MAX_HEALTH, + /** + * Range at which an Entity will follow others. + */ + GENERIC_FOLLOW_RANGE, + /** + * Resistance of an Entity to knockback. + */ + GENERIC_KNOCKBACK_RESISTANCE, + /** + * Movement speed of an Entity. + */ + GENERIC_MOVEMENT_SPEED, + /** + * Attack damage of an Entity. + */ + GENERIC_ATTACK_DAMAGE, + /** + * Attack speed of an Entity. + */ + GENERIC_ATTACK_SPEED, + /** + * Armor bonus of an Entity. + */ + GENERIC_ARMOR, + /** + * Luck bonus of an Entity. + */ + GENERIC_LUCK, + /** + * Strength with which a horse will jump. + */ + HORSE_JUMP_STRENGTH, + /** + * Chance of a zombie to spawn reinforcements. + */ + ZOMBIE_SPAWN_REINFORCEMENTS; +} diff --git a/src/main/java/org/bukkit/attribute/AttributeInstance.java b/src/main/java/org/bukkit/attribute/AttributeInstance.java new file mode 100644 index 00000000..450e0568 --- /dev/null +++ b/src/main/java/org/bukkit/attribute/AttributeInstance.java @@ -0,0 +1,60 @@ +package org.bukkit.attribute; + +import java.util.Collection; + +/** + * Represents a mutable instance of an attribute and its associated modifiers + * and values. + */ +public interface AttributeInstance { + + /** + * The attribute pertaining to this instance. + * + * @return the attribute + */ + Attribute getAttribute(); + + /** + * Base value of this instance before modifiers are applied. + * + * @return base value + */ + double getBaseValue(); + + /** + * Set the base value of this instance. + * + * @param value new base value + */ + void setBaseValue(double value); + + /** + * Get all modifiers present on this instance. + * + * @return + */ + Collection getModifiers(); + + /** + * Add a modifier to this instance. + * + * @param modifier to add + */ + void addModifier(AttributeModifier modifier); + + /** + * Remove a modifier from this instance. + * + * @param modifier to remove + */ + void removeModifier(AttributeModifier modifier); + + /** + * Get the value of this instance after all associated modifiers have been + * applied. + * + * @return the total attribute value + */ + double getValue(); +} diff --git a/src/main/java/org/bukkit/attribute/AttributeModifier.java b/src/main/java/org/bukkit/attribute/AttributeModifier.java new file mode 100644 index 00000000..ade7bf08 --- /dev/null +++ b/src/main/java/org/bukkit/attribute/AttributeModifier.java @@ -0,0 +1,103 @@ +package org.bukkit.attribute; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.util.NumberConversions; + +/** + * Concrete implementation of an attribute modifier. + */ +public class AttributeModifier implements ConfigurationSerializable { + + private final UUID uuid; + private final String name; + private final double amount; + private final Operation operation; + + 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 = uuid; + this.name = name; + this.amount = amount; + this.operation = operation; + } + + /** + * Get the unique ID for this modifier. + * + * @return unique id + */ + public UUID getUniqueId() { + return uuid; + } + + /** + * Get the name of this modifier. + * + * @return name + */ + public String getName() { + return name; + } + + /** + * Get the amount by which this modifier will apply its {@link Operation}. + * + * @return modification amount + */ + public double getAmount() { + return amount; + } + + /** + * Get the operation this modifier will apply. + * + * @return operation + */ + public Operation getOperation() { + return operation; + } + + @Override + public Map serialize() { + Map data = new HashMap(); + data.put("uuid", uuid); + data.put("name", name); + data.put("operation", operation.ordinal()); + data.put("amount", amount); + return data; + } + + public static AttributeModifier deserialize(Map args) { + return new AttributeModifier((UUID) args.get("uuid"), (String) args.get("name"), NumberConversions.toDouble(args.get("amount")), Operation.values()[NumberConversions.toInt(args.get("operation"))]); + } + + /** + * Enumerable operation to be applied. + */ + public enum Operation { + + /** + * Adds (or subtracts) the specified amount to the base value. + */ + ADD_NUMBER, + /** + * Adds this scalar of amount to the base value. + */ + ADD_SCALAR, + /** + * Multiply amount by this value, after adding 1 to it. + */ + MULTIPLY_SCALAR_1; + } +} diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java index 5d35bfcb..46347b9c 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java @@ -7,6 +7,7 @@ import java.util.Set; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.attribute.Attributable; import org.bukkit.block.Block; import org.bukkit.inventory.EntityEquipment; import org.bukkit.potion.PotionEffect; @@ -16,7 +17,7 @@ import org.bukkit.projectiles.ProjectileSource; /** * Represents a living entity, such as a monster or player */ -public interface LivingEntity extends Entity, Damageable, ProjectileSource { +public interface LivingEntity extends Attributable, Entity, Damageable, ProjectileSource { /** * Gets the height of the living entity's eyes above its Location. -- cgit v1.2.3