You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
4.1 KiB
85 lines
4.1 KiB
--- ../src-base/minecraft/org/bukkit/event/entity/EntityDamageEvent.java |
|
+++ ../src-work/minecraft/org/bukkit/event/entity/EntityDamageEvent.java |
|
@@ -10,6 +10,8 @@ |
|
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 @@ |
|
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 @@ |
|
|
|
@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 @@ |
|
} |
|
|
|
/** |
|
- * 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); |
|
} |
|
|
|
|