From 5ea2c493e8f1b92ed0731a27a5c5a2803bf0f2ba Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sat, 24 Aug 2019 17:40:27 +0100 Subject: [PATCH] Don't process mcmmo damage for invuln (#4028) --- .../nossr50/listeners/EntityListener.java | 25 ++++---------- .../nossr50/util/skills/CombatUtils.java | 34 ++++++++----------- 2 files changed, 21 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index 1ee539eed..d837e2de2 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -252,24 +252,6 @@ public class EntityListener implements Listener { Bukkit.broadcastMessage(""); }*/ - @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) - public void onEntityDamageLowest(EntityDamageByEntityEvent event) - { - Entity defender = event.getEntity(); - - if(defender.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() > 0) - { - if(defender instanceof Player) - { - LivingEntity defLive = (LivingEntity) defender; - defLive.setHealth(Math.max(0, (defLive.getHealth() - event.getFinalDamage()))); - event.setCancelled(true); - } - - return; - } - } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onEntityCombustByEntityEvent(EntityCombustByEntityEvent event) { //Prevent players from setting fire to each other if they are in the same party @@ -330,6 +312,13 @@ public class EntityListener implements Listener { return; } + // Don't process this event for marked entities, for players this is handled above, + // However, for entities, we do not wanna cancel this event to allow plugins to observe changes + // properly + if (defender.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() > 0) { + return; + } + if (event.getEntity() instanceof ArmorStand) { return; } 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 3f8b96c8b..201ac00ec 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -558,21 +558,19 @@ public final class CombatUtils { return; } - double incDmg = getFakeDamageFinalResult(attacker, target, DamageCause.ENTITY_ATTACK, damage); - - double newHealth = Math.max(0, target.getHealth() - incDmg); - - if(newHealth == 0) - { - // TODO: This is horrible, but there is no cleaner way to do this without potentially breaking existing code right now - boolean wasMetaSet = target.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() != 0; - target.setMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.metadataValue); - target.damage(9999, attacker); - if (!wasMetaSet) - target.removeMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.p); - } - else - target.setHealth(newHealth); + // TODO: This is horrible, but there is no cleaner way to do this without potentially breaking existing code right now + // calling damage here is a double edged sword: On one hand, without a call, plugins won't see this properly when the entity dies, + // potentially mis-attributing the death cause; calling a fake event would partially fix this, but this and setting the last damage + // cause do have issues around plugin observability. This is not a perfect solution, but it appears to be the best one here + // We also set no damage ticks to 0, to ensure that damage is applied for this case, and reset it back to the original value + boolean wasMetaSet = target.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() != 0; + target.setMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.metadataValue); + int noDamageTicks = target.getNoDamageTicks(); + target.setNoDamageTicks(0); + target.damage(damage, attacker); + target.setNoDamageTicks(noDamageTicks); + if (!wasMetaSet) + target.removeMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.p); } public static void dealNoInvulnerabilityTickDamageRupture(LivingEntity target, double damage, Entity attacker, int toolTier) { @@ -580,11 +578,7 @@ public final class CombatUtils { return; } - // This is horrible, but there is no cleaner way to do this without potentially breaking existing code - boolean wasMetaSet = target.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() != 0; - target.setMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.metadataValue); - target.damage(damage, attacker); - if (!wasMetaSet) target.removeMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.p); + dealNoInvulnerabilityTickDamage(target, damage, attacker); // //IFrame storage //// int noDamageTicks = target.getNoDamageTicks();