From 13482ac7f63f1e652b194b63fadf918720ec3c9e Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Wed, 9 Jul 2014 16:21:06 -0500 Subject: [PATCH] Put damage modifiers in Functions for event. Fixes BUKKIT-5681 --- .../net/minecraft/server/EntityLiving.java | 104 +++++++++++------- .../craftbukkit/event/CraftEventFactory.java | 50 +++++---- 2 files changed, 97 insertions(+), 57 deletions(-) diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index f86d698a4c..0c63b2c6ca 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -9,6 +9,7 @@ import java.util.UUID; // CraftBukkit start import java.util.ArrayList; +import com.google.common.base.Function; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; @@ -956,49 +957,78 @@ public abstract class EntityLiving extends Entity { } // CraftBukkit start - protected boolean d(DamageSource damagesource, float f) { // void -> boolean + protected boolean d(final DamageSource damagesource, float f) { // void -> boolean, add final if (!this.isInvulnerable()) { - boolean human = this instanceof EntityHuman; + final boolean human = this instanceof EntityHuman; float originalDamage = f; - float preDamage = f; - float hardHatModifier = 0; - if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { - f *= 0.75F; - hardHatModifier = preDamage - f; - preDamage = f; - } - float blockingModifier = 0; - if (human) { - if (!damagesource.ignoresArmor() && ((EntityHuman) this).isBlocking() && f > 0.0F) { - f = (1.0F + f) * 0.5F; - blockingModifier = preDamage - f; - preDamage = f; + Function hardHat = new Function() { + @Override + public Double apply(Double f) { + if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && EntityLiving.this.getEquipment(4) != null) { + return -(f - (f * 0.75F)); + } + return -0.0; } - } - // Armor modifier - f = this.applyArmorModifier(damagesource, f); - float armorModifier = preDamage - f; - preDamage = f; - // Resistance Potion Effect - if (!damagesource.isStarvation() && this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { - int i = (this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; - int j = 25 - i; - float f1 = f * (float) j; - f = f1 / 25.0F; - } - float resistanceModifier = preDamage - f; - preDamage = f; - // Magic modifier - f = this.applyMagicModifier(damagesource, f); - float magicModifier = preDamage - f; - float f1 = f; + }; + float hardHatModifier = hardHat.apply((double) f).floatValue(); + f += hardHatModifier; - // Absorption modifier - f = Math.max(f - this.getAbsorptionHearts(), 0.0F); - float absorptionModifier = Math.max(f1 - f, 0.0F); + Function blocking = new Function() { + @Override + public Double apply(Double f) { + if (human) { + if (!damagesource.ignoresArmor() && ((EntityHuman) EntityLiving.this).isBlocking() && f > 0.0F) { + return -(f - ((1.0F + f) * 0.5F)); + } + } + return -0.0; + } + }; + float blockingModifier = blocking.apply((double) f).floatValue(); + f += blockingModifier; - EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, -hardHatModifier, -blockingModifier, -armorModifier, -resistanceModifier, -magicModifier, -absorptionModifier); + Function armor = new Function() { + @Override + public Double apply(Double f) { + return -(f - EntityLiving.this.applyArmorModifier(damagesource, f.floatValue())); + } + }; + float armorModifier = armor.apply((double) f).floatValue(); + f += armorModifier; + Function resistance = new Function() { + @Override + public Double apply(Double f) { + if (!damagesource.isStarvation() && EntityLiving.this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { + int i = (EntityLiving.this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; + int j = 25 - i; + float f1 = f.floatValue() * (float) j; + return -(f - (f1 / 25.0F)); + } + return -0.0; + } + }; + float resistanceModifier = resistance.apply((double) f).floatValue(); + f += resistanceModifier; + + Function magic = new Function() { + @Override + public Double apply(Double f) { + return -(f - EntityLiving.this.applyMagicModifier(damagesource, f.floatValue())); + } + }; + float magicModifier = magic.apply((double) f).floatValue(); + f += magicModifier; + + Function absorption = new Function() { + @Override + public Double apply(Double f) { + return -(Math.max(f - Math.max(f - EntityLiving.this.getAbsorptionHearts(), 0.0F), 0.0F)); + } + }; + float absorptionModifier = absorption.apply((double) f).floatValue(); + + EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); if (event.isCancelled()) { return false; } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 2d5182a6d5..7e27769239 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -3,10 +3,11 @@ package org.bukkit.craftbukkit.event; import java.net.InetAddress; import java.util.ArrayList; import java.util.EnumMap; -import java.util.HashMap; import java.util.List; import java.util.Map; +import com.google.common.base.Function; +import com.google.common.base.Functions; import net.minecraft.server.ChunkCoordinates; import net.minecraft.server.Container; import net.minecraft.server.DamageSource; @@ -23,7 +24,6 @@ import net.minecraft.server.EntityLiving; import net.minecraft.server.EntityPlayer; import net.minecraft.server.EntityPotion; import net.minecraft.server.Explosion; -import net.minecraft.server.IInventory; import net.minecraft.server.InventoryCrafting; import net.minecraft.server.ItemStack; import net.minecraft.server.Items; @@ -403,23 +403,23 @@ public class CraftEventFactory { return event; } - private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers) { + private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions) { if (source.isExplosion()) { DamageCause damageCause; Entity damager = entityDamage; entityDamage = null; EntityDamageEvent event; if (damager == null) { - event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers); + event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions); } else if (entity instanceof EntityEnderDragon && ((EntityEnderDragon) entity).bC == damager) { - event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers); + event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions); } else { if (damager instanceof org.bukkit.entity.TNTPrimed) { damageCause = DamageCause.BLOCK_EXPLOSION; } else { damageCause = DamageCause.ENTITY_EXPLOSION; } - event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers); + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions); } callEvent(event); @@ -443,15 +443,15 @@ public class CraftEventFactory { cause = DamageCause.THORNS; } - return callEntityDamageEvent(damager, entity, cause, modifiers); + return callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions); } else if (source == DamageSource.OUT_OF_WORLD) { - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers)); + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions)); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } return event; } else if (source == DamageSource.LAVA) { - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers)); + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -465,7 +465,7 @@ public class CraftEventFactory { } else { throw new RuntimeException("Unhandled entity damage"); } - EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers)); + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions)); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -483,7 +483,7 @@ public class CraftEventFactory { } else { throw new RuntimeException("Unhandled entity damage"); } - EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers)); + EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions)); if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } @@ -512,22 +512,22 @@ public class CraftEventFactory { } else if (source == DamageSource.FALL) { cause = DamageCause.FALL; } else if (source == DamageSource.GENERIC) { - return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers); + return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers, modifierFunctions); } if (cause != null) { - return callEntityDamageEvent(null, entity, cause, modifiers); + return callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions); } throw new RuntimeException("Unhandled entity damage"); } - private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers) { + private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions) { EntityDamageEvent event; if (damager != null) { - event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers); + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); } else { - event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers); + event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); } callEvent(event); @@ -539,20 +539,30 @@ public class CraftEventFactory { return event; } - public static EntityDamageEvent handleLivingEntityDamageEvent(Entity damagee, DamageSource source, double rawDamage, double hardHatModifier, double blockingModifier, double armorModifier, double resistanceModifier, double magicModifier, double absorptionModifier) { - Map modifiers = new HashMap(); + private static final Function ZERO = Functions.constant(-0.0); + + public static EntityDamageEvent handleLivingEntityDamageEvent(Entity damagee, DamageSource source, double rawDamage, double hardHatModifier, double blockingModifier, double armorModifier, double resistanceModifier, double magicModifier, double absorptionModifier, Function hardHat, Function blocking, Function armor, Function resistance, Function magic, Function absorption) { + Map modifiers = new EnumMap(DamageModifier.class); + Map> modifierFunctions = new EnumMap>(DamageModifier.class); modifiers.put(DamageModifier.BASE, rawDamage); + modifierFunctions.put(DamageModifier.BASE, ZERO); if (source == DamageSource.FALLING_BLOCK || source == DamageSource.ANVIL) { modifiers.put(DamageModifier.HARD_HAT, hardHatModifier); + modifierFunctions.put(DamageModifier.HARD_HAT, hardHat); } if (damagee instanceof EntityHuman) { modifiers.put(DamageModifier.BLOCKING, blockingModifier); + modifierFunctions.put(DamageModifier.BLOCKING, blocking); } modifiers.put(DamageModifier.ARMOR, armorModifier); + modifierFunctions.put(DamageModifier.ARMOR, armor); modifiers.put(DamageModifier.RESISTANCE, resistanceModifier); + modifierFunctions.put(DamageModifier.RESISTANCE, resistance); modifiers.put(DamageModifier.MAGIC, magicModifier); + modifierFunctions.put(DamageModifier.MAGIC, magic); modifiers.put(DamageModifier.ABSORPTION, absorptionModifier); - return handleEntityDamageEvent(damagee, source, new EnumMap(modifiers)); + modifierFunctions.put(DamageModifier.ABSORPTION, absorption); + return handleEntityDamageEvent(damagee, source, modifiers, modifierFunctions); } // Non-Living Entities such as EntityEnderCrystal, EntityItemFrame, and EntityFireball need to call this @@ -560,7 +570,7 @@ public class CraftEventFactory { if (entity instanceof EntityEnderCrystal && !(source instanceof EntityDamageSource)) { return false; } - EntityDamageEvent event = handleEntityDamageEvent(entity, source, new EnumMap(ImmutableMap.of(DamageModifier.BASE, (double) damage))); + EntityDamageEvent event = handleEntityDamageEvent(entity, source, new EnumMap(ImmutableMap.of(DamageModifier.BASE, (double) damage)), null); if (event == null) { return false; }