Core/Combat: reset the ThreatManager update interval upon engaging the creature and move ThreatClear packet sending into the update cycle to mimic retail behavior (#29949)

This commit is contained in:
Ovahlord
2024-05-02 22:50:20 +02:00
committed by GitHub
parent b7e94166fa
commit 24bda9c73d
3 changed files with 26 additions and 5 deletions

View File

@@ -189,7 +189,7 @@ void ThreatReference::HeapNotifyDecreased()
return true;
}
ThreatManager::ThreatManager(Unit* owner) : _owner(owner), _ownerCanHaveThreatList(false), _needClientUpdate(false), _updateTimer(THREAT_UPDATE_INTERVAL),
ThreatManager::ThreatManager(Unit* owner) : _owner(owner), _ownerCanHaveThreatList(false), _needClientUpdate(false), _needThreatClearUpdate(false), _updateTimer(THREAT_UPDATE_INTERVAL),
_sortedThreatList(std::make_unique<Heap>()), _currentVictimRef(nullptr), _fixateRef(nullptr)
{
for (int8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
@@ -210,17 +210,31 @@ void ThreatManager::Initialize()
void ThreatManager::Update(uint32 tdiff)
{
if (!CanHaveThreatList() || IsThreatListEmpty(true))
if (!CanHaveThreatList())
return;
if (_updateTimer <= tdiff)
{
UpdateVictim();
if (_needThreatClearUpdate)
{
SendClearAllThreatToClients();
_needThreatClearUpdate = false;
}
if (!IsThreatListEmpty(true))
UpdateVictim();
_updateTimer = THREAT_UPDATE_INTERVAL;
}
else
_updateTimer -= tdiff;
}
void ThreatManager::ResetUpdateTimer()
{
_updateTimer = THREAT_UPDATE_INTERVAL;
}
Unit* ThreatManager::GetCurrentVictim()
{
if (!_currentVictimRef || _currentVictimRef->ShouldBeOffline())
@@ -539,7 +553,7 @@ void ThreatManager::ClearAllThreat()
{
if (!_myThreatListEntries.empty())
{
SendClearAllThreatToClients();
_needThreatClearUpdate = true;
do
_myThreatListEntries.begin()->second->UnregisterAndFree();
while (!_myThreatListEntries.empty());

View File

@@ -95,6 +95,9 @@ class TC_GAME_API ThreatManager
// called from Creature::Update (only creatures can have their own threat list)
// should not be called from anywhere else
void Update(uint32 tdiff);
// called from Creature::AtEngage
// should not be called from anywhere else
void ResetUpdateTimer();
// never nullptr
Unit* GetOwner() const { return _owner; }
@@ -197,6 +200,7 @@ class TC_GAME_API ThreatManager
void PurgeThreatListRef(ObjectGuid const& guid);
bool _needClientUpdate;
bool _needThreatClearUpdate;
uint32 _updateTimer;
std::unique_ptr<Heap> _sortedThreatList;
std::unordered_map<ObjectGuid, ThreatReference*> _myThreatListEntries;

View File

@@ -743,6 +743,8 @@ void Creature::Update(uint32 diff)
UpdateMovementCapabilities();
GetThreatManager().Update(diff);
switch (m_deathState)
{
case JUST_RESPAWNED:
@@ -829,7 +831,6 @@ void Creature::Update(uint32 diff)
if (!IsAlive())
break;
GetThreatManager().Update(diff);
if (_spellFocusInfo.Delay)
{
if (_spellFocusInfo.Delay <= diff)
@@ -3595,6 +3596,8 @@ void Creature::AtEngage(Unit* target)
{
Unit::AtEngage(target);
GetThreatManager().ResetUpdateTimer();
if (!HasFlag(CREATURE_STATIC_FLAG_2_ALLOW_MOUNTED_COMBAT))
Dismount();