aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-08-08 15:15:14 +0200
committerShauren <shauren.trinity@gmail.com>2015-08-08 15:15:14 +0200
commitfcc8c2d12c775d51b56b280e6684f8d60d798c07 (patch)
tree1b6db969dcc257b7ca0dda6c1633e48996a93629 /src
parentc9e138d66d6a455a72d3fefbc0e4d5998bc338d6 (diff)
Core/PacketIO: Implemented advanced combat logging
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp10
-rw-r--r--src/server/game/Entities/Player/Player.h9
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp75
-rw-r--r--src/server/game/Entities/Unit/Unit.h15
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp5
-rw-r--r--src/server/game/Server/Packets/ClientConfigPackets.cpp5
-rw-r--r--src/server/game/Server/Packets/ClientConfigPackets.h10
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp8
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h4
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp32
-rw-r--r--src/server/game/Spells/Spell.cpp8
-rw-r--r--src/server/game/Spells/SpellEffects.cpp10
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp5
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp2
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp3
17 files changed, 130 insertions, 75 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a263f2664e6..32809957a6b 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -651,7 +651,7 @@ void KillRewarder::Reward()
}
-Player::Player(WorldSession* session): Unit(true)
+Player::Player(WorldSession* session) : Unit(true)
{
m_speakTime = 0;
m_speakCount = 0;
@@ -891,6 +891,8 @@ Player::Player(WorldSession* session): Unit(true)
for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i)
_CUFProfiles[i] = nullptr;
+
+ _advancedCombatLoggingEnabled = false;
}
Player::~Player()
@@ -1305,10 +1307,12 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
packet.Amount = damage;
packet.Absorbed = absorb;
packet.Resisted = resist;
- SendCombatLogMessage(&packet);
uint32 final_damage = DealDamage(this, damage, NULL, SELF_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ packet.LogData.Initialize(this);
+ SendCombatLogMessage(&packet);
+
if (!IsAlive())
{
if (type == DAMAGE_FALL) // DealDamage not apply item durability loss at self damage
@@ -23626,7 +23630,7 @@ void Player::RemoveItemDependentAurasAndCasts(Item* pItem)
InterruptSpell(CurrentSpellTypes(i));
}
-uint32 Player::GetResurrectionSpellId()
+uint32 Player::GetResurrectionSpellId() const
{
// search priceless resurrection possibilities
uint32 prio = 0;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 4dda7d05c6f..4cc78771f1e 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2153,7 +2153,7 @@ class Player : public Unit, public GridObject<Player>
void SpawnCorpseBones();
void CreateCorpse();
void KillPlayer();
- uint32 GetResurrectionSpellId();
+ uint32 GetResurrectionSpellId() const;
void ResurrectPlayer(float restore_percent, bool applySickness = false);
void BuildPlayerRepop();
void RepopAtGraveyard();
@@ -2390,7 +2390,6 @@ class Player : public Unit, public GridObject<Player>
void UpdateSpeakTime();
bool CanSpeak() const;
- void ChangeSpeakTime(int utime);
/*********************************************************/
/*** VARIOUS SYSTEMS ***/
@@ -2572,7 +2571,6 @@ class Player : public Unit, public GridObject<Player>
uint32 GetAchievementPoints() const;
bool HasAchieved(uint32 achievementId) const;
void ResetAchievements();
- void CheckAllAchievementCriteria();
void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false);
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit* unit = NULL);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
@@ -2633,7 +2631,8 @@ class Player : public Unit, public GridObject<Player>
void DeleteGarrison();
Garrison* GetGarrison() { return _garrison.get(); }
- bool HasAdvancedCombatLogging() const { return false; }
+ bool IsAdvancedCombatLoggingEnabled() const { return _advancedCombatLoggingEnabled; }
+ void SetAdvancedCombatLogging(bool enabled) { _advancedCombatLoggingEnabled = enabled; }
protected:
// Gamemaster whisper whitelist
@@ -2984,6 +2983,8 @@ class Player : public Unit, public GridObject<Player>
uint32 _maxPersonalArenaRate;
std::unique_ptr<Garrison> _garrison;
+
+ bool _advancedCombatLoggingEnabled;
};
void AddItemsSetItem(Player* player, Item* item);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 188e39e1e2b..91beb218388 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -164,6 +164,12 @@ ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget,
_damageInfo(damageInfo), _healInfo(healInfo)
{ }
+SpellNonMeleeDamage::SpellNonMeleeDamage(Unit* _attacker, Unit* _target, uint32 _SpellID, uint32 _schoolMask)
+ : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), schoolMask(_schoolMask),
+ absorb(0), resist(0), periodicLog(false), blocked(0), HitInfo(0), cleanDamage(0), preHitHealth(_target->GetHealth())
+{
+}
+
SpellInfo const* ProcEventInfo::GetSpellInfo() const
{
/// WORKAROUND: unfinished new proc system
@@ -1075,29 +1081,29 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damageInfo->damage = damage;
}
-void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss)
+uint32 Unit::DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss)
{
- if (damageInfo == 0)
- return;
+ if (!damageInfo)
+ return 0;
Unit* victim = damageInfo->target;
if (!victim)
- return;
+ return 0;
if (!victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
- return;
+ return 0;
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(damageInfo->SpellID);
- if (spellProto == NULL)
+ if (!spellProto)
{
TC_LOG_DEBUG("entities.unit", "Unit::DealSpellDamage has wrong damageInfo->SpellID: %u", damageInfo->SpellID);
- return;
+ return 0;
}
// Call default DealDamage
CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss);
+ return DealDamage(victim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss);
}
/// @todo for melee need create structure as in
@@ -1418,6 +1424,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
damageShield.LogAbsorbed = absorb;
victim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true);
+
+ damageShield.LogData.Initialize(this);
victim->SendCombatLogMessage(&damageShield);
}
}
@@ -1775,10 +1783,12 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
uint32 split_absorb = 0;
DealDamageMods(caster, splitDamage, &split_absorb);
- SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitDamage, schoolMask, split_absorb, 0, false, 0, false);
-
+ SpellNonMeleeDamage log(this, caster, (*itr)->GetSpellInfo()->Id, schoolMask);
CleanDamage cleanDamage = CleanDamage(splitDamage, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false);
+ log.damage = DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false);
+ log.absorb = split_absorb;
+ SendSpellNonMeleeDamageLog(&log);
+
// break 'Fear' and similar auras
caster->ProcDamageAndSpellFor(true, this, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_EX_NORMAL_HIT, BASE_ATTACK, (*itr)->GetSpellInfo(), splitDamage);
}
@@ -4807,37 +4817,27 @@ void Unit::RemoveAllGameObjects()
}
}
-void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log)
+void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage const* log)
{
WorldPackets::CombatLog::SpellNonMeleeDamageLog packet;
packet.Me = log->target->GetGUID();
packet.CasterGUID = log->attacker->GetGUID();
packet.SpellID = log->SpellID;
packet.Damage = log->damage;
- int32 overkill = log->damage - log->target->GetHealth();
- packet.Overkill = (overkill > 0 ? overkill : 0);
+ if (log->damage > log->preHitHealth)
+ packet.Overkill = log->damage - log->preHitHealth;
+ else
+ packet.Overkill = 0;
+
packet.SchoolMask = log->schoolMask;
packet.ShieldBlock = log->blocked;
packet.Resisted = log->resist;
packet.Absorbed = log->absorb;
- packet.Periodic = false;
+ packet.Periodic = log->periodicLog;
packet.Flags = log->HitInfo;
SendCombatLogMessage(&packet);
}
-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;
- log.absorb = AbsorbedDamage;
- log.resist = Resist;
- log.physicalLog = PhysicalDamage;
- log.blocked = Blocked;
- if (CriticalHit)
- log.HitInfo |= SPELL_HIT_TYPE_CRIT;
- SendSpellNonMeleeDamageLog(&log);
-}
-
void Unit::ProcDamageAndSpell(Unit* victim, uint32 procAttacker, uint32 procVictim, uint32 procExtra, uint32 amount, WeaponAttackType attType, SpellInfo const* procSpell, SpellInfo const* procAura)
{
// Not much to do if no flags are set.
@@ -4856,6 +4856,7 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* info)
data.TargetGUID = GetGUID();
data.CasterGUID = aura->GetCasterGUID();
data.SpellID = aura->GetId();
+ data.LogData.Initialize(this);
/// @todo: should send more logs in one packet when multistrike
WorldPackets::CombatLog::SpellPeriodicAuraLog::SpellLogEffect spellLogEffect;
@@ -4922,6 +4923,8 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
packet.VictimState = damageInfo->TargetState;
packet.BlockAmount = damageInfo->blocked_amount;
+ packet.LogData.Initialize(damageInfo->attacker);
+
SendCombatLogMessage(&packet);
}
@@ -6111,8 +6114,10 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (pPet && pPet->GetVictim() && damage && procSpell)
{
uint32 procDmg = damage / 2;
- pPet->SendSpellNonMeleeDamageLog(pPet->GetVictim(), procSpell->Id, procDmg, procSpell->GetSchoolMask(), 0, 0, false, 0, false);
- pPet->DealDamage(pPet->GetVictim(), procDmg, NULL, SPELL_DIRECT_DAMAGE, procSpell->GetSchoolMask(), procSpell, true);
+
+ SpellNonMeleeDamage log(pPet, pPet->GetVictim(), procSpell->Id, procSpell->GetSchoolMask());
+ log.damage = pPet->DealDamage(pPet->GetVictim(), procDmg, NULL, SPELL_DIRECT_DAMAGE, procSpell->GetSchoolMask(), procSpell, true);
+ pPet->SendSpellNonMeleeDamageLog(&log);
break;
}
else
@@ -8135,6 +8140,8 @@ void Unit::SendHealSpellLog(Unit* victim, uint32 spellID, uint32 health, uint32
if (hasLogData)
SpellParsers.ReadSpellCastLogData(packet);
*/
+
+ spellHealLog.LogData.Initialize(victim);
SendCombatLogMessage(&spellHealLog);
}
@@ -8157,18 +8164,18 @@ void Unit::SendEnergizeSpellLog(Unit* victim, uint32 spellId, int32 damage, Powe
data.SpellID = spellId;
data.Type = powerType;
data.Amount = damage;
-
+ data.LogData.Initialize(victim);
SendCombatLogMessage(&data);
}
void Unit::EnergizeBySpell(Unit* victim, uint32 spellId, int32 damage, Powers powerType)
{
- SendEnergizeSpellLog(victim, spellId, damage, powerType);
- // needs to be called after sending spell log
victim->ModifyPower(powerType, damage);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo);
+
+ SendEnergizeSpellLog(victim, spellId, damage, powerType);
}
uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack) const
@@ -16453,7 +16460,7 @@ struct CombatLogSender
if (!player->HaveAtClient(i_source))
return;
- if (player->HasAdvancedCombatLogging())
+ if (player->IsAdvancedCombatLoggingEnabled())
player->SendDirectMessage(i_message->GetFullLogPacket());
else
player->SendDirectMessage(i_message->GetBasicLogPacket());
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index e2da54a868d..af2cad003b9 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1033,25 +1033,21 @@ struct CalcDamageInfo
// Spell damage info structure based on structure sending in SMSG_SPELLNONMELEEDAMAGELOG opcode
struct SpellNonMeleeDamage
{
- SpellNonMeleeDamage(Unit* _attacker, Unit* _target, uint32 _SpellID, uint32 _schoolMask)
- : target(_target), attacker(_attacker), SpellID(_SpellID), damage(0), overkill(0), schoolMask(_schoolMask),
- absorb(0), resist(0), physicalLog(false), unused(false), blocked(0), HitInfo(0), cleanDamage(0)
- { }
+ SpellNonMeleeDamage(Unit* _attacker, Unit* _target, uint32 _SpellID, uint32 _schoolMask);
Unit *target;
Unit *attacker;
uint32 SpellID;
uint32 damage;
- uint32 overkill;
uint32 schoolMask;
uint32 absorb;
uint32 resist;
- bool physicalLog;
- bool unused;
+ bool periodicLog;
uint32 blocked;
uint32 HitInfo;
// Used for help
uint32 cleanDamage;
+ uint32 preHitHealth;
};
struct SpellPeriodicAuraLogInfo
@@ -1520,7 +1516,7 @@ class Unit : public WorldObject
void HandleProcExtraAttackFor(Unit* victim);
void CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = BASE_ATTACK, bool crit = false);
- void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss);
+ uint32 DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss);
// player or player's pet resilience (-1%)
uint32 GetDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, 1.0f, 100.0f, damage); }
@@ -1629,8 +1625,7 @@ class 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(SpellNonMeleeDamage const* log);
void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo);
void SendSpellMiss(Unit* target, uint32 spellID, SpellMissInfo missInfo);
void SendSpellDamageResist(Unit* target, uint32 spellId);
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 4c93eb2c454..48ce07f3668 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1230,3 +1230,8 @@ void WorldSession::SendLoadCUFProfiles()
loadCUFProfiles.CUFProfiles.push_back(cufProfile);
SendPacket(loadCUFProfiles.Write());
}
+
+void WorldSession::HandleSetAdvancedCombatLogging(WorldPackets::ClientConfig::SetAdvancedCombatLogging& setAdvancedCombatLogging)
+{
+ _player->SetAdvancedCombatLogging(setAdvancedCombatLogging.Enable);
+}
diff --git a/src/server/game/Server/Packets/ClientConfigPackets.cpp b/src/server/game/Server/Packets/ClientConfigPackets.cpp
index 2ff1bd236f8..74ff955f5d7 100644
--- a/src/server/game/Server/Packets/ClientConfigPackets.cpp
+++ b/src/server/game/Server/Packets/ClientConfigPackets.cpp
@@ -127,3 +127,8 @@ void WorldPackets::ClientConfig::UserClientUpdateAccountData::Read()
_worldPacket.read(CompressedData.contents(), compressedSize);
}
}
+
+void WorldPackets::ClientConfig::SetAdvancedCombatLogging::Read()
+{
+ Enable = _worldPacket.ReadBit();
+}
diff --git a/src/server/game/Server/Packets/ClientConfigPackets.h b/src/server/game/Server/Packets/ClientConfigPackets.h
index a1ed1a355bb..12550a3096b 100644
--- a/src/server/game/Server/Packets/ClientConfigPackets.h
+++ b/src/server/game/Server/Packets/ClientConfigPackets.h
@@ -99,6 +99,16 @@ namespace WorldPackets
uint8 DataType = 0; ///< @see enum AccountDataType
ByteBuffer CompressedData;
};
+
+ class SetAdvancedCombatLogging final : public ClientPacket
+ {
+ public:
+ SetAdvancedCombatLogging(WorldPacket&& packet) : ClientPacket(CMSG_SET_ADVANCED_COMBAT_LOGGING, std::move(packet)) { }
+
+ void Read() override;
+
+ bool Enable = false;
+ };
}
}
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index 91821780575..2f7bec3d3ba 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -77,6 +77,14 @@ WorldPacket const* WorldPackets::Spells::SendUnlearnSpells::Write()
return &_worldPacket;
}
+void WorldPackets::Spells::SpellCastLogData::Initialize(Unit const* unit)
+{
+ Health = unit->GetHealth();
+ AttackPower = unit->GetTotalAttackPowerValue(unit->getClass() == CLASS_HUNTER ? RANGED_ATTACK : BASE_ATTACK);
+ SpellPower = unit->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SPELL);
+ PowerData.emplace_back(int32(unit->getPowerType()), unit->GetPower(unit->getPowerType()));
+}
+
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData const& spellCastLogData)
{
data << spellCastLogData.Health;
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index f5df5e32da0..fbd53c0527c 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -135,6 +135,8 @@ namespace WorldPackets
struct SpellLogPowerData
{
+ SpellLogPowerData(int32 powerType, int32 amount) : PowerType(powerType), Amount(amount) { }
+
int32 PowerType = 0;
int32 Amount = 0;
};
@@ -145,6 +147,8 @@ namespace WorldPackets
int32 AttackPower = 0;
int32 SpellPower = 0;
std::vector<SpellLogPowerData> PowerData;
+
+ void Initialize(Unit const* unit);
};
struct AuraDataInfo
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index c30f81b7f6c..a0c26fe749a 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -711,7 +711,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SET_ACTION_BUTTON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::SetActionButton, &WorldSession::HandleSetActionButtonOpcode);
DEFINE_HANDLER(CMSG_SET_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Movement::SetActiveMover, &WorldSession::HandleSetActiveMoverOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel );
- DEFINE_HANDLER(CMSG_SET_ADVANCED_COMBAT_LOGGING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_SET_ADVANCED_COMBAT_LOGGING, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::ClientConfig::SetAdvancedCombatLogging, &WorldSession::HandleSetAdvancedCombatLogging);
DEFINE_HANDLER(CMSG_SET_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Party::SetAssistantLeader, &WorldSession::HandleSetAssistantLeaderOpcode);
DEFINE_HANDLER(CMSG_SET_BACKPACK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SET_BANK_AUTOSORT_DISABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index f7d4fa0bbe4..ed39993fd45 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -181,6 +181,7 @@ namespace WorldPackets
{
class RequestAccountData;
class UserClientUpdateAccountData;
+ class SetAdvancedCombatLogging;
}
namespace Channel
@@ -1091,6 +1092,7 @@ class WorldSession
void HandleUpdateAccountData(WorldPackets::ClientConfig::UserClientUpdateAccountData& packet);
void HandleRequestAccountData(WorldPackets::ClientConfig::RequestAccountData& request);
+ void HandleSetAdvancedCombatLogging(WorldPackets::ClientConfig::SetAdvancedCombatLogging& setAdvancedCombatLogging);
void HandleSetActionButtonOpcode(WorldPackets::Spells::SetActionButton& packet);
void HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUse& packet);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 8f16af2a7b8..1550510123e 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -6085,11 +6085,10 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
overkill = 0;
SpellPeriodicAuraLogInfo pInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
- target->SendPeriodicAuraLog(&pInfo);
caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo());
-
caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
+ target->SendPeriodicAuraLog(&pInfo);
}
bool AuraEffect::IsAreaAuraEffect() const
@@ -6172,7 +6171,13 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s health leech of %s for %u dmg inflicted by %u abs is %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb);
- caster->SendSpellNonMeleeDamageLog(target, GetId(), damage, GetSpellInfo()->GetSchoolMask(), absorb, resist, false, 0, crit);
+ SpellNonMeleeDamage log(caster, target, GetId(), GetSpellInfo()->GetSchoolMask());
+ log.damage = damage - absorb - resist;
+ log.absorb = absorb;
+ log.resist = resist;
+ log.periodicLog = true;
+ if (crit)
+ log.HitInfo |= SPELL_HIT_TYPE_CRIT;
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
@@ -6194,6 +6199,9 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
int32 gain = caster->HealBySpell(caster, GetSpellInfo(), heal);
caster->getHostileRefManager().threatAssist(caster, gain * 0.5f, GetSpellInfo());
}
+
+ log.damage = new_damage;
+ caster->SendSpellNonMeleeDamageLog(&log);
}
void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster) const
@@ -6346,7 +6354,6 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
SpellPeriodicAuraLogInfo pInfo(this, drainedAmount, 0, 0, 0, gainMultiplier, false);
- target->SendPeriodicAuraLog(&pInfo);
int32 gainAmount = int32(drainedAmount * gainMultiplier);
int32 gainedAmount = 0;
@@ -6370,6 +6377,8 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
caster->CastCustomSpell(caster, 32554, &feedAmount, NULL, NULL, true, NULL, this);
}
}
+
+ target->SendPeriodicAuraLog(&pInfo);
}
void AuraEffect::HandleObsModPowerAuraTick(Unit* target, Unit* caster) const
@@ -6399,12 +6408,12 @@ void AuraEffect::HandleObsModPowerAuraTick(Unit* target, Unit* caster) const
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), amount, GetId());
SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f, false);
- target->SendPeriodicAuraLog(&pInfo);
-
int32 gain = target->ModifyPower(powerType, amount);
if (caster)
target->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellInfo());
+
+ target->SendPeriodicAuraLog(&pInfo);
}
void AuraEffect::HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) const
@@ -6431,12 +6440,12 @@ void AuraEffect::HandlePeriodicEnergizeAuraTick(Unit* target, Unit* caster) cons
int32 amount = std::max(m_amount, 0);
SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f, false);
- target->SendPeriodicAuraLog(&pInfo);
TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s energize %s for %u dmg inflicted by %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), amount, GetId());
int32 gain = target->ModifyPower(powerType, amount);
+ target->SendPeriodicAuraLog(&pInfo);
if (caster)
target->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellInfo());
@@ -6470,8 +6479,6 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
- caster->SendSpellNonMeleeDamageLog(&damageInfo);
-
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
@@ -6481,7 +6488,8 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
caster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto);
- caster->DealSpellDamage(&damageInfo, true);
+ damageInfo.damage = caster->DealSpellDamage(&damageInfo, true);
+ caster->SendSpellNonMeleeDamageLog(&damageInfo);
}
void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
@@ -6524,9 +6532,9 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv
damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE, GetSpellEffectInfo());
target->CalculateSpellDamageTaken(&damageInfo, damage, GetSpellInfo());
target->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
- target->SendSpellNonMeleeDamageLog(&damageInfo);
TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerDamageAuraProc: Triggering %u spell damage from aura %u proc", damage, GetId());
- target->DealSpellDamage(&damageInfo, true);
+ damageInfo.damage = target->DealSpellDamage(&damageInfo, true);
+ target->SendSpellNonMeleeDamageLog(&damageInfo);
}
void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcEventInfo& /*eventInfo*/)
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index c1886bc92bc..26da12b1840 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2417,9 +2417,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
- // Send log damage message to client
- caster->SendSpellNonMeleeDamageLog(&damageInfo);
-
procEx |= createProcExtendMask(&damageInfo, missInfo);
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
@@ -2434,7 +2431,10 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
m_damage = damageInfo.damage;
- caster->DealSpellDamage(&damageInfo, true);
+ damageInfo.damage = caster->DealSpellDamage(&damageInfo, true);
+
+ // Send log damage message to client
+ caster->SendSpellNonMeleeDamageLog(&damageInfo);
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 23d183330f2..3f96dc551d3 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -391,10 +391,14 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/)
uint32 resist = 0;
m_caster->CalcAbsorbResist(unitTarget, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo);
-
- m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false);
+ SpellNonMeleeDamage log(m_caster, unitTarget, m_spellInfo->Id, m_spellInfo->GetSchoolMask());
+ log.damage = damage - absorb - resist;
+ log.absorb = absorb;
+ log.resist = resist;
if (unitTarget->GetTypeId() == TYPEID_PLAYER)
- unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage);
+ log.damage = unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage);
+
+ m_caster->SendSpellNonMeleeDamageLog(&log);
}
void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 83c8d55aec3..a16d4324b87 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -2294,7 +2294,7 @@ public:
handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb);
handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false);
- handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
+ handler->GetSession()->GetPlayer()->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0);
return true;
}
@@ -2306,9 +2306,10 @@ public:
return false;
SpellNonMeleeDamage damageInfo(handler->GetSession()->GetPlayer(), target, spellid, sSpellMgr->GetSpellInfo(spellid)->SchoolMask);
+ damageInfo.damage = damage;
handler->GetSession()->GetPlayer()->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ damageInfo.damage = target->DealSpellDamage(&damageInfo, true);
target->SendSpellNonMeleeDamageLog(&damageInfo);
- target->DealSpellDamage(&damageInfo, true);
return true;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 423c1049452..c53906b5b38 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -1093,8 +1093,8 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
SpellNonMeleeDamage damageInfo(GetCaster(), GetHitUnit(), GetSpellInfo()->Id, GetSpellInfo()->SchoolMask);
damageInfo.damage = damage;
+ damageInfo.damage = GetCaster()->DealSpellDamage(&damageInfo, false);
GetCaster()->SendSpellNonMeleeDamageLog(&damageInfo);
- GetCaster()->DealSpellDamage(&damageInfo, false);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index a93d23fa233..ce3153f48ab 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -794,9 +794,10 @@ class spell_warl_health_funnel : public SpellScriptLoader
modOwner->ApplySpellMod(GetId(), SPELLMOD_COST, damage);
SpellNonMeleeDamage damageInfo(caster, caster, GetSpellInfo()->Id, GetSpellInfo()->SchoolMask);
+ damageInfo.periodicLog = true;
damageInfo.damage = damage;
+ damageInfo.damage = caster->DealSpellDamage(&damageInfo, false);
caster->SendSpellNonMeleeDamageLog(&damageInfo);
- caster->DealSpellDamage(&damageInfo, false);
}
void Register() override