mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-30 21:57:01 +01:00
Scripts/Commands: New command: .debug threatinfo
# Conflicts: # sql/base/auth_database.sql # sql/old/4.3.4/auth/19_2017_06_18/2018_01_09_00_auth.sql # sql/old/4.3.4/world/23_2017_11_15/2018_01_09_00_world.sql # src/server/game/Accounts/RBAC.h # src/server/game/Combat/ThreatManager.h
This commit is contained in:
@@ -962,9 +962,8 @@ INSERT INTO `rbac_linked_permissions` VALUES
|
||||
(196,843),
|
||||
(196,866),
|
||||
(196,867),
|
||||
(196,872),
|
||||
(196,873),
|
||||
(197,232),
|
||||
(196,870),(196,872),
|
||||
(196,873),(197,232),
|
||||
(197,236),
|
||||
(197,237),
|
||||
(197,273),
|
||||
@@ -1847,6 +1846,7 @@ INSERT INTO `rbac_permissions` VALUES
|
||||
(865,'Command: npc showloot'),
|
||||
(866,'Command: list spawnpoints'),
|
||||
(867,'Command: reload quest_greeting_locale'),
|
||||
(870,'Command: debug threatinfo');
|
||||
(872,'Command: server debug'),
|
||||
(873,'Command: reload creature_movement_override');
|
||||
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_THREATMANAGER_H
|
||||
#define TRINITY_THREATMANAGER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "IteratorPair.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "SharedDefines.h"
|
||||
#include <array>
|
||||
#include <boost/heap/fibonacci_heap.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@@ -82,8 +80,9 @@ struct CompareThreatLessThan
|
||||
// Please check Game/Combat/ThreatManager.h for documentation on how this class works!
|
||||
class TC_GAME_API ThreatManager
|
||||
{
|
||||
public:
|
||||
typedef boost::heap::fibonacci_heap<ThreatReference const*, boost::heap::compare<CompareThreatLessThan>> threat_list_heap;
|
||||
public:
|
||||
typedef boost::heap::fibonacci_heap<ThreatReference const*, boost::heap::compare<CompareThreatLessThan>> threat_list_heap;
|
||||
static const uint32 CLIENT_THREAT_UPDATE_INTERVAL = 1000u;
|
||||
|
||||
static bool CanHaveThreatList(Unit const* who);
|
||||
|
||||
@@ -99,180 +98,178 @@ public:
|
||||
// never nullptr
|
||||
Unit* GetOwner() const { return _owner; }
|
||||
// can our owner have a threat list?
|
||||
// never nullptr
|
||||
Unit* GetOwner() const { return _owner; }
|
||||
// can our owner have a threat list?
|
||||
// identical to ThreatManager::CanHaveThreatList(GetOwner())
|
||||
bool CanHaveThreatList() const { return _ownerCanHaveThreatList; }
|
||||
// returns the victim selected by the last SelectVictim call - this can be nullptr
|
||||
Unit* GetCurrentVictim() const;
|
||||
// returns an arbitrary non-offline victim from owner's threat list if one exists, nullptr otherwise
|
||||
Unit* GetAnyTarget() const;
|
||||
// selects a (potentially new) victim from the threat list and returns it - this can be nullptr
|
||||
Unit* SelectVictim();
|
||||
// identical to ThreatManager::CanHaveThreatList(GetOwner())
|
||||
bool CanHaveThreatList() const { return _ownerCanHaveThreatList; }
|
||||
// returns the victim selected by the last SelectVictim call - this can be nullptr
|
||||
Unit* GetCurrentVictim() const;
|
||||
// returns an arbitrary non-offline victim from owner's threat list if one exists, nullptr otherwise
|
||||
Unit* GetAnyTarget() const;
|
||||
// selects a (potentially new) victim from the threat list and returns it - this can be nullptr
|
||||
Unit* SelectVictim();
|
||||
|
||||
bool IsEngaged() const { return _ownerEngaged; }
|
||||
// are there any entries in owner's threat list?
|
||||
bool IsThreatListEmpty(bool includeOffline = false) const;
|
||||
// is there a threat list entry on owner's threat list with victim == who?
|
||||
bool IsThreatenedBy(ObjectGuid const& who, bool includeOffline = false) const;
|
||||
// is there a threat list entry on owner's threat list with victim == who?
|
||||
bool IsThreatenedBy(Unit const* who, bool includeOffline = false) const;
|
||||
// returns ThreatReference amount if a ref exists, 0.0f otherwise
|
||||
float GetThreat(Unit const* who, bool includeOffline = false) const;
|
||||
size_t GetThreatListSize() const { return _sortedThreatList.size(); }
|
||||
// fastest of the three threat list getters - gets the threat list in "arbitrary" order
|
||||
Trinity::IteratorPair<threat_list_heap::const_iterator> GetUnsortedThreatList() const { return { _sortedThreatList.begin(), _sortedThreatList.end() }; }
|
||||
// slightly slower than GetUnsorted, but, well...sorted - only use it if you need the sorted property, of course
|
||||
// note: current tank is NOT guaranteed to be the first entry in this list - check GetCurrentVictim separately if you want that!
|
||||
Trinity::IteratorPair<threat_list_heap::ordered_iterator> GetSortedThreatList() const { return { _sortedThreatList.ordered_begin(), _sortedThreatList.ordered_end() }; }
|
||||
// slowest of the three threat list getters (by far), but lets you modify the threat references
|
||||
std::vector<ThreatReference*> GetModifiableThreatList() const;
|
||||
bool IsEngaged() const { return _ownerEngaged; }
|
||||
// are there any entries in owner's threat list?
|
||||
bool IsThreatListEmpty(bool includeOffline = false) const;
|
||||
// is there a threat list entry on owner's threat list with victim == who?
|
||||
bool IsThreatenedBy(ObjectGuid const& who, bool includeOffline = false) const;
|
||||
// is there a threat list entry on owner's threat list with victim == who?
|
||||
bool IsThreatenedBy(Unit const* who, bool includeOffline = false) const;
|
||||
// returns ThreatReference amount if a ref exists, 0.0f otherwise
|
||||
float GetThreat(Unit const* who, bool includeOffline = false) const;
|
||||
size_t GetThreatListSize() const { return _sortedThreatList.size(); }
|
||||
// fastest of the three threat list getters - gets the threat list in "arbitrary" order
|
||||
Trinity::IteratorPair<threat_list_heap::const_iterator> GetUnsortedThreatList() const { return { _sortedThreatList.begin(), _sortedThreatList.end() }; }
|
||||
// slightly slower than GetUnsorted, but, well...sorted - only use it if you need the sorted property, of course
|
||||
// note: current tank is NOT guaranteed to be the first entry in this list - check GetCurrentVictim separately if you want that!
|
||||
Trinity::IteratorPair<threat_list_heap::ordered_iterator> GetSortedThreatList() const { return { _sortedThreatList.ordered_begin(), _sortedThreatList.ordered_end() }; }
|
||||
// slowest of the three threat list getters (by far), but lets you modify the threat references
|
||||
std::vector<ThreatReference*> GetModifiableThreatList() const;
|
||||
|
||||
// does any unit have a threat list entry with victim == this.owner?
|
||||
bool IsThreateningAnyone(bool includeOffline = false) const;
|
||||
// is there a threat list entry on who's threat list for this.owner?
|
||||
bool IsThreateningTo(ObjectGuid const& who, bool includeOffline = false) const;
|
||||
// is there a threat list entry on who's threat list for this.owner?
|
||||
bool IsThreateningTo(Unit const* who, bool includeOffline = false) const;
|
||||
auto const& GetThreatenedByMeList() const { return _threatenedByMe; }
|
||||
// does any unit have a threat list entry with victim == this.owner?
|
||||
bool IsThreateningAnyone(bool includeOffline = false) const;
|
||||
// is there a threat list entry on who's threat list for this.owner?
|
||||
bool IsThreateningTo(ObjectGuid const& who, bool includeOffline = false) const;
|
||||
// is there a threat list entry on who's threat list for this.owner?
|
||||
bool IsThreateningTo(Unit const* who, bool includeOffline = false) const;
|
||||
auto const& GetThreatenedByMeList() const { return _threatenedByMe; }
|
||||
|
||||
// Notify the ThreatManager that a condition changed that may impact refs' online state so it can re-evaluate
|
||||
void UpdateOnlineStates(bool meThreateningOthers = true, bool othersThreateningMe = true);
|
||||
///== AFFECT MY THREAT LIST ==
|
||||
void AddThreat(Unit* target, float amount, SpellInfo const* spell = nullptr, bool ignoreModifiers = false, bool ignoreRedirects = false);
|
||||
void ScaleThreat(Unit* target, float factor);
|
||||
// Modify target's threat by +percent%
|
||||
void ModifyThreatByPercent(Unit* target, int32 percent) { if (percent) ScaleThreat(target, 0.01f * float(100 + percent)); }
|
||||
// Resets the specified unit's threat to zero
|
||||
void ResetThreat(Unit* target) { ScaleThreat(target, 0.0f); }
|
||||
// Sets the specified unit's threat to be equal to the highest entry on the threat list
|
||||
void MatchUnitThreatToHighestThreat(Unit* target);
|
||||
// Notify the ThreatManager that we have a new taunt aura (or a taunt aura expired)
|
||||
void TauntUpdate();
|
||||
// Sets all threat refs in owner's threat list to have zero threat
|
||||
void ResetAllThreat();
|
||||
// Removes specified target from the threat list
|
||||
void ClearThreat(Unit* target);
|
||||
// Removes all targets from the threat list (will cause evade in UpdateVictim if called)
|
||||
void ClearAllThreat();
|
||||
// Notify the ThreatManager that a condition changed that may impact refs' online state so it can re-evaluate
|
||||
void UpdateOnlineStates(bool meThreateningOthers = true, bool othersThreateningMe = true);
|
||||
///== AFFECT MY THREAT LIST ==
|
||||
void AddThreat(Unit* target, float amount, SpellInfo const* spell = nullptr, bool ignoreModifiers = false, bool ignoreRedirects = false);
|
||||
void ScaleThreat(Unit* target, float factor);
|
||||
// Modify target's threat by +percent%
|
||||
void ModifyThreatByPercent(Unit* target, int32 percent) { if (percent) ScaleThreat(target, 0.01f*float(100 + percent)); }
|
||||
// Resets the specified unit's threat to zero
|
||||
void ResetThreat(Unit* target) { ScaleThreat(target, 0.0f); }
|
||||
// Sets the specified unit's threat to be equal to the highest entry on the threat list
|
||||
void MatchUnitThreatToHighestThreat(Unit* target);
|
||||
// Notify the ThreatManager that we have a new taunt aura (or a taunt aura expired)
|
||||
void TauntUpdate();
|
||||
// Sets all threat refs in owner's threat list to have zero threat
|
||||
void ResetAllThreat();
|
||||
// Removes specified target from the threat list
|
||||
void ClearThreat(Unit* target);
|
||||
// Removes all targets from the threat list (will cause evade in UpdateVictim if called)
|
||||
void ClearAllThreat();
|
||||
|
||||
// sends SMSG_THREAT_UPDATE to all nearby clients (used by client to forward threat list info to addons)
|
||||
void SendThreatListToClients() const;
|
||||
// sends SMSG_THREAT_UPDATE to all nearby clients (used by client to forward threat list info to addons)
|
||||
void SendThreatListToClients() const;
|
||||
|
||||
///== AFFECT OTHERS' THREAT LISTS ==
|
||||
// what it says on the tin - call AddThreat on everything that's threatened by us with the specified params
|
||||
void ForwardThreatForAssistingMe(Unit* assistant, float baseAmount, SpellInfo const* spell = nullptr, bool ignoreModifiers = false);
|
||||
// delete all ThreatReferences with victim == owner
|
||||
void RemoveMeFromThreatLists();
|
||||
// re-calculates the temporary threat modifier from auras on myself
|
||||
void UpdateMyTempModifiers();
|
||||
// re-calculate SPELL_AURA_MOD_THREAT modifiers
|
||||
void UpdateMySpellSchoolModifiers();
|
||||
///== AFFECT OTHERS' THREAT LISTS ==
|
||||
// what it says on the tin - call AddThreat on everything that's threatened by us with the specified params
|
||||
void ForwardThreatForAssistingMe(Unit* assistant, float baseAmount, SpellInfo const* spell = nullptr, bool ignoreModifiers = false);
|
||||
// delete all ThreatReferences with victim == owner
|
||||
void RemoveMeFromThreatLists();
|
||||
// re-calculates the temporary threat modifier from auras on myself
|
||||
void UpdateMyTempModifiers();
|
||||
// re-calculate SPELL_AURA_MOD_THREAT modifiers
|
||||
void UpdateMySpellSchoolModifiers();
|
||||
|
||||
///== REDIRECT SYSTEM ==
|
||||
// Register a redirection effect that redirects pct% of threat generated by owner to victim
|
||||
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const& victim, uint32 pct);
|
||||
// Unregister a redirection effort for all victims
|
||||
void UnregisterRedirectThreat(uint32 spellId);
|
||||
// Unregister a redirection effect for a specific victim
|
||||
void UnregisterRedirectThreat(uint32 spellId, ObjectGuid const& victim);
|
||||
///== REDIRECT SYSTEM ==
|
||||
// Register a redirection effect that redirects pct% of threat generated by owner to victim
|
||||
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const& victim, uint32 pct);
|
||||
// Unregister a redirection effort for all victims
|
||||
void UnregisterRedirectThreat(uint32 spellId);
|
||||
// Unregister a redirection effect for a specific victim
|
||||
void UnregisterRedirectThreat(uint32 spellId, ObjectGuid const& victim);
|
||||
|
||||
private:
|
||||
Unit* const _owner;
|
||||
bool _ownerCanHaveThreatList;
|
||||
bool _ownerEngaged;
|
||||
private:
|
||||
Unit* const _owner;
|
||||
bool _ownerCanHaveThreatList;
|
||||
bool _ownerEngaged;
|
||||
|
||||
static const CompareThreatLessThan CompareThreat;
|
||||
static bool CompareReferencesLT(ThreatReference const* a, ThreatReference const* b, float aWeight);
|
||||
static float CalculateModifiedThreat(float threat, Unit const* victim, SpellInfo const* spell);
|
||||
static const CompareThreatLessThan CompareThreat;
|
||||
static bool CompareReferencesLT(ThreatReference const* a, ThreatReference const* b, float aWeight);
|
||||
static float CalculateModifiedThreat(float threat, Unit const* victim, SpellInfo const* spell);
|
||||
|
||||
// send opcodes (all for my own threat list)
|
||||
void SendClearAllThreatToClients() const;
|
||||
void SendRemoveToClients(Unit const* victim) const;
|
||||
void SendNewVictimToClients(ThreatReference const* victimRef) const;
|
||||
// send opcodes (all for my own threat list)
|
||||
void SendClearAllThreatToClients() const;
|
||||
void SendRemoveToClients(Unit const* victim) const;
|
||||
void SendNewVictimToClients(ThreatReference const* victimRef) const;
|
||||
|
||||
///== MY THREAT LIST ==
|
||||
void PutThreatListRef(ObjectGuid const& guid, ThreatReference* ref);
|
||||
void PurgeThreatListRef(ObjectGuid const& guid, bool sendRemove);
|
||||
///== MY THREAT LIST ==
|
||||
void PutThreatListRef(ObjectGuid const& guid, ThreatReference* ref);
|
||||
void PurgeThreatListRef(ObjectGuid const& guid, bool sendRemove);
|
||||
|
||||
uint32 _updateClientTimer;
|
||||
threat_list_heap _sortedThreatList;
|
||||
std::unordered_map<ObjectGuid, ThreatReference*> _myThreatListEntries;
|
||||
ThreatReference const* _currentVictimRef;
|
||||
ThreatReference const* ReselectVictim();
|
||||
uint32 _updateClientTimer;
|
||||
threat_list_heap _sortedThreatList;
|
||||
std::unordered_map<ObjectGuid, ThreatReference*> _myThreatListEntries;
|
||||
ThreatReference const* _currentVictimRef;
|
||||
ThreatReference const* ReselectVictim();
|
||||
|
||||
///== OTHERS' THREAT LISTS ==
|
||||
void PutThreatenedByMeRef(ObjectGuid const& guid, ThreatReference* ref);
|
||||
void PurgeThreatenedByMeRef(ObjectGuid const& guid);
|
||||
std::unordered_map<ObjectGuid, ThreatReference*> _threatenedByMe; // these refs are entries for myself on other units' threat lists
|
||||
float _singleSchoolModifiers[MAX_SPELL_SCHOOL]; // most spells are single school - we pre-calculate these and store them
|
||||
mutable std::unordered_map<std::underlying_type<SpellSchoolMask>::type, float> _multiSchoolModifiers; // these are calculated on demand
|
||||
///== OTHERS' THREAT LISTS ==
|
||||
void PutThreatenedByMeRef(ObjectGuid const& guid, ThreatReference* ref);
|
||||
void PurgeThreatenedByMeRef(ObjectGuid const& guid);
|
||||
std::unordered_map<ObjectGuid, ThreatReference*> _threatenedByMe; // these refs are entries for myself on other units' threat lists
|
||||
std::array<float, MAX_SPELL_SCHOOL> _singleSchoolModifiers; // most spells are single school - we pre-calculate these and store them
|
||||
mutable std::unordered_map<std::underlying_type<SpellSchoolMask>::type, float> _multiSchoolModifiers; // these are calculated on demand
|
||||
|
||||
// redirect system (is kind of dumb, but that's because none of the redirection spells actually have any aura effect associated with them, so spellscript needs to deal with it)
|
||||
void UpdateRedirectInfo();
|
||||
std::vector<std::pair<ObjectGuid, uint32>> _redirectInfo; // current redirection targets and percentages (updated from registry in ThreatManager::UpdateRedirectInfo)
|
||||
std::unordered_map<uint32, std::unordered_map<ObjectGuid, uint32>> _redirectRegistry; // spellid -> (victim -> pct); all redirection effects on us (removal individually managed by spell scripts because blizzard is dumb)
|
||||
// redirect system (is kind of dumb, but that's because none of the redirection spells actually have any aura effect associated with them, so spellscript needs to deal with it)
|
||||
void UpdateRedirectInfo();
|
||||
std::vector<std::pair<ObjectGuid, uint32>> _redirectInfo; // current redirection targets and percentages (updated from registry in ThreatManager::UpdateRedirectInfo)
|
||||
std::unordered_map<uint32, std::unordered_map<ObjectGuid, uint32>> _redirectRegistry; // spellid -> (victim -> pct); all redirection effects on us (removal individually managed by spell scripts because blizzard is dumb)
|
||||
|
||||
public:
|
||||
ThreatManager(ThreatManager const&) = delete;
|
||||
ThreatManager& operator=(ThreatManager const&) = delete;
|
||||
public:
|
||||
ThreatManager(ThreatManager const&) = delete;
|
||||
ThreatManager& operator=(ThreatManager const&) = delete;
|
||||
|
||||
friend class ThreatReference;
|
||||
friend struct CompareThreatLessThan;
|
||||
friend class debug_commandscript;
|
||||
};
|
||||
|
||||
// Please check Game/Combat/ThreatManager.h for documentation on how this class works!
|
||||
class TC_GAME_API ThreatReference
|
||||
{
|
||||
public:
|
||||
enum TauntState { TAUNT_STATE_DETAUNT = -1, TAUNT_STATE_NONE = 0, TAUNT_STATE_TAUNT = 1 };
|
||||
enum OnlineState { ONLINE_STATE_ONLINE = 2, ONLINE_STATE_SUPPRESSED = 1, ONLINE_STATE_OFFLINE = 0 };
|
||||
public:
|
||||
enum TauntState { TAUNT_STATE_DETAUNT = -1, TAUNT_STATE_NONE = 0, TAUNT_STATE_TAUNT = 1 };
|
||||
enum OnlineState { ONLINE_STATE_ONLINE = 2, ONLINE_STATE_SUPPRESSED = 1, ONLINE_STATE_OFFLINE = 0 };
|
||||
|
||||
Unit* GetOwner() const { return _owner; }
|
||||
Unit* GetVictim() const { return _victim; }
|
||||
float GetThreat() const { return std::max<float>(_baseAmount + (float)_tempModifier, 0.0f); }
|
||||
OnlineState GetOnlineState() const { return _online; }
|
||||
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; }
|
||||
bool IsDetaunted() const { return _taunted == TAUNT_STATE_DETAUNT; }
|
||||
Unit* GetOwner() const { return _owner; }
|
||||
Unit* GetVictim() const { return _victim; }
|
||||
float GetThreat() const { return std::max<float>(_baseAmount + (float)_tempModifier, 0.0f); }
|
||||
OnlineState GetOnlineState() const { return _online; }
|
||||
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; }
|
||||
bool IsDetaunted() const { return _taunted == TAUNT_STATE_DETAUNT; }
|
||||
|
||||
void SetThreat(float amount) { _baseAmount = amount; HeapNotifyChanged(); }
|
||||
void AddThreat(float amount);
|
||||
void ScaleThreat(float factor);
|
||||
void ModifyThreatByPercent(int32 percent) { if (percent) ScaleThreat(0.01f * float(100 + percent)); }
|
||||
void UpdateOnlineState();
|
||||
void SetThreat(float amount) { _baseAmount = amount; HeapNotifyChanged(); }
|
||||
void AddThreat(float amount);
|
||||
void ScaleThreat(float factor);
|
||||
void ModifyThreatByPercent(int32 percent) { if (percent) ScaleThreat(0.01f*float(100 + percent)); }
|
||||
void UpdateOnlineState();
|
||||
|
||||
void ClearThreat(bool sendRemove = true); // dealloc's this
|
||||
void ClearThreat(bool sendRemove = true); // dealloc's this
|
||||
|
||||
private:
|
||||
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);
|
||||
Unit* const _owner;
|
||||
ThreatManager* const _mgr;
|
||||
void HeapNotifyIncreased() { _mgr->_sortedThreatList.increase(_handle); }
|
||||
void HeapNotifyDecreased() { _mgr->_sortedThreatList.decrease(_handle); }
|
||||
void HeapNotifyChanged() { _mgr->_sortedThreatList.update(_handle); }
|
||||
Unit* const _victim;
|
||||
float _baseAmount;
|
||||
int32 _tempModifier; // Temporary effects (auras with SPELL_AURA_MOD_TOTAL_THREAT) - set from victim's threatmanager in ThreatManager::UpdateMyTempModifiers
|
||||
OnlineState _online;
|
||||
TauntState _taunted;
|
||||
ThreatManager::threat_list_heap::handle_type _handle;
|
||||
private:
|
||||
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);
|
||||
Unit* const _owner;
|
||||
ThreatManager* const _mgr;
|
||||
void HeapNotifyIncreased() { _mgr->_sortedThreatList.increase(_handle); }
|
||||
void HeapNotifyDecreased() { _mgr->_sortedThreatList.decrease(_handle); }
|
||||
void HeapNotifyChanged() { _mgr->_sortedThreatList.update(_handle); }
|
||||
Unit* const _victim;
|
||||
float _baseAmount;
|
||||
int32 _tempModifier; // Temporary effects (auras with SPELL_AURA_MOD_TOTAL_THREAT) - set from victim's threatmanager in ThreatManager::UpdateMyTempModifiers
|
||||
OnlineState _online;
|
||||
TauntState _taunted;
|
||||
ThreatManager::threat_list_heap::handle_type _handle;
|
||||
|
||||
public:
|
||||
ThreatReference(ThreatReference const&) = delete;
|
||||
ThreatReference& operator=(ThreatReference const&) = delete;
|
||||
public:
|
||||
ThreatReference(ThreatReference const&) = delete;
|
||||
ThreatReference& operator=(ThreatReference const&) = delete;
|
||||
|
||||
friend class ThreatManager;
|
||||
friend struct CompareThreatLessThan;
|
||||
};
|
||||
|
||||
inline bool CompareThreatLessThan::operator()(ThreatReference const* a, ThreatReference const* b) const { return ThreatManager::CompareReferencesLT(a, b, 1.0f); }
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,7 @@ EndScriptData */
|
||||
#include "PoolMgr.h"
|
||||
#include "QuestPools.h"
|
||||
#include "RBAC.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Transport.h"
|
||||
#include "WorldSession.h"
|
||||
#include <fstream>
|
||||
@@ -78,6 +79,7 @@ public:
|
||||
{
|
||||
{ "setbit", rbac::RBAC_PERM_COMMAND_DEBUG_SETBIT, false, &HandleDebugSet32BitCommand, "" },
|
||||
{ "threat", rbac::RBAC_PERM_COMMAND_DEBUG_THREAT, false, &HandleDebugThreatListCommand, "" },
|
||||
{ "threatinfo", rbac::RBAC_PERM_COMMAND_DEBUG_THREATINFO, false, &HandleDebugThreatInfoCommand, "" },
|
||||
{ "combat", rbac::RBAC_PERM_COMMAND_DEBUG_COMBAT, false, &HandleDebugCombatListCommand, "" },
|
||||
{ "anim", rbac::RBAC_PERM_COMMAND_DEBUG_ANIM, false, &HandleDebugAnimCommand, "" },
|
||||
{ "arena", rbac::RBAC_PERM_COMMAND_DEBUG_ARENA, true, &HandleDebugArenaCommand, "" },
|
||||
@@ -916,6 +918,79 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleDebugThreatInfoCommand(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
Unit* target = handler->getSelectedUnit();
|
||||
if (!target)
|
||||
{
|
||||
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
handler->PSendSysMessage("Threat info for %s (%s):", target->GetName(), target->GetGUID().ToString().c_str());
|
||||
|
||||
ThreatManager const& mgr = target->GetThreatManager();
|
||||
|
||||
// _singleSchoolModifiers
|
||||
{
|
||||
auto& mods = mgr._singleSchoolModifiers;
|
||||
handler->SendSysMessage(" - Single-school threat modifiers:");
|
||||
handler->PSendSysMessage(" |-- Physical: %.2f%%", mods[SPELL_SCHOOL_NORMAL]*100.0f);
|
||||
handler->PSendSysMessage(" |-- Holy : %.2f%%", mods[SPELL_SCHOOL_HOLY]*100.0f);
|
||||
handler->PSendSysMessage(" |-- Fire : %.2f%%", mods[SPELL_SCHOOL_FIRE]*100.0f);
|
||||
handler->PSendSysMessage(" |-- Nature : %.2f%%", mods[SPELL_SCHOOL_NATURE]*100.0f);
|
||||
handler->PSendSysMessage(" |-- Frost : %.2f%%", mods[SPELL_SCHOOL_FROST]*100.0f);
|
||||
handler->PSendSysMessage(" |-- Shadow : %.2f%%", mods[SPELL_SCHOOL_SHADOW]*100.0f);
|
||||
handler->PSendSysMessage(" |-- Arcane : %.2f%%", mods[SPELL_SCHOOL_ARCANE]*100.0f);
|
||||
}
|
||||
|
||||
// _multiSchoolModifiers
|
||||
{
|
||||
auto& mods = mgr._multiSchoolModifiers;
|
||||
handler->PSendSysMessage("- Multi-school threat modifiers (%zu entries):", mods.size());
|
||||
for (auto const& pair : mods)
|
||||
handler->PSendSysMessage(" |-- Mask 0x%x: %.2f%%", uint32(pair.first), pair.second);
|
||||
}
|
||||
|
||||
// _redirectInfo
|
||||
{
|
||||
auto const& redirectInfo = mgr._redirectInfo;
|
||||
if (redirectInfo.empty())
|
||||
handler->SendSysMessage(" - No redirects being applied");
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(" - %02zu redirects being applied:", redirectInfo.size());
|
||||
for (auto const& pair : redirectInfo)
|
||||
{
|
||||
Unit* unit = ObjectAccessor::GetUnit(*target, pair.first);
|
||||
handler->PSendSysMessage(" |-- %02u%% to %s", pair.second, unit ? unit->GetName().c_str() : pair.first.ToString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _redirectRegistry
|
||||
{
|
||||
auto const& redirectRegistry = mgr._redirectRegistry;
|
||||
if (redirectRegistry.empty())
|
||||
handler->SendSysMessage(" - No redirects are registered");
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(" - %02zu spells may have redirects registered", redirectRegistry.size());
|
||||
for (auto const& outerPair : redirectRegistry) // (spellId, (guid, pct))
|
||||
{
|
||||
SpellInfo const* const spell = sSpellMgr->GetSpellInfo(outerPair.first);
|
||||
handler->PSendSysMessage(" |-- #%06u %s (%zu entries):", outerPair.first, spell ? spell->SpellName[0] : "<unknown>", outerPair.second.size());
|
||||
for (auto const& innerPair : outerPair.second) // (guid, pct)
|
||||
{
|
||||
Unit* unit = ObjectAccessor::GetUnit(*target, innerPair.first);
|
||||
handler->PSendSysMessage(" |-- %02u%% to %s", innerPair.second, unit ? unit->GetName().c_str() : innerPair.first.ToString().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool HandleDebugCombatListCommand(ChatHandler* handler, char const* /*args*/)
|
||||
{
|
||||
Unit* target = handler->getSelectedUnit();
|
||||
|
||||
Reference in New Issue
Block a user