diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 02519e375..9254468ca 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -328,7 +328,7 @@ enum AuraType SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells SPELL_AURA_284, SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR = 285, - SPELL_AURA_286, + SPELL_AURA_ABILITY_PERIODIC_CRIT = 286, SPELL_AURA_DEFLECT_SPELLS, SPELL_AURA_288, SPELL_AURA_289, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index a1cb7643d..4048fb8a0 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -336,7 +336,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus &Aura::HandleUnused, //284 not used by any spells (3.08a) &Aura::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage - &Aura::HandleUnused, //286 not used by any spells (3.08a) + &Aura::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in Aura::IsCritFromAbilityAura called from AuraEffect::PeriodicTick &Aura::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult &Aura::HandleUnused, //288 not used by any spells (3.09) except 1 test spell. &Aura::HandleUnused, //289 unused @@ -5896,6 +5896,9 @@ void Aura::PeriodicTick() else pdamage = uint32(m_target->GetMaxHealth()*amount/100); + // This method can modify pdamage + bool isCrit = IsCritFromAbilityAura(pCaster, pdamage); + // As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit // Reduce dot damage from resilience for players if (m_target->GetTypeId() == TYPEID_PLAYER) @@ -5908,7 +5911,7 @@ void Aura::PeriodicTick() pCaster->DealDamageMods(m_target, pdamage, &absorb); - SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, absorb, resist, 0.0f); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, absorb, resist, 0.0f, isCrit); m_target->SendPeriodicAuraLog(&pInfo); Unit* target = m_target; // aura can be deleted in DealDamage @@ -6030,10 +6033,13 @@ void Aura::PeriodicTick() pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount()); + // This method can modify pdamage + bool isCrit = IsCritFromAbilityAura(pCaster, pdamage); + sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u", GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); - SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f, isCrit); m_target->SendPeriodicAuraLog(&pInfo); int32 gain = m_target->ModifyHealth(pdamage); @@ -6921,3 +6927,19 @@ void Aura::HandleAuraSafeFall( bool Apply, bool Real ) if(Apply && Real && GetId() == 32474 && m_target->GetTypeId() == TYPEID_PLAYER) ((Player*)m_target)->ActivateTaxiPathTo(506, GetId()); } + +bool Aura::IsCritFromAbilityAura(Unit* caster, uint32& damage) +{ + Unit::AuraList const& auras = caster->GetAurasByType(SPELL_AURA_ABILITY_PERIODIC_CRIT); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + if (!(*itr)->isAffectedOnSpell(m_spellProto)) + continue; + + if (caster->isSpellCrit(m_target, m_spellProto, GetSpellSchoolMask(m_spellProto))) + damage = caster->SpellCriticalDamageBonus(m_spellProto, damage, m_target); + + return true; + } + return false; +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 1588992d3..f0767e299 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -325,6 +325,8 @@ class MANGOS_DLL_SPEC Aura protected: Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL); + bool IsCritFromAbilityAura(Unit* caster, uint32& damage); + Modifier m_modifier; SpellModifier *m_spellmod; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 7ca85987f..2d3cd341c 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4278,13 +4278,13 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo *pInfo) data << uint32(GetSpellSchoolMask(aura->GetSpellProto())); data << uint32(pInfo->absorb); // absorb data << uint32(pInfo->resist); // resist - data << uint8(0); // new 3.1.2 + data << uint8(pInfo->critical ? 1 : 0); // new 3.1.2 critical flag break; case SPELL_AURA_PERIODIC_HEAL: case SPELL_AURA_OBS_MOD_HEALTH: data << uint32(pInfo->damage); // damage data << uint32(pInfo->overDamage); // overheal? - data << uint8(0); // new 3.1.2 + data << uint8(pInfo->critical ? 1 : 0); // new 3.1.2 critical flag break; case SPELL_AURA_OBS_MOD_MANA: case SPELL_AURA_PERIODIC_ENERGIZE: diff --git a/src/game/Unit.h b/src/game/Unit.h index fe35362b1..faefbefcd 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -686,7 +686,7 @@ struct SpellNonMeleeDamage{ struct SpellPeriodicAuraLogInfo { - SpellPeriodicAuraLogInfo(Aura *_aura, uint32 _damage, uint32 _overDamage, uint32 _absorb, uint32 _resist, float _multiplier) + SpellPeriodicAuraLogInfo(Aura *_aura, uint32 _damage, uint32 _overDamage, uint32 _absorb, uint32 _resist, float _multiplier, bool _critical = false) : aura(_aura), damage(_damage), overDamage(_overDamage), absorb(_absorb), resist(_resist), multiplier(_multiplier) {} Aura *aura; @@ -695,6 +695,7 @@ struct SpellPeriodicAuraLogInfo uint32 resist; uint32 overDamage; // overkill/overheal float multiplier; + bool critical; }; uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 534b8c87b..cd2e6680c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8138" + #define REVISION_NR "8139" #endif // __REVISION_NR_H__