aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp64
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.cpp90
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.h71
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp28
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
7 files changed, 199 insertions, 60 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a0fd3db2076..329995ac4e5 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1391,7 +1391,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
// ...or immuned
if (IsImmunedToDamage(i_spellProto))
{
- victim->SendSpellDamageImmune(this, i_spellProto->Id);
+ victim->SendSpellDamageImmune(this, i_spellProto->Id, false);
continue;
}
@@ -1403,20 +1403,20 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetSpellEffectInfo());
}
+ uint32 absorb = 0, resist = 0;
+ victim->CalcAbsorbResist(this, SpellSchoolMask(i_spellProto->SchoolMask), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, i_spellProto);
// No Unit::CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that
victim->DealDamageMods(this, damage, NULL);
- /// @todo Move this to a packet handler
- WorldPacket data(SMSG_SPELL_DAMAGE_SHIELD, 8 + 8 + 4 + 4 + 4 + 4 + 4);
- data << victim->GetGUID();
- data << GetGUID();
- data << uint32(i_spellProto->Id);
- data << uint32(damage); // Damage
- int32 overkill = int32(damage) - int32(GetHealth());
- data << uint32(overkill > 0 ? overkill : 0); // Overkill
- data << uint32(i_spellProto->SchoolMask);
- data << uint32(0); // FIX ME: Send resisted damage, both fully resisted and partly resisted
- victim->SendMessageToSet(&data, true);
+ WorldPackets::CombatLog::SpellDamageShield damageShield;
+ damageShield.Attacker = victim->GetGUID();
+ damageShield.Defender = GetGUID();
+ damageShield.SpellID = i_spellProto->Id;
+ damageShield.TotalDamage = damage;
+ damageShield.OverKill = std::max(int32(damage) - int32(GetHealth()), 0);
+ damageShield.SchoolMask = i_spellProto->SchoolMask;
+ damageShield.LogAbsorbed = absorb;
+ victim->SendMessageToSet(damageShield.Write(), true);
victim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true);
}
@@ -4876,36 +4876,30 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* info)
void Unit::SendSpellMiss(Unit* target, uint32 spellID, SpellMissInfo missInfo)
{
- WorldPacket data(SMSG_SPELL_MISS_LOG, (4+8+1+4+8+1));
- data << uint32(spellID);
- data << GetGUID();
- data << uint8(0); // can be 0 or 1
- data << uint32(1); // target count
- // for (i = 0; i < target count; ++i)
- data << target->GetGUID(); // target GUID
- data << uint8(missInfo);
- // end loop
- SendMessageToSet(&data, true);
+ WorldPackets::CombatLog::SpellMissLog spellMissLog;
+ spellMissLog.SpellID = spellID;
+ spellMissLog.Caster = GetGUID();
+ spellMissLog.Entries.emplace_back(target->GetGUID(), missInfo);
+ SendMessageToSet(spellMissLog.Write(), true);
}
void Unit::SendSpellDamageResist(Unit* target, uint32 spellId)
{
- WorldPacket data(SMSG_PROC_RESIST, 8+8+4+1);
- data << GetGUID();
- data << target->GetGUID();
- data << uint32(spellId);
- data << uint8(0); // bool - log format: 0-default, 1-debug
- SendMessageToSet(&data, true);
+ WorldPackets::CombatLog::ProcResist procResist;
+ procResist.Caster = GetGUID();
+ procResist.SpellID = spellId;
+ procResist.Target = target->GetGUID();
+ SendMessageToSet(procResist.Write(), true);
}
-void Unit::SendSpellDamageImmune(Unit* target, uint32 spellId)
+void Unit::SendSpellDamageImmune(Unit* target, uint32 spellId, bool isPeriodic)
{
- WorldPacket data(SMSG_SPELL_OR_DAMAGE_IMMUNE, 8+8+4+1);
- data << GetGUID();
- data << target->GetGUID();
- data << uint32(spellId);
- data << uint8(0); // bool - log format: 0-default, 1-debug
- SendMessageToSet(&data, true);
+ WorldPackets::CombatLog::SpellOrDamageImmune spellOrDamageImmune;
+ spellOrDamageImmune.CasterGUID = GetGUID();
+ spellOrDamageImmune.VictimGUID = target->GetGUID();
+ spellOrDamageImmune.SpellID = spellId;
+ spellOrDamageImmune.IsPeriodic = isPeriodic;
+ SendMessageToSet(spellOrDamageImmune.Write(), true);
}
void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index fe7fd3c306a..fa9b4138b43 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1625,7 +1625,7 @@ class Unit : public WorldObject
void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo);
void SendSpellMiss(Unit* target, uint32 spellID, SpellMissInfo missInfo);
void SendSpellDamageResist(Unit* target, uint32 spellId);
- void SendSpellDamageImmune(Unit* target, uint32 spellId);
+ void SendSpellDamageImmune(Unit* target, uint32 spellId, bool isPeriodic);
void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false);
void SendTeleportPacket(Position& pos);
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 7b636cba0ec..e02dcaefdea 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -2039,7 +2039,7 @@ enum SpellHitType
SPELL_HIT_TYPE_VICTIM_IS_ATTACKER = 0x10,
SPELL_HIT_TYPE_ATTACK_TABLE_DEBUG = 0x20,
SPELL_HIT_TYPE_UNK = 0x40,
- SPELL_HIT_TYPE_NO_ATTACKER = 0x80,
+ SPELL_HIT_TYPE_NO_ATTACKER = 0x80, // does the same as SPELL_ATTR4_COMBAT_LOG_NO_CASTER
};
enum SpellDmgClass
diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp
index 295f27375da..baf1576f852 100644
--- a/src/server/game/Server/Packets/CombatLogPackets.cpp
+++ b/src/server/game/Server/Packets/CombatLogPackets.cpp
@@ -22,16 +22,16 @@ WorldPacket const* WorldPackets::CombatLog::SpellNonMeleeDamageLog::Write()
{
_worldPacket << Me;
_worldPacket << CasterGUID;
- _worldPacket << SpellID;
- _worldPacket << Damage;
- _worldPacket << Overkill;
- _worldPacket << SchoolMask;
- _worldPacket << ShieldBlock;
- _worldPacket << Resisted;
- _worldPacket << Absorbed;
+ _worldPacket << int32(SpellID);
+ _worldPacket << int32(Damage);
+ _worldPacket << int32(Overkill);
+ _worldPacket << uint8(SchoolMask);
+ _worldPacket << int32(ShieldBlock);
+ _worldPacket << int32(Resisted);
+ _worldPacket << int32(Absorbed);
_worldPacket.WriteBit(Periodic);
- _worldPacket.WriteBits(Flags, 9);
+ _worldPacket.WriteBits(Flags, 8);
_worldPacket.WriteBit(false); // Debug info
_worldPacket.WriteBit(LogData.is_initialized());
_worldPacket.FlushBits();
@@ -220,3 +220,77 @@ WorldPacket const* WorldPackets::CombatLog::SpellInstakillLog::Write()
return &_worldPacket;
}
+
+ByteBuffer& operator<<(ByteBuffer& buffer, WorldPackets::CombatLog::SpellLogMissDebug const& missDebug)
+{
+ buffer << float(missDebug.HitRoll);
+ buffer << float(missDebug.HitRollNeeded);
+ return buffer;
+}
+
+ByteBuffer& operator<<(ByteBuffer& buffer, WorldPackets::CombatLog::SpellLogMissEntry const& missEntry)
+{
+ buffer << missEntry.Victim;
+ buffer << uint8(missEntry.MissReason);
+ if (buffer.WriteBit(missEntry.Debug.is_initialized()))
+ buffer << *missEntry.Debug;
+
+ buffer.FlushBits();
+ return buffer;
+}
+
+WorldPacket const* WorldPackets::CombatLog::SpellMissLog::Write()
+{
+ _worldPacket << int32(SpellID);
+ _worldPacket << Caster;
+ _worldPacket << uint32(Entries.size());
+ for (SpellLogMissEntry const& missEntry : Entries)
+ _worldPacket << missEntry;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::CombatLog::ProcResist::Write()
+{
+ _worldPacket << Caster;
+ _worldPacket << Target;
+ _worldPacket << int32(SpellID);
+ _worldPacket.WriteBit(Rolled.is_initialized());
+ _worldPacket.WriteBit(Needed.is_initialized());
+ _worldPacket.FlushBits();
+
+ if (Rolled)
+ _worldPacket << *Rolled;
+
+ if (Needed)
+ _worldPacket << *Needed;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::CombatLog::SpellOrDamageImmune::Write()
+{
+ _worldPacket << CasterGUID;
+ _worldPacket << VictimGUID;
+ _worldPacket << uint32(SpellID);
+ _worldPacket.WriteBit(IsPeriodic);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::CombatLog::SpellDamageShield::Write()
+{
+ _worldPacket << Attacker;
+ _worldPacket << Defender;
+ _worldPacket << int32(SpellID);
+ _worldPacket << int32(TotalDamage);
+ _worldPacket << int32(OverKill);
+ _worldPacket << int32(SchoolMask);
+ _worldPacket << int32(LogAbsorbed);
+ if (_worldPacket.WriteBit(LogData.is_initialized()))
+ _worldPacket << *LogData;
+
+ _worldPacket.FlushBits();
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h
index 5566ea62180..a181ead6d6a 100644
--- a/src/server/game/Server/Packets/CombatLogPackets.h
+++ b/src/server/game/Server/Packets/CombatLogPackets.h
@@ -180,6 +180,77 @@ namespace WorldPackets
ObjectGuid Caster;
int32 SpellID = 0;
};
+
+ struct SpellLogMissDebug
+ {
+ float HitRoll = 0.0f;
+ float HitRollNeeded = 0.0f;
+ };
+
+ struct SpellLogMissEntry
+ {
+ SpellLogMissEntry(ObjectGuid const& victim, uint8 missReason) : Victim(victim), MissReason(missReason) { }
+
+ ObjectGuid Victim;
+ uint8 MissReason = 0;
+ Optional<SpellLogMissDebug> Debug;
+ };
+
+ class SpellMissLog final : public ServerPacket
+ {
+ public:
+ SpellMissLog() : ServerPacket(SMSG_SPELL_MISS_LOG) { }
+
+ WorldPacket const* Write() override;
+
+ int32 SpellID = 0;
+ ObjectGuid Caster;
+ std::vector<SpellLogMissEntry> Entries;
+ };
+
+ class ProcResist final : public ServerPacket
+ {
+ public:
+ ProcResist() : ServerPacket(SMSG_PROC_RESIST, 16 + 4 + 4 + 4 + 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Caster;
+ ObjectGuid Target;
+ int32 SpellID = 0;
+ Optional<float> Rolled;
+ Optional<float> Needed;
+ };
+
+ class SpellOrDamageImmune final : public ServerPacket
+ {
+ public:
+ SpellOrDamageImmune() : ServerPacket(SMSG_SPELL_OR_DAMAGE_IMMUNE, 16 + 1 + 4 + 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid CasterGUID;
+ ObjectGuid VictimGUID;
+ uint32 SpellID = 0;
+ bool IsPeriodic = false;
+ };
+
+ class SpellDamageShield final : public ServerPacket
+ {
+ public:
+ SpellDamageShield() : ServerPacket(SMSG_SPELL_DAMAGE_SHIELD, 4 + 16 + 4 + 4 + 16 + 4 + 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Attacker;
+ ObjectGuid Defender;
+ int32 SpellID = 0;
+ int32 TotalDamage = 0;
+ int32 OverKill = 0;
+ int32 SchoolMask = 0;
+ int32 LogAbsorbed = 0;
+ Optional<Spells::SpellCastLogData> LogData;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 84743eea95a..883a1693cec 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1492,7 +1492,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PRE_RESSURECT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PRINT_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROC_RESIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROC_RESIST, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
@@ -1638,24 +1638,24 @@ void OpcodeTable::Initialize()
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);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DAMAGE_SHIELD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DISPELL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ENERGIZE_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_EXECUTE_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DAMAGE_SHIELD, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DISPELL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ENERGIZE_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_EXECUTE_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILURE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_GO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_HEAL_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_INSTAKILL_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_INTERRUPT_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MISS_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MULTISTRIKE_EFFECT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_HEAL_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_INSTAKILL_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_INTERRUPT_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MISS_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_MULTISTRIKE_EFFECT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_NON_MELEE_DAMAGE_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_OR_DAMAGE_IMMUNE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_PERIODIC_AURA_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_OR_DAMAGE_IMMUNE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_PERIODIC_AURA_LOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_STAND_STATE_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 58c0353998f..8f16af2a7b8 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1162,7 +1162,7 @@ bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
void AuraEffect::SendTickImmune(Unit* target, Unit* caster) const
{
if (caster)
- caster->SendSpellDamageImmune(target, m_spellInfo->Id);
+ caster->SendSpellDamageImmune(target, m_spellInfo->Id, true);
}
void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const