diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 0249cbb6c..341a0f4d9 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -765,7 +765,7 @@ void Unit::DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb) } } -uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, bool /*allowGM*/) +uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss, bool /*allowGM*/, Spell const* damageSpell /*= nullptr*/) { // Xinef: initialize damage done for rage calculations // Xinef: its rare to modify damage in hooks, however training dummy's sets damage to 0 @@ -1026,24 +1026,33 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage { if (victim != attacker && victim->GetTypeId() == TYPEID_PLAYER) // does not support creature push_back { - if (damagetype != DOT) + if (damagetype != DOT && !(damageSpell && damageSpell->m_targets.HasDstChannel())) + { if (Spell* spell = victim->m_currentSpells[CURRENT_GENERIC_SPELL]) + { if (spell->getState() == SPELL_STATE_PREPARING) { uint32 interruptFlags = spell->m_spellInfo->InterruptFlags; if (interruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) + { victim->InterruptNonMeleeSpells(false); + } else if (interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK) + { spell->Delayed(); + } } - - if (Spell* spell = victim->m_currentSpells[CURRENT_CHANNELED_SPELL]) - if (spell->getState() == SPELL_STATE_CASTING) - { - uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags; - if (((channelInterruptFlags & CHANNEL_FLAG_DELAY) != 0) && (damagetype != DOT)) - spell->DelayedChannel(); } + + if (Spell* spell = victim->m_currentSpells[CURRENT_CHANNELED_SPELL]) + if (spell->getState() == SPELL_STATE_CASTING) + { + if ((spell->m_spellInfo->ChannelInterruptFlags & CHANNEL_FLAG_DELAY) != 0) + { + spell->DelayedChannel(); + } + } + } } } @@ -1338,7 +1347,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama damageInfo->damage = 0; } -void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss) +void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell /*= nullptr*/) { if (damageInfo == 0) return; @@ -1360,7 +1369,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss) // Call default DealDamage CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, BASE_ATTACK, MELEE_HIT_NORMAL); - Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss); + Unit::DealDamage(this, victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss, false, spell); } // TODO for melee need create structure as in diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f63dd4685..f8dd29b6b 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1652,7 +1652,7 @@ public: uint16 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } static void DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb); - static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false); + static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false, Spell const* spell = nullptr); static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr); static int32 DealHeal(Unit* healer, Unit* victim, uint32 addhealth); @@ -1672,7 +1672,7 @@ public: void HandleProcExtraAttackFor(Unit* victim); void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false); - void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss); + void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell = nullptr); // player or player's pet resilience (-1%) [[nodiscard]] float GetMeleeCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_MELEE); } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8bd2922b4..4d8c3d9a9 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2663,7 +2663,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) procEx |= createProcExtendMask(&damageInfo, missInfo); procVictim |= PROC_FLAG_TAKEN_DAMAGE; - caster->DealSpellDamage(&damageInfo, true); + caster->DealSpellDamage(&damageInfo, true, this); // do procs after damage, eg healing effects // no need to check if target is alive, done in procdamageandspell