From 9baa31bc04d13f8e8e91d5d73f34f432d17d9dd2 Mon Sep 17 00:00:00 2001 From: Lynx3d Date: Mon, 17 Jan 2011 16:42:10 +0100 Subject: [PATCH] [11028] Implement proper bonus threat distribution for spells not (only) affecting the primary target. --- src/game/Spell.cpp | 60 +++++++++++++++++++++++++++++++++------- src/game/Spell.h | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 1719b181a..7cb595f9c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3162,7 +3162,7 @@ uint64 Spell::handle_delayed(uint64 t_offset) void Spell::_handle_immediate_phase() { // handle some immediate features of the spell here - HandleThreatSpells(m_spellInfo->Id); + HandleThreatSpells(); m_needSpellLog = IsNeedSendToClient(); for(int j = 0; j < MAX_EFFECT_INDEX; ++j) @@ -4219,26 +4219,66 @@ void Spell::TakeReagents() } } -void Spell::HandleThreatSpells(uint32 spellId) +void Spell::HandleThreatSpells() { - if(!m_targets.getUnitTarget() || !spellId) + if (m_UniqueTargetInfo.empty()) return; - if(!m_targets.getUnitTarget()->CanHaveThreatList()) - return; + SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(m_spellInfo->Id); - SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(spellId); - - if(!threatEntry || (!threatEntry->threat && threatEntry->ap_bonus == 0.0f)) + if (!threatEntry || (!threatEntry->threat && threatEntry->ap_bonus == 0.0f)) return; float threat = threatEntry->threat; if (threatEntry->ap_bonus != 0.0f) threat += threatEntry->ap_bonus * m_caster->GetTotalAttackPowerValue(GetWeaponAttackType(m_spellInfo)); - m_targets.getUnitTarget()->AddThreat(m_caster, threat, false, GetSpellSchoolMask(m_spellInfo), m_spellInfo); + bool positive = true; + uint8 effectMask = 0; + for (int i = 0; i < MAX_EFFECT_INDEX; ++i) + if (m_spellInfo->Effect[i]) + effectMask |= (1<Id, sSpellMgr.GetSpellRank(m_spellInfo->Id)); + return; + } + positive = false; + } + + // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus + threat /= m_UniqueTargetInfo.size(); + + for (std::list::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + { + if (ihit->missCondition != SPELL_MISS_NONE) + continue; + + Unit* target = m_caster->GetObjectGuid() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID); + if (!target) + continue; + + // positive spells distribute threat among all units that are in combat with target, like healing + if (positive) + { + target->getHostileRefManager().threatAssist(m_caster /*real_caster ??*/, threat, m_spellInfo); + } + // for negative spells threat gets distributed among affected targets + else + { + if (!target->CanHaveThreatList()) + continue; + + target->AddThreat(m_caster, threat, false, GetSpellSchoolMask(m_spellInfo), m_spellInfo); + } + } + + DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, positive ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size())); } void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,SpellEffectIndex i, float DamageMultiplier) diff --git a/src/game/Spell.h b/src/game/Spell.h index ea9894051..0141a1f98 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -423,7 +423,7 @@ class Spell void SendPlaySpellVisual(uint32 SpellID); void HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,SpellEffectIndex i, float DamageMultiplier = 1.0); - void HandleThreatSpells(uint32 spellId); + void HandleThreatSpells(); //void HandleAddAura(Unit* Target); SpellEntry const* m_spellInfo; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0e4cf4332..8b8cdcf28 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11027" + #define REVISION_NR "11028" #endif // __REVISION_NR_H__