diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 108 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.cpp | 17 | ||||
| -rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.h | 17 | ||||
| -rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 |
4 files changed, 110 insertions, 34 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 20b4957e604..f0fb4fd7efc 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -920,6 +920,20 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam killed = false; skipSettingDeathState = true; + + if (currentAbsorb) + { + WorldPackets::CombatLog::SpellAbsorbLog absorbLog; + absorbLog.Attacker = GetGUID(); + absorbLog.Victim = victim->GetGUID(); + absorbLog.Caster = base->GetCasterGUID(); + absorbLog.AbsorbedSpellID = spellProto ? spellProto->Id : 0; + absorbLog.AbsorbSpellID = base->GetId(); + absorbLog.Absorbed = currentAbsorb; + absorbLog.OriginalDamage = damageInfo.GetOriginalDamage(); + absorbLog.LogData.Initialize(victim); + SendCombatLogMessage(&absorbLog); + } } damage = damageInfo.GetDamage(); @@ -1815,25 +1829,39 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo) absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented); currentAbsorb = tempAbsorb; - if (defaultPrevented) - continue; + if (!defaultPrevented) + { + // absorb must be smaller than the damage itself + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); - // absorb must be smaller than the damage itself - currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); + damageInfo.AbsorbDamage(currentAbsorb); - damageInfo.AbsorbDamage(currentAbsorb); + tempAbsorb = currentAbsorb; + absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); - tempAbsorb = currentAbsorb; - absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); + // Check if our aura is using amount to count damage + if (absorbAurEff->GetAmount() >= 0) + { + // Reduce shield amount + absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb); + // Aura cannot absorb anything more - remove it + if (absorbAurEff->GetAmount() <= 0) + absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); + } + } - // Check if our aura is using amount to count damage - if (absorbAurEff->GetAmount() >= 0) + if (currentAbsorb) { - // Reduce shield amount - absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb); - // Aura cannot absorb anything more - remove it - if (absorbAurEff->GetAmount() <= 0) - absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); + WorldPackets::CombatLog::SpellAbsorbLog absorbLog; + absorbLog.Attacker = damageInfo.GetAttacker()->GetGUID(); + absorbLog.Victim = damageInfo.GetVictim()->GetGUID(); + absorbLog.Caster = absorbAurEff->GetBase()->GetCasterGUID(); + absorbLog.AbsorbedSpellID = damageInfo.GetSpellInfo() ? damageInfo.GetSpellInfo()->Id : 0; + absorbLog.AbsorbSpellID = absorbAurEff->GetId(); + absorbLog.Absorbed = currentAbsorb; + absorbLog.OriginalDamage = damageInfo.GetOriginalDamage(); + absorbLog.LogData.Initialize(damageInfo.GetVictim()); + SendCombatLogMessage(&absorbLog); } } @@ -1863,34 +1891,48 @@ void Unit::CalcAbsorbResist(DamageInfo& damageInfo) absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented); currentAbsorb = tempAbsorb; - if (defaultPrevented) - continue; + if (!defaultPrevented) + { + // absorb must be smaller than the damage itself + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); - // absorb must be smaller than the damage itself - currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); + int32 manaReduction = currentAbsorb; - int32 manaReduction = currentAbsorb; + // lower absorb amount by talents + if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster())) + manaReduction = int32(float(manaReduction) * manaMultiplier); - // lower absorb amount by talents - if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster())) - manaReduction = int32(float(manaReduction) * manaMultiplier); + int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction); - int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction); + // take case when mana has ended up into account + currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0; - // take case when mana has ended up into account - currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0; + damageInfo.AbsorbDamage(currentAbsorb); - damageInfo.AbsorbDamage(currentAbsorb); + tempAbsorb = currentAbsorb; + absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); - tempAbsorb = currentAbsorb; - absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); + // Check if our aura is using amount to count damage + if (absorbAurEff->GetAmount() >= 0) + { + absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb); + if ((absorbAurEff->GetAmount() <= 0)) + absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); + } + } - // Check if our aura is using amount to count damage - if (absorbAurEff->GetAmount() >= 0) + if (currentAbsorb) { - absorbAurEff->ChangeAmount(absorbAurEff->GetAmount() - currentAbsorb); - if ((absorbAurEff->GetAmount() <= 0)) - absorbAurEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); + WorldPackets::CombatLog::SpellAbsorbLog absorbLog; + absorbLog.Attacker = damageInfo.GetAttacker()->GetGUID(); + absorbLog.Victim = damageInfo.GetVictim()->GetGUID(); + absorbLog.Caster = absorbAurEff->GetBase()->GetCasterGUID(); + absorbLog.AbsorbedSpellID = damageInfo.GetSpellInfo() ? damageInfo.GetSpellInfo()->Id : 0; + absorbLog.AbsorbSpellID = absorbAurEff->GetId(); + absorbLog.Absorbed = currentAbsorb; + absorbLog.OriginalDamage = damageInfo.GetOriginalDamage(); + absorbLog.LogData.Initialize(damageInfo.GetVictim()); + SendCombatLogMessage(&absorbLog); } } diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp index 390fb70170e..e6a81be2bc1 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.cpp +++ b/src/server/game/Server/Packets/CombatLogPackets.cpp @@ -395,3 +395,20 @@ WorldPacket const* WorldPackets::CombatLog::SpellDispellLog::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::CombatLog::SpellAbsorbLog::Write() +{ + *this << Attacker; + *this << Victim; + *this << int32(AbsorbedSpellID); + *this << int32(AbsorbSpellID); + *this << Caster; + *this << int32(Absorbed); + *this << int32(OriginalDamage); + WriteBit(Unk); + WriteLogDataBit(); + FlushBits(); + WriteLogData(); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h index 0d06623746f..bef250fa4d0 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.h +++ b/src/server/game/Server/Packets/CombatLogPackets.h @@ -324,6 +324,23 @@ namespace WorldPackets float Unk = 0.0f; Spells::ContentTuningParams ContentTuning; }; + + class SpellAbsorbLog final : public CombatLogServerPacket + { + public: + SpellAbsorbLog() : CombatLogServerPacket(SMSG_SPELL_ABSORB_LOG, 100) { } + + WorldPacket const* Write() override; + + ObjectGuid Attacker; + ObjectGuid Victim; + ObjectGuid Caster; + int32 AbsorbedSpellID = 0; + int32 AbsorbSpellID = 0; + int32 Absorbed = 0; + int32 OriginalDamage = 0; + bool Unk = false; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 0c1e39bb487..ddbabb4822a 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1900,7 +1900,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SOCKET_GEMS_SUCCESS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPECIAL_MOUNT_ANIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPEC_INVOLUNTARILY_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ABSORB_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ABSORB_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CHANNEL_START, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CHANNEL_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); |
