aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Combat/ThreatManager.cpp30
-rw-r--r--src/server/game/Combat/ThreatManager.h7
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp26
3 files changed, 51 insertions, 12 deletions
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index ad1c513ffd1..82e98c91dbf 100644
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -459,10 +459,36 @@ void ThreatManager::ClearAllThreat()
while (!_myThreatListEntries.empty());
}
+void ThreatManager::FixtateTarget(Unit* target)
+{
+ if (target)
+ {
+ auto it = _myThreatListEntries.find(target->GetGUID());
+ if (it != _myThreatListEntries.end())
+ {
+ _fixtateRef = it->second;
+ return;
+ }
+ }
+ _fixtateRef = nullptr;
+}
+
+Unit* ThreatManager::GetFixtateTarget() const
+{
+ if (_fixtateRef)
+ return _fixtateRef->GetVictim();
+ else
+ return nullptr;
+}
+
ThreatReference const* ThreatManager::ReselectVictim()
{
+ // fixtated target is always preferred
+ if (_fixtateRef && _fixtateRef->IsAvailable())
+ return _fixtateRef;
+
ThreatReference const* oldVictimRef = _currentVictimRef;
- if (oldVictimRef && !oldVictimRef->IsAvailable())
+ if (oldVictimRef && oldVictimRef->IsOffline())
oldVictimRef = nullptr;
// in 99% of cases - we won't need to actually look at anything beyond the first element
ThreatReference const* highest = _sortedThreatList.top();
@@ -705,6 +731,8 @@ void ThreatManager::PurgeThreatListRef(ObjectGuid const& guid, bool sendRemove)
if (_currentVictimRef == ref)
_currentVictimRef = nullptr;
+ if (_fixtateRef == ref)
+ _fixtateRef = nullptr;
_sortedThreatList.erase(ref->_handle);
if (sendRemove && ref->IsAvailable())
diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h
index a10807cb061..a3755fdf167 100644
--- a/src/server/game/Combat/ThreatManager.h
+++ b/src/server/game/Combat/ThreatManager.h
@@ -160,6 +160,12 @@ class TC_GAME_API ThreatManager
// Removes all targets from the threat list (will cause evade in UpdateVictim if called)
void ClearAllThreat();
+ // Fixtate on the passed target; this target will always be selected until the fixtate is cleared
+ // (if the target is not in the threat list, does nothing)
+ void FixtateTarget(Unit* target);
+ void ClearFixtate() { FixtateTarget(nullptr); }
+ Unit* GetFixtateTarget() const;
+
// sends SMSG_THREAT_UPDATE to all nearby clients (used by client to forward threat list info to addons)
void SendThreatListToClients() const;
@@ -204,6 +210,7 @@ class TC_GAME_API ThreatManager
std::unordered_map<ObjectGuid, ThreatReference*> _myThreatListEntries;
ThreatReference const* _currentVictimRef;
ThreatReference const* ReselectVictim();
+ ThreatReference const* _fixtateRef;
///== OTHERS' THREAT LISTS ==
void PutThreatenedByMeRef(ObjectGuid const& guid, ThreatReference* ref);
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 67490c05f7d..7057d642908 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -889,6 +889,7 @@ public:
handler->PSendSysMessage("%s (%s, SpawnID " UI64FMTD ") is not engaged, but still has a threat list? Well, here it is:", target->GetName().c_str(), target->GetGUID().ToString().c_str(), target->GetTypeId() == TYPEID_UNIT ? target->ToCreature()->GetSpawnId() : 0);
count = 0;
+ Unit* fixtateVictim = mgr.GetFixtateTarget();
for (ThreatReference const* ref : mgr.GetSortedThreatList())
{
Unit* unit = ref->GetVictim();
@@ -905,17 +906,20 @@ public:
onlineStr = "";
}
char const* tauntStr;
- switch (ref->GetTauntState())
- {
- case ThreatReference::TAUNT_STATE_TAUNT:
- tauntStr = " [TAUNT]";
- break;
- case ThreatReference::TAUNT_STATE_DETAUNT:
- tauntStr = " [DETAUNT]";
- break;
- default:
- tauntStr = "";
- }
+ if (unit == fixtateVictim)
+ tauntStr = " [FIXTATE]";
+ else
+ switch (ref->GetTauntState())
+ {
+ case ThreatReference::TAUNT_STATE_TAUNT:
+ tauntStr = " [TAUNT]";
+ break;
+ case ThreatReference::TAUNT_STATE_DETAUNT:
+ tauntStr = " [DETAUNT]";
+ break;
+ default:
+ tauntStr = "";
+ }
handler->PSendSysMessage(" %u. %s (%s) - threat %f%s%s", ++count, unit->GetName().c_str(), unit->GetGUID().ToString().c_str(), ref->GetThreat(), tauntStr, onlineStr);
}
handler->SendSysMessage("End of threat list.");