mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Threat: Fix taunt behavior in some edge cases
(cherry picked from commit 1b7ec4bc84)
This commit is contained in:
@@ -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;
|
||||
|
||||
_taunted = TAUNT_STATE_NONE;
|
||||
HeapNotifyChanged();
|
||||
std::swap(state, _taunted);
|
||||
|
||||
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)
|
||||
{
|
||||
auto threatIt = _myThreatListEntries.find((*it)->GetCasterGUID());
|
||||
if (threatIt == threatEnd)
|
||||
continue;
|
||||
if (!threatIt->second->IsAvailable())
|
||||
continue;
|
||||
tauntRef = threatIt->second;
|
||||
break;
|
||||
}
|
||||
for (auto it = tauntEffects.begin(), end = tauntEffects.end(); it != end; ++it)
|
||||
tauntStates[(*it)->GetCasterGUID()] = ThreatReference::TauntState(state++);
|
||||
|
||||
for (auto const& pair : _myThreatListEntries)
|
||||
pair.second->UpdateTauntState(pair.second == tauntRef);
|
||||
{
|
||||
auto it = tauntStates.find(pair.first);
|
||||
if (it != tauntStates.end())
|
||||
pair.second->UpdateTauntState(it->second);
|
||||
else
|
||||
pair.second->UpdateTauntState();
|
||||
}
|
||||
}
|
||||
|
||||
void ThreatManager::ResetAllThreat()
|
||||
|
||||
@@ -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); }
|
||||
|
||||
Reference in New Issue
Block a user