diff options
Diffstat (limited to 'src/main/java/org')
3 files changed, 45 insertions, 7 deletions
diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java index 49bf2a84..2ff121e3 100644 --- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.entity; import java.util.Map; +import com.google.common.base.Function; import org.bukkit.block.Block; import org.bukkit.entity.Entity; @@ -22,8 +23,8 @@ public class EntityDamageByBlockEvent extends EntityDamageEvent { this.damager = damager; } - public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> modifiers) { - super(damagee, cause, modifiers); + public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> modifiers, final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) { + super(damagee, cause, modifiers, modifierFunctions); this.damager = damager; } diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java index e7ea32f5..49e74c30 100644 --- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.entity; import java.util.Map; +import com.google.common.base.Function; import org.bukkit.entity.Entity; /** @@ -21,8 +22,8 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { this.damager = damager; } - public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> modifiers) { - super(damagee, cause, modifiers); + public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> modifiers, final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) { + super(damagee, cause, modifiers, modifierFunctions); this.damager = damager; } diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java index 17d95487..2cc07996 100644 --- a/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java +++ b/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java @@ -10,6 +10,8 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.util.NumberConversions; +import com.google.common.base.Function; +import com.google.common.base.Functions; import com.google.common.collect.ImmutableMap; /** @@ -18,7 +20,9 @@ import com.google.common.collect.ImmutableMap; public class EntityDamageEvent extends EntityEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private static final DamageModifier[] MODIFIERS = DamageModifier.values(); + private static final Function<? super Double, Double> ZERO = Functions.constant(-0.0); private final Map<DamageModifier, Double> modifiers; + private final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions; private final Map<DamageModifier, Double> originals; private boolean cancelled; private final DamageCause cause; @@ -30,16 +34,20 @@ public class EntityDamageEvent extends EntityEvent implements Cancellable { @Deprecated public EntityDamageEvent(final Entity damagee, final DamageCause cause, final double damage) { - this(damagee, cause, new EnumMap<DamageModifier, Double>(ImmutableMap.of(DamageModifier.BASE, damage))); + this(damagee, cause, new EnumMap<DamageModifier, Double>(ImmutableMap.of(DamageModifier.BASE, damage)), new EnumMap<DamageModifier, Function<? super Double, Double>>(ImmutableMap.of(DamageModifier.BASE, ZERO))); } - public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> modifiers) { + public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map<DamageModifier, Double> modifiers, final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) { super(damagee); Validate.isTrue(modifiers.containsKey(DamageModifier.BASE), "BASE DamageModifier missing"); Validate.isTrue(!modifiers.containsKey(null), "Cannot have null DamageModifier"); + Validate.noNullElements(modifiers.values(), "Cannot have null modifier values"); + Validate.isTrue(modifiers.keySet().equals(modifierFunctions.keySet()), "Must have a modifier function for each DamageModifier"); + Validate.noNullElements(modifierFunctions.values(), "Cannot have null modifier function"); this.originals = new EnumMap<DamageModifier, Double>(modifiers); this.cause = cause; this.modifiers = modifiers; + this.modifierFunctions = modifierFunctions; } public boolean isCancelled() { @@ -149,11 +157,39 @@ public class EntityDamageEvent extends EntityEvent implements Cancellable { } /** - * Sets the raw amount of damage caused by the event + * Sets the raw amount of damage caused by the event. + * <p> + * For compatibility this also recalculates the modifiers and scales + * them by the difference between the modifier for the previous damage + * value and the new one. * * @param damage The raw amount of damage caused by the event */ public void setDamage(double damage) { + // These have to happen in the same order as the server calculates them, keep the enum sorted + double remaining = damage; + double oldRemaining = getDamage(DamageModifier.BASE); + for (DamageModifier modifier : MODIFIERS) { + if (!isApplicable(modifier)) { + continue; + } + + Function<? super Double, Double> modifierFunction = modifierFunctions.get(modifier); + double newVanilla = modifierFunction.apply(remaining); + double oldVanilla = modifierFunction.apply(oldRemaining); + double difference = oldVanilla - newVanilla; + + // Don't allow value to cross zero, assume zero values should be negative + double old = getDamage(modifier); + if (old > 0) { + setDamage(modifier, Math.max(0, old - difference)); + } else { + setDamage(modifier, Math.min(0, old - difference)); + } + remaining += newVanilla; + oldRemaining += oldVanilla; + } + setDamage(DamageModifier.BASE, damage); } |