diff --git a/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageByEntityEvent.java b/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageByEntityEvent.java index 2dfcbd138..4d43ed3f1 100644 --- a/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageByEntityEvent.java +++ b/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageByEntityEvent.java @@ -1,5 +1,7 @@ package com.gmail.nossr50.events.fake; +import java.util.Map; + import org.bukkit.entity.Entity; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -7,6 +9,11 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; * Called when mcMMO applies damage from an entity due to special abilities. */ public class FakeEntityDamageByEntityEvent extends EntityDamageByEntityEvent { + public FakeEntityDamageByEntityEvent(Entity damager, Entity damagee, DamageCause cause, final Map modifiers) { + super(damager, damagee, cause, modifiers); + } + + @Deprecated public FakeEntityDamageByEntityEvent(Entity damager, Entity damagee, DamageCause cause, double damage) { super(damager, damagee, cause, damage); } diff --git a/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageEvent.java b/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageEvent.java index 20a2dd0d8..233e15840 100644 --- a/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageEvent.java +++ b/src/main/java/com/gmail/nossr50/events/fake/FakeEntityDamageEvent.java @@ -1,5 +1,7 @@ package com.gmail.nossr50.events.fake; +import java.util.Map; + import org.bukkit.entity.Entity; import org.bukkit.event.entity.EntityDamageEvent; @@ -7,6 +9,11 @@ import org.bukkit.event.entity.EntityDamageEvent; * Called when mcMMO applies damage due to special abilities. */ public class FakeEntityDamageEvent extends EntityDamageEvent { + public FakeEntityDamageEvent(Entity damagee, DamageCause cause, final Map modifiers) { + super(damagee, cause, modifiers); + } + + @Deprecated public FakeEntityDamageEvent(Entity damagee, DamageCause cause, double damage) { super(damagee, cause, damage); } diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index 070a845bb..e02bbfe50 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -147,7 +147,7 @@ public class EntityListener implements Listener { return; } - double damage = event.getDamage(); + double damage = event.getFinalDamage(); if (damage <= 0) { return; @@ -211,7 +211,7 @@ public class EntityListener implements Listener { } CombatUtils.processCombatAttack(event, attacker, target); - CombatUtils.handleHealthbars(attacker, target, event.getDamage()); + CombatUtils.handleHealthbars(attacker, target, event.getFinalDamage()); } /** @@ -225,7 +225,7 @@ public class EntityListener implements Listener { return; } - double damage = event.getDamage(); + double damage = event.getFinalDamage(); if (damage <= 0) { return; @@ -276,7 +276,7 @@ public class EntityListener implements Listener { if (acrobaticsManager.canRoll()) { event.setDamage(acrobaticsManager.rollCheck(event.getDamage())); - if (event.getDamage() == 0) { + if (event.getFinalDamage() == 0) { event.setCancelled(true); return; } @@ -289,7 +289,7 @@ public class EntityListener implements Listener { if (miningManager.canUseDemolitionsExpertise()) { event.setDamage(miningManager.processDemolitionsExpertise(event.getDamage())); - if (event.getDamage() == 0) { + if (event.getFinalDamage() == 0) { event.setCancelled(true); return; } @@ -300,7 +300,7 @@ public class EntityListener implements Listener { break; } - if (event.getDamage() >= 1) { + if (event.getFinalDamage() >= 1) { mcMMOPlayer.actualizeRecentlyHurt(); } } @@ -334,7 +334,7 @@ public class EntityListener implements Listener { if (tamingManager.canUseThickFur()) { event.setDamage(Taming.processThickFur(wolf, event.getDamage())); - if (event.getDamage() == 0) { + if (event.getFinalDamage() == 0) { event.setCancelled(true); } } @@ -360,7 +360,7 @@ public class EntityListener implements Listener { if (tamingManager.canUseShockProof()) { event.setDamage(Taming.processShockProof(wolf, event.getDamage())); - if (event.getDamage() == 0) { + if (event.getFinalDamage() == 0) { event.setCancelled(true); } } diff --git a/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java b/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java index e1deb42ac..769028708 100644 --- a/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java +++ b/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java @@ -1,8 +1,11 @@ package com.gmail.nossr50.skills.swords; +import java.util.Map; + import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.datatypes.player.McMMOPlayer; @@ -96,8 +99,8 @@ public class SwordsManager extends SkillManager { * @param target The {@link LivingEntity} being affected by the ability * @param damage The amount of damage initially dealt by the event */ - public void serratedStrikes(LivingEntity target, double damage) { - CombatUtils.applyAbilityAoE(getPlayer(), target, damage / Swords.serratedStrikesModifier, skill); + public void serratedStrikes(LivingEntity target, double damage, Map modifiers) { + CombatUtils.applyAbilityAoE(getPlayer(), target, damage / Swords.serratedStrikesModifier, modifiers, skill); BleedTimerTask.add(target, Swords.serratedStrikesBleedTicks); } } diff --git a/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java b/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java index 525a64bf2..340bf378a 100644 --- a/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java +++ b/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java @@ -1,10 +1,13 @@ package com.gmail.nossr50.skills.unarmed; +import java.util.Map; + import org.bukkit.Material; import org.bukkit.block.BlockState; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; import org.bukkit.material.SmoothBrick; @@ -120,10 +123,10 @@ public class UnarmedManager extends SkillManager { * @param target The {@link LivingEntity} being affected by the ability * @param damage The amount of damage initially dealt by the event */ - public double berserkDamage(LivingEntity target, double damage) { + public double berserkDamage(LivingEntity target, double damage, Map modifiers) { damage = (damage * Unarmed.berserkDamageModifier) - damage; - return CombatUtils.callFakeDamageEvent(getPlayer(), target, damage); + return CombatUtils.callFakeDamageEvent(getPlayer(), target, damage, modifiers); } /** @@ -131,10 +134,10 @@ public class UnarmedManager extends SkillManager { * * @param target The {@link LivingEntity} being affected by the ability */ - public double ironArm(LivingEntity target) { + public double ironArm(LivingEntity target, Map modifiers) { double unarmedBonus = Math.min(Unarmed.ironArmMinBonusDamage + (getSkillLevel() / Unarmed.ironArmIncreaseLevel), Unarmed.ironArmMaxBonusDamage); - return CombatUtils.callFakeDamageEvent(getPlayer(), target, unarmedBonus); + return CombatUtils.callFakeDamageEvent(getPlayer(), target, unarmedBonus, modifiers); } /** diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java index ceba8a969..4de417f79 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -1,5 +1,9 @@ package com.gmail.nossr50.util.skills; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + import org.bukkit.Material; import org.bukkit.entity.AnimalTamer; import org.bukkit.entity.Animals; @@ -15,6 +19,7 @@ import org.bukkit.entity.Wolf; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; import org.bukkit.inventory.ItemStack; import org.bukkit.projectiles.ProjectileSource; @@ -44,12 +49,16 @@ import com.gmail.nossr50.util.MobHealthbarUtils; import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.player.UserManager; +import com.google.common.collect.ImmutableMap; + public final class CombatUtils { private CombatUtils() {} - private static void processSwordCombat(LivingEntity target, Player player, double damage) { + private static void processSwordCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event) { McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); SwordsManager swordsManager = mcMMOPlayer.getSwordsManager(); + double initialDamage = event.getDamage(); + Map modifiers = getModifiers(event); if (swordsManager.canActivateAbility()) { mcMMOPlayer.checkAbilityActivation(SkillType.SWORDS); @@ -60,7 +69,7 @@ public final class CombatUtils { } if (swordsManager.canUseSerratedStrike()) { - swordsManager.serratedStrikes(target, damage); + swordsManager.serratedStrikes(target, initialDamage, modifiers); } startGainXp(mcMMOPlayer, target, SkillType.SWORDS); @@ -103,6 +112,7 @@ public final class CombatUtils { private static void processUnarmedCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event) { double initialDamage = event.getDamage(); double finalDamage = initialDamage; + Map modifiers = getModifiers(event); McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager(); @@ -112,11 +122,11 @@ public final class CombatUtils { } if (unarmedManager.canUseIronArm()) { - finalDamage += unarmedManager.ironArm(target); + finalDamage += unarmedManager.ironArm(target, modifiers); } if (unarmedManager.canUseBerserk()) { - finalDamage += unarmedManager.berserkDamage(target, initialDamage); + finalDamage += unarmedManager.berserkDamage(target, initialDamage, modifiers); } if (unarmedManager.canDisarm(target)) { @@ -319,10 +329,27 @@ public final class CombatUtils { * @param damage Amount of damage to attempt to do * @param attacker Player to pass to event as damager */ + @Deprecated public static void dealDamage(LivingEntity target, double damage, LivingEntity attacker) { dealDamage(target, damage, DamageCause.ENTITY_ATTACK, attacker); } + /** + * Attempt to damage target for value dmg with reason ENTITY_ATTACK with damager attacker + * + * @param target LivingEntity which to attempt to damage + * @param damage Amount of damage to attempt to do + * @param attacker Player to pass to event as damager + */ + public static void dealDamage(LivingEntity target, double damage, Map modifiers, LivingEntity attacker) { + if (target.isDead()) { + return; + } + + // Aren't we applying the damage twice???? + target.damage(callFakeDamageEvent(attacker, target, damage, modifiers)); + } + /** * Attempt to damage target for value dmg with reason ENTITY_ATTACK with damager attacker * @@ -346,7 +373,7 @@ public final class CombatUtils { * @param damage The initial damage amount * @param type The type of skill being used */ - public static void applyAbilityAoE(Player attacker, LivingEntity target, double damage, SkillType type) { + public static void applyAbilityAoE(Player attacker, LivingEntity target, double damage, Map modifiers, SkillType type) { int numberOfTargets = getTier(attacker.getItemInHand()); // The higher the weapon tier, the more targets you hit double damageAmount = Math.max(damage, 1); @@ -382,7 +409,7 @@ public final class CombatUtils { break; } - dealDamage(livingEntity, damageAmount, attacker); + dealDamage(livingEntity, damageAmount, modifiers, attacker); numberOfTargets--; } } @@ -567,23 +594,63 @@ public final class CombatUtils { return false; } + @Deprecated public static double callFakeDamageEvent(Entity attacker, Entity target, double damage) { - return callFakeDamageEvent(attacker, target, DamageCause.ENTITY_ATTACK, damage); + return callFakeDamageEvent(attacker, target, DamageCause.ENTITY_ATTACK, new EnumMap(ImmutableMap.of(DamageModifier.BASE, damage))); } - public static double callFakeDamageEvent(Entity attacker, Entity target, DamageCause cause, double damage) { + @Deprecated + public static double callFakeDamageEvent(Entity attacker, Entity target, DamageCause damageCause, double damage) { + return callFakeDamageEvent(attacker, target, damageCause, new EnumMap(ImmutableMap.of(DamageModifier.BASE, damage))); + } + + public static double callFakeDamageEvent(Entity attacker, Entity target, Map modifiers) { + return callFakeDamageEvent(attacker, target, DamageCause.ENTITY_ATTACK, modifiers); + } + + public static double callFakeDamageEvent(Entity attacker, Entity target, double damage, Map modifiers) { + return callFakeDamageEvent(attacker, target, DamageCause.ENTITY_ATTACK, scaleModifiers(damage, modifiers)); + } + + public static double callFakeDamageEvent(Entity attacker, Entity target, DamageCause cause, Map modifiers) { + double finalDamage = 0; + if (Config.getInstance().getEventCallbackEnabled()) { - EntityDamageEvent damageEvent = attacker == null ? new FakeEntityDamageEvent(target, cause, damage) : new FakeEntityDamageByEntityEvent(attacker, target, cause, damage); + EntityDamageEvent damageEvent = attacker == null ? new FakeEntityDamageEvent(target, cause, modifiers) : new FakeEntityDamageByEntityEvent(attacker, target, cause, modifiers); mcMMO.p.getServer().getPluginManager().callEvent(damageEvent); if (damageEvent.isCancelled()) { return 0; } - damage = damageEvent.getDamage(); + finalDamage = damageEvent.getFinalDamage(); } - return damage; + return finalDamage; + } + + public static Map getModifiers(EntityDamageEvent event) { + Map modifiers = new HashMap(); + for (DamageModifier modifier : DamageModifier.values()) { + modifiers.put(modifier, event.getDamage(modifier)); + } + + return modifiers; + } + + public static Map scaleModifiers(double damage, Map modifiers) { + Map scaledModifiers = new HashMap(); + + for (DamageModifier modifier : DamageModifier.values()) { + if (modifier == DamageModifier.BASE) { + modifiers.put(modifier, damage); + continue; + } + + scaledModifiers.put(modifier, damage * modifiers.get(modifier)); + } + + return scaledModifiers; } /**