From 657200d93c910258d0f2681ead2a4a2413928df5 Mon Sep 17 00:00:00 2001 From: Wesley Wolfe Date: Mon, 2 Jun 2014 01:05:03 -0500 Subject: Add damage modifier API in EntityDamageEvent. Adds BUKKIT-347, BUKKIT-4104 This commit adds API for the enchantment, armor, potion and other modifications to damage done to an entity. These damage modifiers are each editable editable via a getter and a setter. This addition allows for more accurate modification and monitoring of damage done to/by an entity, as it displays the final damage done as well. --- .../event/entity/EntityDamageByBlockEvent.java | 8 ++ .../event/entity/EntityDamageByEntityEvent.java | 8 ++ .../org/bukkit/event/entity/EntityDamageEvent.java | 156 ++++++++++++++++++++- 3 files changed, 165 insertions(+), 7 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java index c9ebdfb7..49bf2a84 100644 --- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java @@ -1,5 +1,7 @@ package org.bukkit.event.entity; +import java.util.Map; + import org.bukkit.block.Block; import org.bukkit.entity.Entity; @@ -14,11 +16,17 @@ public class EntityDamageByBlockEvent extends EntityDamageEvent { this(damager, damagee, cause, (double) damage); } + @Deprecated public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final double damage) { super(damagee, cause, damage); this.damager = damager; } + public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final Map modifiers) { + super(damagee, cause, modifiers); + this.damager = damager; + } + /** * Returns the block that damaged the player. * diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java index 9eb9f274..e7ea32f5 100644 --- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java @@ -1,5 +1,7 @@ package org.bukkit.event.entity; +import java.util.Map; + import org.bukkit.entity.Entity; /** @@ -13,11 +15,17 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { this(damager, damagee, cause, (double) damage); } + @Deprecated public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final double damage) { super(damagee, cause, damage); this.damager = damager; } + public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final Map modifiers) { + super(damagee, cause, modifiers); + this.damager = damager; + } + /** * Returns the entity that damaged the defender. * diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java index 6e722d29..17d95487 100644 --- a/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java @@ -1,16 +1,25 @@ package org.bukkit.event.entity; +import java.util.EnumMap; +import java.util.Map; + +import org.apache.commons.lang.Validate; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.util.NumberConversions; +import com.google.common.collect.ImmutableMap; + /** * Stores data for damage events */ public class EntityDamageEvent extends EntityEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); - private double damage; + private static final DamageModifier[] MODIFIERS = DamageModifier.values(); + private final Map modifiers; + private final Map originals; private boolean cancelled; private final DamageCause cause; @@ -19,10 +28,18 @@ public class EntityDamageEvent extends EntityEvent implements Cancellable { this(damagee, cause, (double) damage); } + @Deprecated public EntityDamageEvent(final Entity damagee, final DamageCause cause, final double damage) { + this(damagee, cause, new EnumMap(ImmutableMap.of(DamageModifier.BASE, damage))); + } + + public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map modifiers) { super(damagee); + Validate.isTrue(modifiers.containsKey(DamageModifier.BASE), "BASE DamageModifier missing"); + Validate.isTrue(!modifiers.containsKey(null), "Cannot have null DamageModifier"); + this.originals = new EnumMap(modifiers); this.cause = cause; - this.damage = damage; + this.modifiers = modifiers; } public boolean isCancelled() { @@ -34,11 +51,90 @@ public class EntityDamageEvent extends EntityEvent implements Cancellable { } /** - * Gets the amount of damage caused by the event + * Gets the original damage for the specified modifier, as defined at this + * event's construction. + * + * @param type the modifier + * @throws IllegalArgumentException if type is null + */ + public double getOriginalDamage(DamageModifier type) throws IllegalArgumentException { + final Double damage = originals.get(type); + if (damage != null) { + return damage; + } + if (type == null) { + throw new IllegalArgumentException("Cannot have null DamageModifier"); + } + return 0; + } + + /** + * Sets the damage for the specified modifier. + * + * @param damage the scalar value of the damage's modifier + * @see #getFinalDamage() + * @throws IllegalArgumentException if type is null + * @throws UnsupportedOperationException if the caller does not support + * the particular DamageModifier, or to rephrase, when {@link + * #isApplicable(DamageModifier)} returns false + */ + public void setDamage(DamageModifier type, double damage) throws IllegalArgumentException, UnsupportedOperationException { + if (!modifiers.containsKey(type)) { + throw type == null ? new IllegalArgumentException("Cannot have null DamageModifier") : new UnsupportedOperationException(type + " is not applicable to " + getEntity()); + } + modifiers.put(type, damage); + } + + /** + * Gets the damage change for some modifier + * + * @return The raw amount of damage caused by the event + * @throws IllegalArgumentException if type is null + * @see DamageModifier#BASE + */ + public double getDamage(DamageModifier type) throws IllegalArgumentException { + Validate.notNull(type, "Cannot have null DamageModifier"); + final Double damage = modifiers.get(type); + return damage == null ? 0 : damage; + } + + /** + * This checks to see if a particular modifier is valid for this event's + * caller, such that, {@link #setDamage(DamageModifier, double)} will not + * throw an {@link UnsupportedOperationException}. + *

+ * {@link DamageModifier#BASE} is always applicable. + * + * @param type the modifier + * @return true if the modifier is supported by the caller, false otherwise + * @throws IllegalArgumentException if type is null + */ + public boolean isApplicable(DamageModifier type) throws IllegalArgumentException { + Validate.notNull(type, "Cannot have null DamageModifier"); + return modifiers.containsKey(type); + } + + /** + * Gets the raw amount of damage caused by the event * - * @return The amount of damage caused by the event + * @return The raw amount of damage caused by the event + * @see DamageModifier#BASE */ public double getDamage() { + return getDamage(DamageModifier.BASE); + } + + /** + * Gets the amount of damage caused by the event after all damage + * reduction is applied. + * + * @return the amount of damage caused by the event + */ + public final double getFinalDamage() { + double damage = 0; + for (DamageModifier modifier : MODIFIERS) { + damage += getDamage(modifier); + } return damage; } @@ -53,12 +149,12 @@ public class EntityDamageEvent extends EntityEvent implements Cancellable { } /** - * Sets the amount of damage caused by the event + * Sets the raw amount of damage caused by the event * - * @param damage The amount of damage caused by the event + * @param damage The raw amount of damage caused by the event */ public void setDamage(double damage) { - this.damage = damage; + setDamage(DamageModifier.BASE, damage); } /** @@ -89,6 +185,52 @@ public class EntityDamageEvent extends EntityEvent implements Cancellable { return handlers; } + /** + * An enum to specify the types of modifier + */ + public enum DamageModifier { + /** + * This represents the amount of damage being done, also known as the + * raw {@link EntityDamageEvent#getDamage()}. + */ + BASE, + /** + * This represents the damage reduced by a wearing a helmet when hit + * by a falling block. + */ + HARD_HAT, + /** + * This represents the damage reduction caused by blocking, only present for + * {@link Player Players}. + */ + BLOCKING, + /** + * This represents the damage reduction caused by wearing armor. + */ + ARMOR, + /** + * This represents the damage reduction caused by the Resistance potion effect. + */ + RESISTANCE, + /** + * This represents the damage reduction caused by the combination of: + *

    + *
  • + * Armor enchantments + *
  • + * Witch's potion resistance + *
  • + *
+ */ + MAGIC, + /** + * This represents the damage reduction caused by the absorption potion + * effect. + */ + ABSORPTION, + ; + } + /** * An enum to specify the cause of the damage */ -- cgit v1.2.3