Core/Threat: Fix taunt behavior in some edge cases

This commit is contained in:
Treeston
2018-05-04 10:36:56 +02:00
parent 081eab3cf5
commit 1b7ec4bc84
2 changed files with 34 additions and 32 deletions

View File

@@ -108,26 +108,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)
@@ -414,21 +416,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()

View File

@@ -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); }