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.

By: Wesley Wolfe <wesley.d.wolfe+git@gmail.com>
This commit is contained in:
Bukkit/Spigot 2014-06-02 01:05:03 -05:00
parent 9a3633a13f
commit 8460bd531a
3 changed files with 165 additions and 7 deletions

View file

@ -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<DamageModifier, Double> modifiers) {
super(damagee, cause, modifiers);
this.damager = damager;
}
/**
* Returns the block that damaged the player.
*

View file

@ -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<DamageModifier, Double> modifiers) {
super(damagee, cause, modifiers);
this.damager = damager;
}
/**
* Returns the entity that damaged the defender.
*

View file

@ -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<DamageModifier, Double> modifiers;
private final Map<DamageModifier, Double> 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<DamageModifier, Double>(ImmutableMap.of(DamageModifier.BASE, damage)));
}
public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> 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<DamageModifier, Double>(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.
*
* @return The amount of damage caused by the event
* @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}.
* <p>
* {@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 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:
* <ul>
* <li>
* Armor enchantments
* </li><li>
* Witch's potion resistance
* </li>
* </ul>
*/
MAGIC,
/**
* This represents the damage reduction caused by the absorption potion
* effect.
*/
ABSORPTION,
;
}
/**
* An enum to specify the cause of the damage
*/