aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Combat/ThreatManager.cpp25
-rw-r--r--src/server/game/Combat/ThreatManager.h3
2 files changed, 24 insertions, 4 deletions
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index 12253e9b588..2f2351bb43f 100644
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -104,6 +104,8 @@ bool ThreatReference::ShouldBeOffline() const
bool ThreatReference::ShouldBeSuppressed() const
{
+ if (IsTaunting()) // a taunting victim can never be suppressed
+ return false;
if (_victim->IsImmunedToDamage(_owner->GetMeleeDamageSchoolMask()))
return true;
if (_victim->HasAuraType(SPELL_AURA_MOD_CONFUSE))
@@ -270,11 +272,22 @@ bool ThreatManager::IsThreateningTo(ObjectGuid const& who, bool includeOffline)
}
bool ThreatManager::IsThreateningTo(Unit const* who, bool includeOffline) const { return IsThreateningTo(who->GetGUID(), includeOffline); }
-void ThreatManager::EvaluateSuppressed()
+void ThreatManager::EvaluateSuppressed(bool canExpire)
{
for (auto const& pair : _threatenedByMe)
- if (pair.second->IsOnline() && pair.second->ShouldBeSuppressed())
+ {
+ bool const shouldBeSuppressed = pair.second->ShouldBeSuppressed();
+ if (pair.second->IsOnline() && shouldBeSuppressed)
+ {
pair.second->_online = ThreatReference::ONLINE_STATE_SUPPRESSED;
+ pair.second->HeapNotifyDecreased();
+ }
+ else if (canExpire && pair.second->IsSuppressed() && !shouldBeSuppressed)
+ {
+ pair.second->_online = ThreatReference::ONLINE_STATE_ONLINE;
+ pair.second->HeapNotifyIncreased();
+ }
+ }
}
static void SaveCreatureHomePositionIfNeed(Creature* c)
@@ -370,10 +383,13 @@ void ThreatManager::AddThreat(Unit* target, float amount, SpellInfo const* spell
if (it != _myThreatListEntries.end())
{
ThreatReference* const ref = it->second;
- // causing threat causes SUPPRESSED threat states to stop being suppressed
+ // SUPPRESSED threat states don't go back to ONLINE until threat is caused by them (retail behavior)
if (ref->GetOnlineState() == ThreatReference::ONLINE_STATE_SUPPRESSED)
if (!ref->ShouldBeSuppressed())
+ {
ref->_online = ThreatReference::ONLINE_STATE_ONLINE;
+ ref->HeapNotifyIncreased();
+ }
if (ref->IsOnline())
ref->AddThreat(amount);
@@ -444,6 +460,9 @@ void ThreatManager::TauntUpdate()
else
pair.second->UpdateTauntState();
}
+
+ // taunt aura update also re-evaluates all suppressed states (retail behavior)
+ EvaluateSuppressed(true);
}
void ThreatManager::ResetAllThreat()
diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h
index defb4a1b94e..eca5f45c804 100644
--- a/src/server/game/Combat/ThreatManager.h
+++ b/src/server/game/Combat/ThreatManager.h
@@ -141,7 +141,7 @@ class TC_GAME_API ThreatManager
auto const& GetThreatenedByMeList() const { return _threatenedByMe; }
// Notify the ThreatManager that its owner may now be suppressed on others' threat lists (immunity or damage-breakable CC being applied)
- void EvaluateSuppressed();
+ void EvaluateSuppressed(bool canExpire = false);
///== AFFECT MY THREAT LIST ==
void AddThreat(Unit* target, float amount, SpellInfo const* spell = nullptr, bool ignoreModifiers = false, bool ignoreRedirects = false);
void ScaleThreat(Unit* target, float factor);
@@ -262,6 +262,7 @@ class TC_GAME_API ThreatReference
OnlineState GetOnlineState() const { return _online; }
bool IsOnline() const { return (_online >= ONLINE_STATE_ONLINE); }
bool IsAvailable() const { return (_online > ONLINE_STATE_OFFLINE); }
+ bool IsSuppressed() const { return (_online == ONLINE_STATE_SUPPRESSED); }
bool IsOffline() const { return (_online <= ONLINE_STATE_OFFLINE); }
TauntState GetTauntState() const { return IsTaunting() ? TAUNT_STATE_TAUNT : _taunted; }
bool IsTaunting() const { return _taunted >= TAUNT_STATE_TAUNT; }