diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 118 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 9 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.cpp | 278 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.h | 131 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatPackets.cpp | 58 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatPackets.h | 48 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 2 |
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) |