diff --git a/core/src/main/java/com/nisovin/magicspells/events/SpellApplyDamageEvent.java b/core/src/main/java/com/nisovin/magicspells/events/SpellApplyDamageEvent.java index 036be9bd9..8c13b7530 100644 --- a/core/src/main/java/com/nisovin/magicspells/events/SpellApplyDamageEvent.java +++ b/core/src/main/java/com/nisovin/magicspells/events/SpellApplyDamageEvent.java @@ -22,6 +22,10 @@ public SpellApplyDamageEvent(Spell spell, LivingEntity caster, LivingEntity targ this(spell, caster, target, damage, DamageType.GENERIC, cause, spellDamageType); } + public SpellApplyDamageEvent(Spell spell, LivingEntity caster, LivingEntity target, double damage, String spellDamageType) { + this(spell, caster, target, damage, DamageType.GENERIC, spellDamageType); + } + public SpellApplyDamageEvent(Spell spell, LivingEntity caster, LivingEntity target, double damage, DamageType damageType, String spellDamageType) { this(spell, caster, target, damage, damageType, DamageCause.ENTITY_ATTACK, spellDamageType); } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/instant/ThrowBlockSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/instant/ThrowBlockSpell.java index 179767ff3..3a6de2df6 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/instant/ThrowBlockSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/instant/ThrowBlockSpell.java @@ -30,6 +30,7 @@ import com.nisovin.magicspells.util.config.FunctionData; import com.nisovin.magicspells.spelleffects.EffectPosition; import com.nisovin.magicspells.spells.TargetedLocationSpell; +import com.nisovin.magicspells.events.SpellApplyDamageEvent; public class ThrowBlockSpell extends InstantSpell implements TargetedLocationSpell { @@ -347,7 +348,6 @@ private void onDamage(EntityDamageByEntityEvent event) { } subData = targetEvent.getSpellData(); - target = subData.target(); } double damage = event.getDamage(); @@ -358,7 +358,9 @@ private void onDamage(EntityDamageByEntityEvent event) { return; } - event.setDamage(damage); + SpellApplyDamageEvent spellEvent = new SpellApplyDamageEvent(info.getSpell(), info.data.caster(), info.data.target(), damage, DamageCause.ENTITY_ATTACK, ""); + spellEvent.callEvent(); + event.setDamage(spellEvent.getFinalDamage()); if (spell.spellOnLand != null && !info.spellActivated) { spell.spellOnLand.subcast(subData.retarget(null, block.getLocation())); diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/CombustSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/CombustSpell.java index d4d519d10..651a23704 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/CombustSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/CombustSpell.java @@ -13,7 +13,6 @@ import com.nisovin.magicspells.util.*; import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.spells.TargetedSpell; -import com.nisovin.magicspells.util.compat.EventUtil; import com.nisovin.magicspells.util.config.ConfigData; import com.nisovin.magicspells.spells.TargetedEntitySpell; import com.nisovin.magicspells.events.SpellApplyDamageEvent; @@ -95,8 +94,9 @@ public void onEntityDamage(EntityDamageEvent event) { if (powerAffectsFireTickDamage.get(data.spellData)) fireTickDamage *= data.spellData.power(); } - EventUtil.call(new SpellApplyDamageEvent(this, data.spellData.caster(), target, fireTickDamage, DamageCause.FIRE_TICK, "")); - event.setDamage(fireTickDamage); + SpellApplyDamageEvent spellEvent = new SpellApplyDamageEvent(this, data.spellData.caster(), target, fireTickDamage, DamageCause.FIRE_TICK, ""); + spellEvent.callEvent(); + event.setDamage(spellEvent.getFinalDamage()); if (data.preventImmunity) MagicSpells.scheduleDelayedTask(() -> target.setNoDamageTicks(0), 0); } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/DotSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/DotSpell.java index 47163e296..76eb6ffb6 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/DotSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/DotSpell.java @@ -14,7 +14,6 @@ import com.nisovin.magicspells.util.*; import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.spells.TargetedSpell; -import com.nisovin.magicspells.util.compat.EventUtil; import com.nisovin.magicspells.util.config.ConfigData; import com.nisovin.magicspells.spells.TargetedEntitySpell; import com.nisovin.magicspells.spelleffects.EffectPosition; @@ -180,18 +179,18 @@ public void run() { data.target().setLastDamageCause(event); } + if (ignoreArmor && checkPlugins && data.hasCaster()) { + EntityDamageEvent damageEvent = createFakeDamageEvent(data.caster(), data.target(), DamageCause.ENTITY_ATTACK, localDamage); + if (!damageEvent.callEvent()) return; + + if (!avoidDamageModification) localDamage = damageEvent.getDamage(); + } + SpellApplyDamageEvent event = new SpellApplyDamageEvent(DotSpell.this, data.caster(), data.target(), localDamage, damageType, spellDamageType); - EventUtil.call(event); + event.callEvent(); localDamage = event.getFinalDamage(); if (ignoreArmor) { - if (checkPlugins && data.hasCaster()) { - EntityDamageEvent damageEvent = createFakeDamageEvent(data.caster(), data.target(), DamageCause.ENTITY_ATTACK, localDamage); - if (!damageEvent.callEvent()) return; - - if (!avoidDamageModification) localDamage = event.getDamage(); - } - double maxHealth = Util.getMaxHealth(data.target()); double health = data.target().getHealth(); diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/FireballSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/FireballSpell.java index 5ae0c6475..68420bb86 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/FireballSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/FireballSpell.java @@ -27,6 +27,7 @@ import com.nisovin.magicspells.spells.TargetedSpell; import com.nisovin.magicspells.util.config.ConfigData; import com.nisovin.magicspells.spelleffects.EffectPosition; +import com.nisovin.magicspells.events.SpellApplyDamageEvent; import com.nisovin.magicspells.spells.TargetedEntityFromLocationSpell; public class FireballSpell extends TargetedSpell implements TargetedEntityFromLocationSpell { @@ -201,6 +202,10 @@ public void onExplosionPrime(ExplosionPrimeEvent event) { double noExplosionDamage = this.noExplosionDamage.get(data); if (powerAffectsNoExplosionDamage.get(data)) noExplosionDamage *= data.power(); + SpellApplyDamageEvent spellEvent = new SpellApplyDamageEvent(this, data.caster(), data.target(), noExplosionDamage, ""); + spellEvent.callEvent(); + noExplosionDamage = spellEvent.getFinalDamage(); + target.damage(noExplosionDamage, caster); } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/ForcetossSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/ForcetossSpell.java index db4e55589..c38b814b8 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/ForcetossSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/ForcetossSpell.java @@ -7,18 +7,19 @@ import com.nisovin.magicspells.spells.TargetedSpell; import com.nisovin.magicspells.util.config.ConfigData; import com.nisovin.magicspells.spells.TargetedEntitySpell; +import com.nisovin.magicspells.events.SpellApplyDamageEvent; public class ForcetossSpell extends TargetedSpell implements TargetedEntitySpell { - private ConfigData damage; + private final ConfigData damage; - private ConfigData vForce; - private ConfigData hForce; - private ConfigData rotation; + private final ConfigData vForce; + private final ConfigData hForce; + private final ConfigData rotation; - private ConfigData powerAffectsForce; - private ConfigData powerAffectsDamage; - private ConfigData addVelocityInstead; + private final ConfigData powerAffectsForce; + private final ConfigData powerAffectsDamage; + private final ConfigData addVelocityInstead; public ForcetossSpell(MagicConfig config, String spellName) { super(config, spellName); @@ -45,14 +46,18 @@ public CastResult cast(SpellData data) { @Override public CastResult castAtEntity(SpellData data) { if (!data.hasCaster()) return new CastResult(PostCastAction.ALREADY_HANDLED, data); - if (!data.caster().getWorld().equals(data.target().getWorld())) return noTarget(data); LivingEntity caster = data.caster(); LivingEntity target = data.target(); + if (!caster.getWorld().equals(target.getWorld())) return noTarget(data); double damage = this.damage.get(data); if (powerAffectsDamage.get(data)) damage *= data.power(); + SpellApplyDamageEvent event = new SpellApplyDamageEvent(this, caster, target, damage, ""); + event.callEvent(); + damage = event.getFinalDamage(); + if (damage > 0) target.damage(damage, caster); Vector v; diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/GeyserSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/GeyserSpell.java index 04c8f153e..fb65168b7 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/GeyserSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/GeyserSpell.java @@ -18,10 +18,11 @@ import com.nisovin.magicspells.spells.TargetedSpell; import com.nisovin.magicspells.util.config.ConfigData; import com.nisovin.magicspells.spells.TargetedEntitySpell; +import com.nisovin.magicspells.events.SpellApplyDamageEvent; public class GeyserSpell extends TargetedSpell implements TargetedEntitySpell { - private ConfigData geyserType; + private final ConfigData geyserType; private final ConfigData damage; private final ConfigData velocity; @@ -63,24 +64,31 @@ public CastResult cast(SpellData data) { @Override public CastResult castAtEntity(SpellData data) { + LivingEntity caster = data.caster(); LivingEntity target = data.target(); double damage = this.damage.get(data); if (powerAffectsDamage.get(data)) damage *= data.power(); if (damage > 0) { - if (ignoreArmor.get(data)) { - if (data.hasCaster() && checkPlugins.get(data)) { - EntityDamageEvent event = createFakeDamageEvent(data.caster(), target, DamageCause.ENTITY_ATTACK, damage); - if (!event.callEvent()) return noTarget(data); + boolean ignoreArmor = this.ignoreArmor.get(data); - if (!avoidDamageModification.get(data)) damage = event.getDamage(); - } + if (ignoreArmor && data.hasCaster() && checkPlugins.get(data)) { + EntityDamageEvent event = createFakeDamageEvent(caster, target, DamageCause.ENTITY_ATTACK, damage); + if (!event.callEvent()) return noTarget(data); + if (!avoidDamageModification.get(data)) damage = event.getDamage(); + } + + SpellApplyDamageEvent spellEvent = new SpellApplyDamageEvent(this, caster, target, damage, ""); + spellEvent.callEvent(); + damage = spellEvent.getFinalDamage(); + + if (ignoreArmor) { target.setHealth(Math.clamp(target.getHealth() - damage, 0, Util.getMaxHealth(target))); - Util.playHurtEffect(data.target(), data.caster()); + Util.playHurtEffect(target, caster); } else { - if (data.hasCaster()) target.damage(damage, data.caster()); + if (data.hasCaster()) target.damage(damage, caster); else target.damage(damage); } } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/LightningSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/LightningSpell.java index 4bbb71902..9823c4fb5 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/LightningSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/LightningSpell.java @@ -23,6 +23,7 @@ import com.nisovin.magicspells.spells.TargetedSpell; import com.nisovin.magicspells.util.config.ConfigData; import com.nisovin.magicspells.spells.TargetedLocationSpell; +import com.nisovin.magicspells.events.SpellApplyDamageEvent; public class LightningSpell extends TargetedSpell implements TargetedLocationSpell { @@ -82,8 +83,8 @@ public CastResult cast(SpellData data) { if (checkPlugins.get(data) && checkFakeDamageEvent(data.caster(), data.target())) return noTarget(data); - ChargeOption option = new ChargeOption(additionalDamage, chargeCreepers.get(data), zapPigs.get(data), transformEntities.get(data)); LightningStrike strike = data.target().getWorld().strikeLightning(data.target().getLocation()); + ChargeOption option = new ChargeOption(this, data.caster(), additionalDamage, chargeCreepers.get(data), zapPigs.get(data), transformEntities.get(data)); lightningListener.striking.put(strike.getUniqueId(), option); return new CastResult(PostCastAction.HANDLE_NORMALLY, data); @@ -104,8 +105,8 @@ public CastResult castAtLocation(SpellData data) { double additionalDamage = this.additionalDamage.get(data); if (powerAffectsAdditionalDamage.get(data)) additionalDamage *= data.power(); - ChargeOption option = new ChargeOption(additionalDamage, chargeCreepers.get(data), zapPigs.get(data), transformEntities.get(data)); LightningStrike strike = target.getWorld().strikeLightning(target); + ChargeOption option = new ChargeOption(this, data.caster(), additionalDamage, chargeCreepers.get(data), zapPigs.get(data), transformEntities.get(data)); lightningListener.striking.put(strike.getUniqueId(), option); } @@ -113,8 +114,7 @@ public CastResult castAtLocation(SpellData data) { return new CastResult(PostCastAction.HANDLE_NORMALLY, data); } - private record ChargeOption(double additionalDamage, boolean chargeCreeper, boolean changePig, boolean transformEntities) { - + private record ChargeOption(LightningSpell spell, LivingEntity caster, double additionalDamage, boolean chargeCreeper, boolean changePig, boolean transformEntities) { } private static class LightningListener implements Listener { @@ -130,9 +130,18 @@ public void onLightningDamage(EntityDamageByEntityEvent event) { if (source.getDamageType() != DamageType.LIGHTNING_BOLT) return; ChargeOption option = striking.get(strike.getUniqueId()); - if (option == null || option.additionalDamage <= 0) return; + if (option == null) return; + + double damage = event.getDamage(); + if (option.additionalDamage > 0) damage += option.additionalDamage; + + if (event.getEntity() instanceof LivingEntity target) { + SpellApplyDamageEvent spellEvent = new SpellApplyDamageEvent(option.spell(), option.caster(), target, damage, source.getDamageType(), ""); + spellEvent.callEvent(); + damage = spellEvent.getFinalDamage(); + } - event.setDamage(event.getDamage() + option.additionalDamage); + event.setDamage(damage); } @EventHandler diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/PainSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/PainSpell.java index 8e40510cc..d4a04bc0b 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/PainSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/PainSpell.java @@ -85,18 +85,20 @@ public CastResult castAtEntity(SpellData data) { data.target().setLastDamageCause(event); } + boolean ignoreArmor = this.ignoreArmor.get(data); + + if (ignoreArmor && checkPlugins && data.hasCaster()) { + EntityDamageEvent damageEvent = createFakeDamageEvent(data.caster(), data.target(), DamageCause.ENTITY_ATTACK, damage); + if (!damageEvent.callEvent()) return noTarget(data); + + if (!avoidDamageModification) damage = damageEvent.getDamage(); + } + SpellApplyDamageEvent event = new SpellApplyDamageEvent(this, data.caster(), data.target(), damage, damageType, spellDamageType); event.callEvent(); damage = event.getFinalDamage(); - if (ignoreArmor.get(data)) { - if (checkPlugins && data.hasCaster()) { - EntityDamageEvent damageEvent = createFakeDamageEvent(data.caster(), data.target(), DamageCause.ENTITY_ATTACK, damage); - if (!damageEvent.callEvent()) return noTarget(data); - - if (!avoidDamageModification) damage = event.getDamage(); - } - + if (ignoreArmor) { double maxHealth = Util.getMaxHealth(data.target()); double health = Math.min(data.target().getHealth(), maxHealth); @@ -106,13 +108,11 @@ public CastResult castAtEntity(SpellData data) { data.target().setHealth(health); data.target().setLastDamage(damage); Util.playHurtEffect(data.target(), data.caster()); - - playSpellEffects(data); - return new CastResult(PostCastAction.HANDLE_NORMALLY, data); } - - if (tryAvoidingAntiCheatPlugins.get(data)) data.target().damage(damage); - else data.target().damage(damage, data.caster()); + else { + if (tryAvoidingAntiCheatPlugins.get(data)) data.target().damage(damage); + else data.target().damage(damage, data.caster()); + } playSpellEffects(data); return new CastResult(PostCastAction.HANDLE_NORMALLY, data);