aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.h3
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp118
-rw-r--r--src/server/game/Entities/Unit/Unit.h9
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.cpp278
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.h131
-rw-r--r--src/server/game/Server/Packets/CombatPackets.cpp58
-rw-r--r--src/server/game/Server/Packets/CombatPackets.h48
-rw-r--r--src/server/game/Spells/Spell.cpp2
9 files changed, 392 insertions, 257 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 687478ae6d8..3666da7f6d5 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1305,7 +1305,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
packet.Amount = damage;
packet.Absorbed = absorb;
packet.Resisted = resist;
- SendMessageToSet(packet.Write(), true);
+ SendCombatLogMessage(&packet);
uint32 final_damage = DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 6147090a0ff..3d6fe21c388 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2633,6 +2633,8 @@ class Player : public Unit, public GridObject<Player>
void DeleteGarrison();
Garrison* GetGarrison() { return _garrison.get(); }
+ bool HasAdvancedCombatLogging() const { return false; }
+
protected:
// Gamemaster whisper whitelist
GuidList WhisperList;
@@ -2938,7 +2940,6 @@ class Player : public Unit, public GridObject<Player>
MapReference m_mapRef;
void UpdateCharmedAI();
-
uint32 m_lastFallTime;
float m_lastFallZ;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 329995ac4e5..188e39e1e2b 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1416,9 +1416,9 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
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);
+ victim->SendCombatLogMessage(&damageShield);
}
}
}
@@ -4822,7 +4822,7 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log)
packet.Absorbed = log->absorb;
packet.Periodic = false;
packet.Flags = log->HitInfo;
- SendMessageToSet(packet.Write(), true);
+ SendCombatLogMessage(&packet);
}
void Unit::SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
@@ -4871,7 +4871,7 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* info)
data.Effects.push_back(spellLogEffect);
- SendMessageToSet(data.Write(), true);
+ SendCombatLogMessage(&data);
}
void Unit::SendSpellMiss(Unit* target, uint32 spellID, SpellMissInfo missInfo)
@@ -4904,7 +4904,7 @@ void Unit::SendSpellDamageImmune(Unit* target, uint32 spellId, bool isPeriodic)
void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
{
- WorldPackets::Combat::AttackerStateUpdate packet;
+ WorldPackets::CombatLog::AttackerStateUpdate packet;
packet.HitInfo = damageInfo->HitInfo;
packet.AttackerGUID = damageInfo->attacker->GetGUID();
packet.VictimGUID = damageInfo->target->GetGUID();
@@ -4912,7 +4912,7 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
int32 overkill = damageInfo->damage - damageInfo->target->GetHealth();
packet.OverDamage = (overkill < 0 ? -1 : overkill);
- packet.SubDmg = WorldPackets::Combat::SubDamage();
+ packet.SubDmg = boost::in_place();
packet.SubDmg->SchoolMask = damageInfo->damageSchoolMask; // School of sub damage
packet.SubDmg->FDamage = damageInfo->damage; // sub damage
packet.SubDmg->Damage = damageInfo->damage; // Sub Damage
@@ -4922,7 +4922,7 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
packet.VictimState = damageInfo->TargetState;
packet.BlockAmount = damageInfo->blocked_amount;
- SendMessageToSet(packet.Write(), true);
+ SendCombatLogMessage(&packet);
}
void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType*/, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
@@ -8135,7 +8135,7 @@ void Unit::SendHealSpellLog(Unit* victim, uint32 spellID, uint32 health, uint32
if (hasLogData)
SpellParsers.ReadSpellCastLogData(packet);
*/
- SendMessageToSet(spellHealLog.Write(), true);
+ SendCombatLogMessage(&spellHealLog);
}
int32 Unit::HealBySpell(Unit* victim, SpellInfo const* spellInfo, uint32 addHealth, bool critical)
@@ -8158,7 +8158,7 @@ void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellId, int32 damage, Powe
data.Type = powerType;
data.Amount = damage;
- SendMessageToSet(data.Write(), true);
+ SendCombatLogMessage(&data);
}
void Unit::EnergizeBySpell(Unit* victim, uint32 spellId, int32 damage, Powers powerType)
@@ -16430,3 +16430,105 @@ SpellInfo const* Unit::GetCastSpellInfo(SpellInfo const* spellInfo) const
return spellInfo;
}
+
+struct CombatLogSender
+{
+ WorldObject const* i_source;
+ WorldPackets::CombatLog::CombatLogServerPacket const* i_message;
+ float const i_distSq;
+ CombatLogSender(WorldObject const* src, WorldPackets::CombatLog::CombatLogServerPacket* msg, float dist)
+ : i_source(src), i_message(msg), i_distSq(dist * dist)
+ {
+ msg->Write();
+ }
+
+ bool IsInRangeHelper(WorldObject const* object) const;
+ void Visit(PlayerMapType &m);
+ void Visit(CreatureMapType &m);
+ void Visit(DynamicObjectMapType &m);
+ template<class SKIP> void Visit(GridRefManager<SKIP>&) { }
+
+ void SendPacket(Player* player)
+ {
+ if (!player->HaveAtClient(i_source))
+ return;
+
+ if (player->HasAdvancedCombatLogging())
+ player->SendDirectMessage(i_message->GetFullLogPacket());
+ else
+ player->SendDirectMessage(i_message->GetBasicLogPacket());
+ }
+};
+
+bool CombatLogSender::IsInRangeHelper(WorldObject const* object) const
+{
+ if (!object->IsInPhase(i_source))
+ return false;
+
+ return object->GetExactDist2dSq(i_source) <= i_distSq;
+}
+
+void CombatLogSender::Visit(PlayerMapType& m)
+{
+ for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ Player* target = iter->GetSource();
+ if (!IsInRangeHelper(target))
+ continue;
+
+ // Send packet to all who are sharing the player's vision
+ if (target->HasSharedVision())
+ {
+ SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
+ for (; i != target->GetSharedVisionList().end(); ++i)
+ if ((*i)->m_seer == target)
+ SendPacket(*i);
+ }
+
+ if (target->m_seer == target || target->GetVehicle())
+ SendPacket(target);
+ }
+}
+
+void CombatLogSender::Visit(CreatureMapType& m)
+{
+ for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ Creature* target = iter->GetSource();
+ if (!IsInRangeHelper(target))
+ continue;
+
+ // Send packet to all who are sharing the creature's vision
+ if (target->HasSharedVision())
+ {
+ SharedVisionList::const_iterator i = target->GetSharedVisionList().begin();
+ for (; i != target->GetSharedVisionList().end(); ++i)
+ if ((*i)->m_seer == target)
+ SendPacket(*i);
+ }
+ }
+}
+
+void CombatLogSender::Visit(DynamicObjectMapType& m)
+{
+ for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
+ {
+ DynamicObject* target = iter->GetSource();
+ if (!IsInRangeHelper(target))
+ continue;
+
+ if (Unit* caster = target->GetCaster())
+ {
+ // Send packet back to the caster if the caster has vision of dynamic object
+ Player* player = caster->ToPlayer();
+ if (player && player->m_seer == target)
+ SendPacket(player);
+ }
+ }
+}
+
+void Unit::SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* combatLog) const
+{
+ CombatLogSender notifier(this, combatLog, GetVisibilityRange());
+ VisitNearbyWorldObject(GetVisibilityRange(), notifier);
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index fa9b4138b43..e2da54a868d 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -410,6 +410,13 @@ namespace Movement
{
class MoveSpline;
}
+namespace WorldPackets
+{
+ namespace CombatLog
+ {
+ class CombatLogServerPacket;
+ }
+}
typedef std::list<Unit*> UnitList;
typedef std::list<std::pair<Aura*, uint8>> DispelChargesList;
@@ -1325,6 +1332,8 @@ class Unit : public WorldObject
void CleanupBeforeRemoveFromMap(bool finalCleanup);
void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units)
+ void SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* combatLog) const;
+
DiminishingLevels GetDiminishing(DiminishingGroup group);
void IncrDiminishing(DiminishingGroup group);
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit* caster, DiminishingLevels Level, int32 limitduration);
diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp
index baf1576f852..1b55bc8e26f 100644
--- a/src/server/game/Server/Packets/CombatLogPackets.cpp
+++ b/src/server/game/Server/Packets/CombatLogPackets.cpp
@@ -20,167 +20,150 @@
WorldPacket const* WorldPackets::CombatLog::SpellNonMeleeDamageLog::Write()
{
- _worldPacket << Me;
- _worldPacket << CasterGUID;
- _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, 8);
- _worldPacket.WriteBit(false); // Debug info
- _worldPacket.WriteBit(LogData.is_initialized());
- _worldPacket.FlushBits();
-
- if (LogData)
- _worldPacket << *LogData;
+ *this << Me;
+ *this << CasterGUID;
+ *this << int32(SpellID);
+ *this << int32(Damage);
+ *this << int32(Overkill);
+ *this << uint8(SchoolMask);
+ *this << int32(ShieldBlock);
+ *this << int32(Resisted);
+ *this << int32(Absorbed);
+ WriteBit(Periodic);
+ WriteBits(Flags, 8);
+ WriteBit(false); // Debug info
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
return &_worldPacket;
}
WorldPacket const* WorldPackets::CombatLog::EnvironmentalDamageLog::Write()
{
- _worldPacket << Victim;
- _worldPacket << Type;
- _worldPacket << Amount;
- _worldPacket << Resisted;
- _worldPacket << Absorbed;
-
- _worldPacket.WriteBit(LogData.is_initialized());
- _worldPacket.FlushBits();
-
- if (LogData)
- _worldPacket << *LogData;
+ *this << Victim;
+ *this << uint8(Type);
+ *this << int32(Amount);
+ *this << int32(Resisted);
+ *this << int32(Absorbed);
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
return &_worldPacket;
}
WorldPacket const* WorldPackets::CombatLog::SpellExecuteLog::Write()
{
- _worldPacket << Caster;
- _worldPacket << SpellID;
-
- _worldPacket << uint32(Effects.size());
+ *this << Caster;
+ *this << SpellID;
+ *this << uint32(Effects.size());
for (SpellLogEffect const& effect : Effects)
{
- _worldPacket << effect.Effect;
+ *this << effect.Effect;
- _worldPacket << uint32(effect.PowerDrainTargets.size());
- _worldPacket << uint32(effect.ExtraAttacksTargets.size());
- _worldPacket << uint32(effect.DurabilityDamageTargets.size());
- _worldPacket << uint32(effect.GenericVictimTargets.size());
- _worldPacket << uint32(effect.TradeSkillTargets.size());
- _worldPacket << uint32(effect.FeedPetTargets.size());
+ *this << uint32(effect.PowerDrainTargets.size());
+ *this << uint32(effect.ExtraAttacksTargets.size());
+ *this << uint32(effect.DurabilityDamageTargets.size());
+ *this << uint32(effect.GenericVictimTargets.size());
+ *this << uint32(effect.TradeSkillTargets.size());
+ *this << uint32(effect.FeedPetTargets.size());
for (SpellLogEffectPowerDrainParams const& powerDrainTarget : effect.PowerDrainTargets)
{
- _worldPacket << powerDrainTarget.Victim;
- _worldPacket << powerDrainTarget.Points;
- _worldPacket << powerDrainTarget.PowerType;
- _worldPacket << powerDrainTarget.Amplitude;
+ *this << powerDrainTarget.Victim;
+ *this << powerDrainTarget.Points;
+ *this << powerDrainTarget.PowerType;
+ *this << powerDrainTarget.Amplitude;
}
for (SpellLogEffectExtraAttacksParams const& extraAttacksTarget : effect.ExtraAttacksTargets)
{
- _worldPacket << extraAttacksTarget.Victim;
- _worldPacket << extraAttacksTarget.NumAttacks;
+ *this << extraAttacksTarget.Victim;
+ *this << extraAttacksTarget.NumAttacks;
}
for (SpellLogEffectDurabilityDamageParams const& durabilityDamageTarget : effect.DurabilityDamageTargets)
{
- _worldPacket << durabilityDamageTarget.Victim;
- _worldPacket << durabilityDamageTarget.ItemID;
- _worldPacket << durabilityDamageTarget.Amount;
+ *this << durabilityDamageTarget.Victim;
+ *this << durabilityDamageTarget.ItemID;
+ *this << durabilityDamageTarget.Amount;
}
for (SpellLogEffectGenericVictimParams const& genericVictimTarget : effect.GenericVictimTargets)
- _worldPacket << genericVictimTarget.Victim;
+ *this << genericVictimTarget.Victim;
for (SpellLogEffectTradeSkillItemParams const& tradeSkillTarget : effect.TradeSkillTargets)
- _worldPacket << tradeSkillTarget.ItemID;
-
+ *this << tradeSkillTarget.ItemID;
for (SpellLogEffectFeedPetParams const& feedPetTarget : effect.FeedPetTargets)
- _worldPacket << feedPetTarget.ItemID;
+ *this << feedPetTarget.ItemID;
}
- _worldPacket.WriteBit(LogData.is_initialized());
- _worldPacket.FlushBits();
-
- if (LogData)
- _worldPacket << *LogData;
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
return &_worldPacket;
}
WorldPacket const* WorldPackets::CombatLog::SpellHealLog::Write()
{
- _worldPacket << TargetGUID;
- _worldPacket << CasterGUID;
-
- _worldPacket << SpellID;
- _worldPacket << Health;
- _worldPacket << OverHeal;
- _worldPacket << Absorbed;
-
- _worldPacket.WriteBit(Crit);
- _worldPacket.WriteBit(Multistrike);
-
- _worldPacket.WriteBit(CritRollMade.is_initialized());
- _worldPacket.WriteBit(CritRollNeeded.is_initialized());
- _worldPacket.WriteBit(LogData.is_initialized());
- _worldPacket.FlushBits();
+ *this << TargetGUID;
+ *this << CasterGUID;
+ *this << int32(SpellID);
+ *this << int32(Health);
+ *this << int32(OverHeal);
+ *this << int32(Absorbed);
+ WriteBit(Crit);
+ WriteBit(Multistrike);
+ WriteBit(CritRollMade.is_initialized());
+ WriteBit(CritRollNeeded.is_initialized());
+ WriteLogDataBit();
+ FlushBits();
if (CritRollMade)
- _worldPacket << *CritRollMade;
+ *this << *CritRollMade;
if (CritRollNeeded)
- _worldPacket << *CritRollNeeded;
+ *this << *CritRollNeeded;
- if (LogData)
- _worldPacket << *LogData;
+ WriteLogData();
return &_worldPacket;
}
WorldPacket const* WorldPackets::CombatLog::SpellPeriodicAuraLog::Write()
{
- _worldPacket << TargetGUID;
- _worldPacket << CasterGUID;
- _worldPacket << SpellID;
-
- _worldPacket << uint32(Effects.size());
+ *this << TargetGUID;
+ *this << CasterGUID;
+ *this << SpellID;
+ *this << uint32(Effects.size());
for (SpellLogEffect const& effect : Effects)
{
- _worldPacket << effect.Effect;
- _worldPacket << int32(effect.Amount);
- _worldPacket << int32(effect.OverHealOrKill);
- _worldPacket << int32(effect.SchoolMaskOrPower);
- _worldPacket << int32(effect.AbsorbedOrAmplitude);
- _worldPacket << int32(effect.Resisted);
-
- _worldPacket.WriteBit(effect.Crit);
- _worldPacket.WriteBit(effect.Multistrike);
-
- if (_worldPacket.WriteBit(effect.DebugInfo.is_initialized()))
+ *this << effect.Effect;
+ *this << int32(effect.Amount);
+ *this << int32(effect.OverHealOrKill);
+ *this << int32(effect.SchoolMaskOrPower);
+ *this << int32(effect.AbsorbedOrAmplitude);
+ *this << int32(effect.Resisted);
+ WriteBit(effect.Crit);
+ WriteBit(effect.Multistrike);
+
+ if (WriteBit(effect.DebugInfo.is_initialized()))
{
- _worldPacket << float(effect.DebugInfo->CritRollMade);
- _worldPacket << float(effect.DebugInfo->CritRollNeeded);
+ *this << float(effect.DebugInfo->CritRollMade);
+ *this << float(effect.DebugInfo->CritRollNeeded);
}
- _worldPacket.FlushBits();
+ FlushBits();
}
- _worldPacket.WriteBit(LogData.is_initialized());
- _worldPacket.FlushBits();
- if (LogData)
- _worldPacket << *LogData;
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
return &_worldPacket;
}
@@ -197,17 +180,16 @@ WorldPacket const* WorldPackets::CombatLog::SpellInterruptLog::Write()
WorldPacket const* WorldPackets::CombatLog::SpellEnergizeLog::Write()
{
- _worldPacket << CasterGUID;
- _worldPacket << TargetGUID;
+ *this << CasterGUID;
+ *this << TargetGUID;
- _worldPacket << int32(SpellID);
- _worldPacket << int32(Type);
- _worldPacket << int32(Amount);
+ *this << int32(SpellID);
+ *this << int32(Type);
+ *this << int32(Amount);
- _worldPacket.WriteBit(LogData.is_initialized());
- _worldPacket.FlushBits();
- if (LogData)
- _worldPacket << *LogData;
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
return &_worldPacket;
}
@@ -281,16 +263,74 @@ WorldPacket const* WorldPackets::CombatLog::SpellOrDamageImmune::Write()
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;
+ *this << Attacker;
+ *this << Defender;
+ *this << int32(SpellID);
+ *this << int32(TotalDamage);
+ *this << int32(OverKill);
+ *this << int32(SchoolMask);
+ *this << int32(LogAbsorbed);
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::CombatLog::AttackerStateUpdate::Write()
+{
+ ByteBuffer attackRoundInfo;
+ attackRoundInfo << HitInfo;
+ attackRoundInfo << AttackerGUID;
+ attackRoundInfo << VictimGUID;
+ attackRoundInfo << Damage;
+ attackRoundInfo << OverDamage;
+
+ if (attackRoundInfo.WriteBit(SubDmg.is_initialized()))
+ {
+ attackRoundInfo << SubDmg->SchoolMask;
+ attackRoundInfo << SubDmg->FDamage;
+ attackRoundInfo << SubDmg->Damage;
+ if (HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB))
+ attackRoundInfo << SubDmg->Absorbed;
+ if (HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST))
+ attackRoundInfo << SubDmg->Resisted;
+ }
+
+ attackRoundInfo << VictimState;
+ attackRoundInfo << AttackerState;
+ attackRoundInfo << MeleeSpellID;
+ if (HitInfo & HITINFO_BLOCK)
+ attackRoundInfo << BlockAmount;
+
+ if (HitInfo & HITINFO_RAGE_GAIN)
+ attackRoundInfo << RageGained;
+
+ if (HitInfo & HITINFO_UNK1)
+ {
+ attackRoundInfo << UnkState.State1;
+ attackRoundInfo << UnkState.State2;
+ attackRoundInfo << UnkState.State3;
+ attackRoundInfo << UnkState.State4;
+ attackRoundInfo << UnkState.State5;
+ attackRoundInfo << UnkState.State6;
+ attackRoundInfo << UnkState.State7;
+ attackRoundInfo << UnkState.State8;
+ attackRoundInfo << UnkState.State9;
+ attackRoundInfo << UnkState.State10;
+ attackRoundInfo << UnkState.State11;
+ attackRoundInfo << UnkState.State12;
+ }
+ if (HitInfo & (HITINFO_BLOCK | HITINFO_UNK12))
+ attackRoundInfo << Unk;
+
+ WriteLogDataBit();
+ FlushBits();
+ WriteLogData();
+
+ *this << uint32(attackRoundInfo.size());
+ _worldPacket.append(attackRoundInfo);
+ _fullLogPacket.append(attackRoundInfo);
- _worldPacket.FlushBits();
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h
index a181ead6d6a..408210342e3 100644
--- a/src/server/game/Server/Packets/CombatLogPackets.h
+++ b/src/server/game/Server/Packets/CombatLogPackets.h
@@ -26,10 +26,59 @@ namespace WorldPackets
{
namespace CombatLog
{
- class SpellNonMeleeDamageLog final : public ServerPacket
+ class CombatLogServerPacket : public ServerPacket
{
public:
- SpellNonMeleeDamageLog() : ServerPacket(SMSG_SPELL_NON_MELEE_DAMAGE_LOG, 60) { }
+ CombatLogServerPacket(OpcodeServer opcode, size_t initialSize = 200, ConnectionType connection = CONNECTION_TYPE_DEFAULT)
+ : ServerPacket(opcode, initialSize, connection), _fullLogPacket(opcode, initialSize, connection) { }
+
+ WorldPacket const* GetFullLogPacket() const { return &_fullLogPacket; }
+ WorldPacket const* GetBasicLogPacket() const { return &_worldPacket; }
+
+ Spells::SpellCastLogData LogData;
+
+ protected:
+ template<typename T>
+ void operator<<(T const& val)
+ {
+ _worldPacket << val;
+ _fullLogPacket << val;
+ }
+
+ void WriteLogDataBit()
+ {
+ _worldPacket.WriteBit(false);
+ _fullLogPacket.WriteBit(true);
+ }
+
+ void FlushBits()
+ {
+ _worldPacket.FlushBits();
+ _fullLogPacket.FlushBits();
+ }
+
+ bool WriteBit(bool bit)
+ {
+ _worldPacket.WriteBit(bit);
+ _fullLogPacket.WriteBit(bit);
+ return bit;
+ }
+
+ void WriteBits(uint32 value, uint32 bitCount)
+ {
+ _worldPacket.WriteBits(value, bitCount);
+ _fullLogPacket.WriteBits(value, bitCount);
+ }
+
+ ByteBuffer& WriteLogData() { return _fullLogPacket << LogData; }
+
+ WorldPacket _fullLogPacket;
+ };
+
+ class SpellNonMeleeDamageLog final : public CombatLogServerPacket
+ {
+ public:
+ SpellNonMeleeDamageLog() : CombatLogServerPacket(SMSG_SPELL_NON_MELEE_DAMAGE_LOG, 60) { }
WorldPacket const* Write() override;
@@ -41,17 +90,16 @@ namespace WorldPackets
bool Periodic = 0.0f;
uint8 SchoolMask = 0;
ObjectGuid CasterGUID;
- Optional<Spells::SpellCastLogData> LogData;
int32 Damage = 0;
// Optional<SpellNonMeleeDamageLogDebugInfo> Debug Info;
int32 Flags = 0;
int32 Overkill = 0;
};
- class EnvironmentalDamageLog final : public ServerPacket
+ class EnvironmentalDamageLog final : public CombatLogServerPacket
{
public:
- EnvironmentalDamageLog() : ServerPacket(SMSG_ENVIRONMENTAL_DAMAGE_LOG, 23) { }
+ EnvironmentalDamageLog() : CombatLogServerPacket(SMSG_ENVIRONMENTAL_DAMAGE_LOG, 23) { }
WorldPacket const* Write() override;
@@ -60,10 +108,9 @@ namespace WorldPackets
int32 Amount = 0;
int32 Resisted = 0;
int32 Absorbed = 0;
- Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false
};
- class SpellExecuteLog final : public ServerPacket
+ class SpellExecuteLog final : public CombatLogServerPacket
{
public:
struct SpellLogEffect
@@ -78,20 +125,19 @@ namespace WorldPackets
std::vector<SpellLogEffectFeedPetParams> FeedPetTargets;
};
- SpellExecuteLog() : ServerPacket(SMSG_SPELL_EXECUTE_LOG, 16 + 4 + 4 + 1) { }
+ SpellExecuteLog() : CombatLogServerPacket(SMSG_SPELL_EXECUTE_LOG, 16 + 4 + 4 + 1) { }
WorldPacket const* Write() override;
ObjectGuid Caster;
int32 SpellID = 0;
std::vector<SpellLogEffect> Effects;
- Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false
};
- class SpellHealLog final : public ServerPacket
+ class SpellHealLog final : public CombatLogServerPacket
{
public:
- SpellHealLog() : ServerPacket(SMSG_SPELL_HEAL_LOG, 16 + 16 + 4 * 4 + 1) { }
+ SpellHealLog() : CombatLogServerPacket(SMSG_SPELL_HEAL_LOG, 16 + 16 + 4 * 4 + 1) { }
WorldPacket const* Write() override;
@@ -105,10 +151,9 @@ namespace WorldPackets
bool Multistrike = false;
Optional<float> CritRollMade;
Optional<float> CritRollNeeded;
- Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false
};
- class SpellPeriodicAuraLog final : public ServerPacket
+ class SpellPeriodicAuraLog final : public CombatLogServerPacket
{
public:
struct PeriodicalAuraLogEffectDebugInfo
@@ -130,7 +175,7 @@ namespace WorldPackets
Optional<PeriodicalAuraLogEffectDebugInfo> DebugInfo;
};
- SpellPeriodicAuraLog() : ServerPacket(SMSG_SPELL_PERIODIC_AURA_LOG, 16 + 16 + 4 + 4 + 1) { }
+ SpellPeriodicAuraLog() : CombatLogServerPacket(SMSG_SPELL_PERIODIC_AURA_LOG, 16 + 16 + 4 + 4 + 1) { }
WorldPacket const* Write() override;
@@ -138,7 +183,6 @@ namespace WorldPackets
ObjectGuid CasterGUID;
int32 SpellID = 0;
std::vector<SpellLogEffect> Effects;
- Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false
};
class SpellInterruptLog final : public ServerPacket
@@ -154,10 +198,10 @@ namespace WorldPackets
int32 SpellID = 0;
};
- class SpellEnergizeLog final : public ServerPacket
+ class SpellEnergizeLog final : public CombatLogServerPacket
{
public:
- SpellEnergizeLog() : ServerPacket(SMSG_SPELL_ENERGIZE_LOG, 16 + 16 + 4 + 4 + 4 + 1) { }
+ SpellEnergizeLog() : CombatLogServerPacket(SMSG_SPELL_ENERGIZE_LOG, 16 + 16 + 4 + 4 + 4 + 1) { }
WorldPacket const* Write() override;
@@ -166,7 +210,6 @@ namespace WorldPackets
int32 SpellID = 0;
int32 Type = 0;
int32 Amount = 0;
- Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false
};
class SpellInstakillLog final : public ServerPacket
@@ -235,10 +278,10 @@ namespace WorldPackets
bool IsPeriodic = false;
};
- class SpellDamageShield final : public ServerPacket
+ class SpellDamageShield final : public CombatLogServerPacket
{
public:
- SpellDamageShield() : ServerPacket(SMSG_SPELL_DAMAGE_SHIELD, 4 + 16 + 4 + 4 + 16 + 4 + 4 + 1) { }
+ SpellDamageShield() : CombatLogServerPacket(SMSG_SPELL_DAMAGE_SHIELD, 4 + 16 + 4 + 4 + 16 + 4 + 4 + 1) { }
WorldPacket const* Write() override;
@@ -249,7 +292,53 @@ namespace WorldPackets
int32 OverKill = 0;
int32 SchoolMask = 0;
int32 LogAbsorbed = 0;
- Optional<Spells::SpellCastLogData> LogData;
+ };
+
+ struct SubDamage
+ {
+ int32 SchoolMask = 0;
+ float FDamage = 0.0f; // Float damage (Most of the time equals to Damage)
+ int32 Damage = 0;
+ int32 Absorbed = 0;
+ int32 Resisted = 0;
+ };
+
+ struct UnkAttackerState
+ {
+ int32 State1 = 0;
+ float State2 = 0.0f;
+ float State3 = 0.0f;
+ float State4 = 0.0f;
+ float State5 = 0.0f;
+ float State6 = 0.0f;
+ float State7 = 0.0f;
+ float State8 = 0.0f;
+ float State9 = 0.0f;
+ float State10 = 0.0f;
+ float State11 = 0.0f;
+ int32 State12 = 0;
+ };
+
+ class AttackerStateUpdate final : public CombatLogServerPacket
+ {
+ public:
+ AttackerStateUpdate() : CombatLogServerPacket(SMSG_ATTACKER_STATE_UPDATE, 70) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 HitInfo = 0; // Flags
+ ObjectGuid AttackerGUID;
+ ObjectGuid VictimGUID;
+ int32 Damage = 0;
+ int32 OverDamage = -1; // (damage - health) or -1 if unit is still alive
+ Optional<SubDamage> SubDmg;
+ uint8 VictimState = 0;
+ int32 AttackerState = -1;
+ int32 MeleeSpellID = 0;
+ int32 BlockAmount = 0;
+ int32 RageGained = 0;
+ UnkAttackerState UnkState;
+ float Unk = 0.0f;
};
}
}
diff --git a/src/server/game/Server/Packets/CombatPackets.cpp b/src/server/game/Server/Packets/CombatPackets.cpp
index d47f2275ee6..50527a3ec58 100644
--- a/src/server/game/Server/Packets/CombatPackets.cpp
+++ b/src/server/game/Server/Packets/CombatPackets.cpp
@@ -94,64 +94,6 @@ WorldPacket const* WorldPackets::Combat::AIReaction::Write()
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Combat::AttackerStateUpdate::Write()
-{
- if (_worldPacket.WriteBit(LogData.is_initialized()))
- _worldPacket << *LogData;
-
- // Placeholder for size which will be calculated at the end based on packet size
- // Client uses this size to copy remaining packet to another CDataStore
- _worldPacket << int32(0);
- size_t pos = _worldPacket.wpos();
-
- _worldPacket << HitInfo;
- _worldPacket << AttackerGUID;
- _worldPacket << VictimGUID;
- _worldPacket << Damage;
- _worldPacket << OverDamage;
-
- if (_worldPacket.WriteBit(SubDmg.is_initialized()))
- {
- _worldPacket << SubDmg->SchoolMask;
- _worldPacket << SubDmg->FDamage;
- _worldPacket << SubDmg->Damage;
- if (HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB))
- _worldPacket << SubDmg->Absorbed;
- if (HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST))
- _worldPacket << SubDmg->Resisted;
- }
-
- _worldPacket << VictimState;
- _worldPacket << AttackerState;
- _worldPacket << MeleeSpellID;
- if (HitInfo & HITINFO_BLOCK)
- _worldPacket << BlockAmount;
- if (HitInfo & HITINFO_RAGE_GAIN)
- _worldPacket << RageGained;
- if (HitInfo & HITINFO_UNK1)
- {
- _worldPacket << UnkState.State1;
- _worldPacket << UnkState.State2;
- _worldPacket << UnkState.State3;
- _worldPacket << UnkState.State4;
- _worldPacket << UnkState.State5;
- _worldPacket << UnkState.State6;
- _worldPacket << UnkState.State7;
- _worldPacket << UnkState.State8;
- _worldPacket << UnkState.State9;
- _worldPacket << UnkState.State10;
- _worldPacket << UnkState.State11;
- _worldPacket << UnkState.State12;
- }
- if (HitInfo & (HITINFO_BLOCK|HITINFO_UNK12))
- _worldPacket << Unk;
-
- // Update size placeholder
- _worldPacket.put<int32>(pos - sizeof(int32), _worldPacket.wpos() - pos);
-
- return &_worldPacket;
-}
-
WorldPacket const* WorldPackets::Combat::AttackSwingError::Write()
{
_worldPacket.WriteBits(Reason, 2);
diff --git a/src/server/game/Server/Packets/CombatPackets.h b/src/server/game/Server/Packets/CombatPackets.h
index deeb98fe335..a550dda4b73 100644
--- a/src/server/game/Server/Packets/CombatPackets.h
+++ b/src/server/game/Server/Packets/CombatPackets.h
@@ -130,54 +130,6 @@ namespace WorldPackets
uint32 Reaction = 0;
};
- struct SubDamage
- {
- int32 SchoolMask = 0;
- float FDamage = 0.0f; // Float damage (Most of the time equals to Damage)
- int32 Damage = 0;
- int32 Absorbed = 0;
- int32 Resisted = 0;
- };
-
- struct UnkAttackerState
- {
- int32 State1 = 0;
- float State2 = 0.0f;
- float State3 = 0.0f;
- float State4 = 0.0f;
- float State5 = 0.0f;
- float State6 = 0.0f;
- float State7 = 0.0f;
- float State8 = 0.0f;
- float State9 = 0.0f;
- float State10 = 0.0f;
- float State11 = 0.0f;
- int32 State12 = 0;
- };
-
- class AttackerStateUpdate final : public ServerPacket
- {
- public:
- AttackerStateUpdate() : ServerPacket(SMSG_ATTACKER_STATE_UPDATE, 70) { }
-
- WorldPacket const* Write() override;
-
- Optional<Spells::SpellCastLogData> LogData;
- uint32 HitInfo = 0; // Flags
- ObjectGuid AttackerGUID;
- ObjectGuid VictimGUID;
- int32 Damage = 0;
- int32 OverDamage = -1; // (damage - health) or -1 if unit is still alive
- Optional<SubDamage> SubDmg;
- uint8 VictimState = 0;
- int32 AttackerState = -1;
- int32 MeleeSpellID = 0;
- int32 BlockAmount = 0;
- int32 RageGained = 0;
- UnkAttackerState UnkState;
- float Unk = 0.0f;
- };
-
class CancelCombat final : public ServerPacket
{
public:
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 945580b0ee3..c1886bc92bc 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4083,7 +4083,7 @@ void Spell::SendSpellExecuteLog()
spellExecuteLog.Effects.push_back(spellLogEffect);
}
- m_caster->SendMessageToSet(spellExecuteLog.Write(), true);
+ m_caster->SendCombatLogMessage(&spellExecuteLog);
}
void Spell::ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit* target, uint32 powerType, uint32 points, float amplitude)