aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-05-04 10:36:56 +0200
committerShauren <shauren.trinity@gmail.com>2021-09-26 16:07:40 +0200
commit4634cfaa9f1e7064147f2c81a146234405f4e121 (patch)
tree84b2a0c425dcb7031ab3d132422c6f0f991cf0ed /src
parentf1ac141f25500a0f6ffd3c32b1185de2d9f9c940 (diff)
Core/Threat: Fix taunt behavior in some edge cases
(cherry picked from commit 1b7ec4bc841cd51e17bb21a3d4b774102f195c46)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Combat/ThreatManager.cpp56
-rw-r--r--src/server/game/Combat/ThreatManager.h8
2 files changed, 33 insertions, 31 deletions
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index d6c744dd43b..d9f3d0d4b4b 100644
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -106,26 +106,28 @@ ThreatReference::OnlineState ThreatReference::SelectOnlineState()
return ONLINE_STATE_ONLINE;
}
-void ThreatReference::UpdateTauntState(bool victimIsTaunting)
+void ThreatReference::UpdateTauntState(TauntState state)
{
- if (victimIsTaunting)
+ if (state < TAUNT_STATE_TAUNT) // not taunting
{
- _taunted = TAUNT_STATE_TAUNT;
- HeapNotifyIncreased();
- return;
+ // Check for SPELL_AURA_MOD_DETAUNT (applied from owner to victim)
+ for (AuraEffect const* eff : _victim->GetAuraEffectsByType(SPELL_AURA_MOD_DETAUNT))
+ if (eff->GetCasterGUID() == _owner->GetGUID())
+ {
+ state = TAUNT_STATE_DETAUNT;
+ break;
+ }
}
- // Check for SPELL_AURA_MOD_DETAUNT (applied from owner to victim)
- for (AuraEffect const* eff : _victim->GetAuraEffectsByType(SPELL_AURA_MOD_DETAUNT))
- if (eff->GetCasterGUID() == _owner->GetGUID())
- {
- _taunted = TAUNT_STATE_DETAUNT;
- HeapNotifyDecreased();
- return;
- }
+ if (state == _taunted)
+ return;
+
+ std::swap(state, _taunted);
- _taunted = TAUNT_STATE_NONE;
- HeapNotifyChanged();
+ if (_taunted < state)
+ HeapNotifyDecreased();
+ else
+ HeapNotifyIncreased();
}
void ThreatReference::ClearThreat(bool sendRemove)
@@ -422,21 +424,21 @@ void ThreatManager::MatchUnitThreatToHighestThreat(Unit* target)
void ThreatManager::TauntUpdate()
{
std::list<AuraEffect*> const& tauntEffects = _owner->GetAuraEffectsByType(SPELL_AURA_MOD_TAUNT);
- auto threatEnd = _myThreatListEntries.end();
- ThreatReference* tauntRef = nullptr;
+
+ uint32 state = ThreatReference::TAUNT_STATE_TAUNT;
+ std::unordered_map<ObjectGuid, ThreatReference::TauntState> tauntStates;
// Only the last taunt effect applied by something still on our threat list is considered
- for (auto it = tauntEffects.rbegin(), end = tauntEffects.rend(); it != end; ++it)
+ for (auto it = tauntEffects.begin(), end = tauntEffects.end(); it != end; ++it)
+ tauntStates[(*it)->GetCasterGUID()] = ThreatReference::TauntState(state++);
+
+ for (auto const& pair : _myThreatListEntries)
{
- auto threatIt = _myThreatListEntries.find((*it)->GetCasterGUID());
- if (threatIt == threatEnd)
- continue;
- if (!threatIt->second->IsAvailable())
- continue;
- tauntRef = threatIt->second;
- break;
+ auto it = tauntStates.find(pair.first);
+ if (it != tauntStates.end())
+ pair.second->UpdateTauntState(it->second);
+ else
+ pair.second->UpdateTauntState();
}
- for (auto const& pair : _myThreatListEntries)
- pair.second->UpdateTauntState(pair.second == tauntRef);
}
void ThreatManager::ResetAllThreat()
diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h
index 09717ff66fb..a10807cb061 100644
--- a/src/server/game/Combat/ThreatManager.h
+++ b/src/server/game/Combat/ThreatManager.h
@@ -244,7 +244,7 @@ class TC_GAME_API ThreatManager
class TC_GAME_API ThreatReference
{
public:
- enum TauntState { TAUNT_STATE_DETAUNT = -1, TAUNT_STATE_NONE = 0, TAUNT_STATE_TAUNT = 1 };
+ enum TauntState : uint32 { TAUNT_STATE_DETAUNT = 0, TAUNT_STATE_NONE = 1, TAUNT_STATE_TAUNT = 2 };
enum OnlineState { ONLINE_STATE_ONLINE = 2, ONLINE_STATE_SUPPRESSED = 1, ONLINE_STATE_OFFLINE = 0 };
Unit* GetOwner() const { return _owner; }
@@ -254,8 +254,8 @@ class TC_GAME_API ThreatReference
bool IsOnline() const { return (_online >= ONLINE_STATE_ONLINE); }
bool IsAvailable() const { return (_online > ONLINE_STATE_OFFLINE); }
bool IsOffline() const { return (_online <= ONLINE_STATE_OFFLINE); }
- TauntState GetTauntState() const { return _taunted; }
- bool IsTaunting() const { return _taunted == TAUNT_STATE_TAUNT; }
+ TauntState GetTauntState() const { return IsTaunting() ? TAUNT_STATE_TAUNT : _taunted; }
+ bool IsTaunting() const { return _taunted >= TAUNT_STATE_TAUNT; }
bool IsDetaunted() const { return _taunted == TAUNT_STATE_DETAUNT; }
void SetThreat(float amount) { _baseAmount = amount; HeapNotifyChanged(); }
@@ -270,7 +270,7 @@ class TC_GAME_API ThreatReference
ThreatReference(ThreatManager* mgr, Unit* victim, float amount) : _owner(mgr->_owner), _mgr(mgr), _victim(victim), _baseAmount(amount), _tempModifier(0), _online(SelectOnlineState()), _taunted(TAUNT_STATE_NONE) { }
static bool FlagsAllowFighting(Unit const* a, Unit const* b);
OnlineState SelectOnlineState();
- void UpdateTauntState(bool victimIsTaunting);
+ void UpdateTauntState(TauntState state = TAUNT_STATE_NONE);
Unit* const _owner;
ThreatManager* const _mgr;
void HeapNotifyIncreased() { _mgr->_sortedThreatList.increase(_handle); }