summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java5
-rw-r--r--src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java5
-rw-r--r--src/main/java/org/bukkit/event/entity/EntityDamageEvent.java42
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);
}