diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 4844d74d8..523324a60 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -5707,10 +5707,10 @@ void Aura::PeriodicTick() case 38772: { uint32 percent = - GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_DUMMY ? - pCaster->CalculateSpellDamage(GetSpellProto(),GetEffIndex()+1,GetSpellProto()->EffectBasePoints[GetEffIndex()+1],m_target) : + GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()] == SPELL_EFFECT_DUMMY ? + pCaster->CalculateSpellDamage(GetSpellProto(), GetEffIndex() + 1, GetSpellProto()->EffectBasePoints[GetEffIndex() + 1], m_target) : 100; - if(m_target->GetHealth()*100 >= m_target->GetMaxHealth()*percent ) + if(m_target->GetHealth() * 100 >= m_target->GetMaxHealth() * percent ) { m_target->RemoveAurasDueToSpell(GetId()); return; @@ -5751,18 +5751,18 @@ void Aura::PeriodicTick() if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) && GetSpellProto()->SpellIconID==544) { // 1..4 ticks, 1/2 from normal tick damage - if (m_duration>=((m_maxduration-m_modifier.periodictime)*2/3)) + if (m_duration >= ((m_maxduration-m_modifier.periodictime) * 2 / 3)) pdamage = pdamage/2; // 9..12 ticks, 3/2 from normal tick damage - else if(m_duration<((m_maxduration-m_modifier.periodictime)/3)) - pdamage += (pdamage+1)/2; // +1 prevent 0.5 damage possible lost at 1..4 ticks + else if(m_duration < ((m_maxduration-m_modifier.periodictime) / 3)) + pdamage += (pdamage + 1) / 2; // +1 prevent 0.5 damage possible lost at 1..4 ticks // 5..8 ticks have normal tick damage } } else pdamage = uint32(m_target->GetMaxHealth()*amount/100); - //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit + // 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) pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage); @@ -5772,28 +5772,18 @@ void Aura::PeriodicTick() sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u", GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb); - pCaster->DealDamageMods(m_target,pdamage,&absorb); + pCaster->DealDamageMods(m_target, pdamage, &absorb); - WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size - data.append(m_target->GetPackGUID()); - data.appendPackGUID(GetCasterGUID()); - data << uint32(GetId()); - data << uint32(1); - data << uint32(m_modifier.m_auraname); - data << (uint32)pdamage; - data << uint32(0); // overkill - data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x - data << (uint32)absorb; - data << (uint32)resist; - m_target->SendMessageToSet(&data, true); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, absorb, resist, 0.0f); + m_target->SendPeriodicAuraLog(&pInfo); Unit* target = m_target; // aura can be deleted in DealDamage SpellEntry const* spellProto = GetSpellProto(); // Set trigger flag - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; // | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT; - pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist); + pdamage = (pdamage <= absorb + resist) ? 0 : (pdamage - absorb - resist); if (pdamage) procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE; pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto); @@ -5835,7 +5825,7 @@ void Aura::PeriodicTick() pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetStackAmount()); - //As of 2.2 resilience reduces damage from DoT ticks as much as the chance to not be critically hit + // 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) pdamage-=((Player*)m_target)->GetDotDamageReduction(pdamage); @@ -5850,16 +5840,15 @@ void Aura::PeriodicTick() pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0); - Unit* target = m_target; // aura can be deleted in DealDamage SpellEntry const* spellProto = GetSpellProto(); float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1; int32 stackAmount = GetStackAmount(); // Set trigger flag - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; // | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT; - pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist); + pdamage = (pdamage <= absorb + resist) ? 0 : (pdamage-absorb-resist); if (pdamage) procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE; pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, PROC_EX_NORMAL_HIT, pdamage, BASE_ATTACK, spellProto); @@ -5867,7 +5856,7 @@ void Aura::PeriodicTick() if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false)) { - for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++) + for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) { if (pCaster->m_currentSpells[i] && pCaster->m_currentSpells[i]->m_spellInfo->Id == spellProto->Id) pCaster->m_currentSpells[i]->cancel(); @@ -5892,7 +5881,7 @@ void Aura::PeriodicTick() return; // heal for caster damage (must be alive) - if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive()) + if(m_target != pCaster && GetSpellProto()->SpellVisual[0] == 163 && !pCaster->isAlive()) return; // ignore non positive values (can be result apply spellmods to aura damage @@ -5901,7 +5890,7 @@ void Aura::PeriodicTick() uint32 pdamage; if(m_modifier.m_auraname==SPELL_AURA_OBS_MOD_HEALTH) - pdamage = uint32(m_target->GetMaxHealth() * amount/100); + pdamage = uint32(m_target->GetMaxHealth() * amount / 100); else pdamage = amount; @@ -5910,15 +5899,8 @@ void Aura::PeriodicTick() 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()); - WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size - data.append(m_target->GetPackGUID()); - data.appendPackGUID(GetCasterGUID()); - data << uint32(GetId()); - data << uint32(1); - data << uint32(m_modifier.m_auraname); - data << (uint32)pdamage; - data << uint32(0); // wotlk - m_target->SendMessageToSet(&data, true); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f); + m_target->SendPeriodicAuraLog(&pInfo); int32 gain = m_target->ModifyHealth(pdamage); @@ -5932,7 +5914,7 @@ void Aura::PeriodicTick() SpellEntry const* spellProto = GetSpellProto(); // heal for caster damage - if(m_target!=pCaster && spellProto->SpellVisual[0] == 163) + if(m_target != pCaster && spellProto->SpellVisual[0] == 163) { uint32 dmg = spellProto->manaPerSecond; if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER) @@ -5954,7 +5936,7 @@ void Aura::PeriodicTick() { uint32 damage = gain; uint32 absorb = 0; - pCaster->DealDamageMods(pCaster,damage,&absorb); + pCaster->DealDamageMods(pCaster, damage, &absorb); pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false); CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); @@ -5987,7 +5969,7 @@ void Aura::PeriodicTick() if(!pCaster->isAlive()) return; - if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA && + if( GetSpellProto()->Effect[GetEffIndex()] == SPELL_EFFECT_PERSISTENT_AREA_AURA && pCaster->SpellHitResult(m_target, GetSpellProto(), false) != SPELL_MISS_NONE) return; @@ -6030,22 +6012,14 @@ void Aura::PeriodicTick() modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier); } - WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size - data.append(m_target->GetPackGUID()); - data.appendPackGUID(GetCasterGUID()); - data << uint32(GetId()); - data << uint32(1); - data << uint32(m_modifier.m_auraname); - data << (uint32)power; // power type - data << (uint32)drain_amount; - data << (float)gain_multiplier; - m_target->SendMessageToSet(&data, true); + SpellPeriodicAuraLogInfo pInfo(this, drain_amount, 0, 0, 0, gain_multiplier); + m_target->SendPeriodicAuraLog(&pInfo); - int32 gain_amount = int32(drain_amount*gain_multiplier); + int32 gain_amount = int32(drain_amount * gain_multiplier); if(gain_amount) { - int32 gain = pCaster->ModifyPower(power,gain_amount); + int32 gain = pCaster->ModifyPower(power, gain_amount); m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto()); } break; @@ -6066,15 +6040,8 @@ void Aura::PeriodicTick() if(m_target->GetMaxPower(power) == 0) break; - WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size - data.append(m_target->GetPackGUID()); - data.appendPackGUID(GetCasterGUID()); - data << uint32(GetId()); - data << uint32(1); - data << uint32(m_modifier.m_auraname); - data << (uint32)power; // power type - data << (uint32)pdamage; - m_target->SendMessageToSet(&data, true); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f); + m_target->SendPeriodicAuraLog(&pInfo); int32 gain = m_target->ModifyPower(power,pdamage); @@ -6087,7 +6054,7 @@ void Aura::PeriodicTick() // ignore non positive values (can be result apply spellmods to aura damage uint32 amount = m_modifier.m_amount > 0 ? m_modifier.m_amount : 0; - uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount/100); + uint32 pdamage = uint32(m_target->GetMaxPower(POWER_MANA) * amount / 100); sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u mana inflicted by %u", GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId()); @@ -6095,15 +6062,8 @@ void Aura::PeriodicTick() if(m_target->GetMaxPower(POWER_MANA) == 0) break; - WorldPacket data(SMSG_PERIODICAURALOG, (21+16));// we guess size - data.append(m_target->GetPackGUID()); - data.appendPackGUID(GetCasterGUID()); - data << uint32(GetId()); - data << uint32(1); - data << uint32(m_modifier.m_auraname); - data << (uint32)0; // ? - data << (uint32)pdamage; - m_target->SendMessageToSet(&data,true); + SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f); + m_target->SendPeriodicAuraLog(&pInfo); int32 gain = m_target->ModifyPower(POWER_MANA, pdamage); @@ -6137,7 +6097,7 @@ void Aura::PeriodicTick() gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]); SpellEntry const* spellProto = GetSpellProto(); - //maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG + // maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask); pCaster->CalculateSpellDamage(&damageInfo, gain, spellProto); @@ -6146,7 +6106,7 @@ void Aura::PeriodicTick() pCaster->SendSpellNonMeleeDamageLog(&damageInfo); // Set trigger flag - uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;// | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; + uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC; // | PROC_FLAG_SUCCESSFUL_HARMFUL_SPELL_HIT; uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;// | PROC_FLAG_TAKEN_HARMFUL_SPELL_HIT; uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE); if (damageInfo.damage) @@ -6185,7 +6145,7 @@ void Aura::PeriodicTick() // amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3 // so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec if(pt == POWER_RAGE) - m_target->ModifyPower(pt, m_modifier.m_amount*3/5); + m_target->ModifyPower(pt, m_modifier.m_amount * 3 / 5); break; } // Here tick dummy auras diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 41cf0cf66..407314ed7 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4250,10 +4250,10 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log) SendMessageToSet( &data, true ); } -void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit) +void Unit::SendSpellNonMeleeDamageLog(Unit *target, uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit) { - SpellNonMeleeDamage log(this,target,SpellID,damageSchoolMask); - log.damage = Damage-AbsorbedDamage-Resist-Blocked; + SpellNonMeleeDamage log(this, target, SpellID, damageSchoolMask); + log.damage = Damage - AbsorbedDamage - Resist - Blocked; log.absorb = AbsorbedDamage; log.resist = Resist; log.physicalLog = PhysicalDamage; @@ -4264,6 +4264,52 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SendSpellNonMeleeDamageLog(&log); } +void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo *pInfo) +{ + Aura *aura = pInfo->aura; + Modifier *mod = aura->GetModifier(); + + WorldPacket data(SMSG_PERIODICAURALOG, 30); + data.append(aura->GetTarget()->GetPackGUID()); + data.appendPackGUID(aura->GetCasterGUID()); + data << uint32(aura->GetId()); // spellId + data << uint32(1); // count + data << uint32(mod->m_auraname); // auraId + switch(mod->m_auraname) + { + case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: + data << uint32(pInfo->damage); // damage + data << uint32(pInfo->overDamage); // overkill? + data << uint32(GetSpellSchoolMask(aura->GetSpellProto())); + data << uint32(pInfo->absorb); // absorb + data << uint32(pInfo->resist); // resist + data << uint8(0); // new 3.1.2 + 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 + break; + case SPELL_AURA_OBS_MOD_MANA: + case SPELL_AURA_PERIODIC_ENERGIZE: + data << uint32(mod->m_miscvalue); // power type + data << uint32(pInfo->damage); // damage + break; + case SPELL_AURA_PERIODIC_MANA_LEECH: + data << uint32(mod->m_miscvalue); // power type + data << uint32(pInfo->damage); // amount + data << float(pInfo->multiplier); // gain multiplier + break; + default: + sLog.outError("Unit::SendPeriodicAuraLog: unknown aura %u", uint32(mod->m_auraname)); + return; + } + + aura->GetTarget()->SendMessageToSet(&data, true); +} + void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellEntry const *procSpell) { // Not much to do if no flags are set. diff --git a/src/game/Unit.h b/src/game/Unit.h index ba1fc153f..cc7627600 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -685,7 +685,7 @@ struct CalcDamageInfo uint32 procAttacker; uint32 procVictim; uint32 procEx; - uint32 cleanDamage; // Used only fo rage calcultion + uint32 cleanDamage; // Used only for rage calculation MeleeHitOutcome hitOutCome; // TODO: remove this field (need use TargetState) }; @@ -712,6 +712,19 @@ struct SpellNonMeleeDamage{ uint32 cleanDamage; }; +struct SpellPeriodicAuraLogInfo +{ + SpellPeriodicAuraLogInfo(Aura *_aura, uint32 _damage, uint32 _overDamage, uint32 _absorb, uint32 _resist, float _multiplier) + : aura(_aura), damage(_damage), overDamage(_overDamage), absorb(_absorb), resist(_resist), multiplier(_multiplier) {} + + Aura *aura; + uint32 damage; + uint32 absorb; + uint32 resist; + uint32 overDamage; // overkill/overheal + float multiplier; +}; + uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition); #define MAX_DECLINED_NAME_CASES 5 @@ -1106,7 +1119,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SendAttackStateUpdate(CalcDamageInfo *damageInfo); void SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount); void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log); - void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false); + void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false); + void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo *pInfo); void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo); void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false);