mirror of
https://github.com/mangosfour/server.git
synced 2025-12-18 10:37:01 +00:00
[8858] Implement client inform about creature threat list changes.
Signed-off-by: VladimirMangos <vladimir@getmangos.com> Also small related code cleanups.
This commit is contained in:
parent
29cbdf0a9e
commit
d924406bd8
6 changed files with 114 additions and 18 deletions
|
|
@ -523,8 +523,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
||||||
break;
|
break;
|
||||||
case ACTION_T_THREAT_ALL_PCT:
|
case ACTION_T_THREAT_ALL_PCT:
|
||||||
{
|
{
|
||||||
std::list<HostileReference*>& threatList = m_creature->getThreatManager().getThreatList();
|
ThreatList& threatList = m_creature->getThreatManager().getThreatList();
|
||||||
for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i)
|
for (ThreatList::iterator i = threatList.begin(); i != threatList.end(); ++i)
|
||||||
if(Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
|
if(Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
|
||||||
m_creature->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent);
|
m_creature->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent);
|
||||||
break;
|
break;
|
||||||
|
|
@ -634,8 +634,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
||||||
break;
|
break;
|
||||||
case ACTION_T_CAST_EVENT_ALL:
|
case ACTION_T_CAST_EVENT_ALL:
|
||||||
{
|
{
|
||||||
std::list<HostileReference*>& threatList = m_creature->getThreatManager().getThreatList();
|
ThreatList& threatList = m_creature->getThreatManager().getThreatList();
|
||||||
for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i)
|
for (ThreatList::iterator i = threatList.begin(); i != threatList.end(); ++i)
|
||||||
if (Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
|
if (Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
|
||||||
if (Temp->GetTypeId() == TYPEID_PLAYER)
|
if (Temp->GetTypeId() == TYPEID_PLAYER)
|
||||||
((Player*)Temp)->CastedCreatureOrGO(action.cast_event_all.creatureId, m_creature->GetGUID(), action.cast_event_all.spellId);
|
((Player*)Temp)->CastedCreatureOrGO(action.cast_event_all.creatureId, m_creature->GetGUID(), action.cast_event_all.spellId);
|
||||||
|
|
@ -1114,9 +1114,9 @@ bool CreatureEventAI::IsVisible(Unit *pl) const
|
||||||
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position)
|
||||||
{
|
{
|
||||||
//ThreatList m_threatlist;
|
//ThreatList m_threatlist;
|
||||||
std::list<HostileReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
|
ThreatList& m_threatlist = m_creature->getThreatManager().getThreatList();
|
||||||
std::list<HostileReference*>::iterator i = m_threatlist.begin();
|
ThreatList::iterator i = m_threatlist.begin();
|
||||||
std::list<HostileReference*>::reverse_iterator r = m_threatlist.rbegin();
|
ThreatList::reverse_iterator r = m_threatlist.rbegin();
|
||||||
|
|
||||||
if (position >= m_threatlist.size() || !m_threatlist.size())
|
if (position >= m_threatlist.size() || !m_threatlist.size())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ Unit* HostileReference::getSourceUnit()
|
||||||
|
|
||||||
void ThreatContainer::clearReferences()
|
void ThreatContainer::clearReferences()
|
||||||
{
|
{
|
||||||
for(std::list<HostileReference*>::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
|
for(ThreatList::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
|
||||||
{
|
{
|
||||||
(*i)->unlink();
|
(*i)->unlink();
|
||||||
delete (*i);
|
delete (*i);
|
||||||
|
|
@ -222,7 +222,7 @@ HostileReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
|
||||||
{
|
{
|
||||||
HostileReference* result = NULL;
|
HostileReference* result = NULL;
|
||||||
uint64 guid = pVictim->GetGUID();
|
uint64 guid = pVictim->GetGUID();
|
||||||
for(std::list<HostileReference*>::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
|
for(ThreatList::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
|
||||||
{
|
{
|
||||||
if((*i)->getUnitGuid() == guid)
|
if((*i)->getUnitGuid() == guid)
|
||||||
{
|
{
|
||||||
|
|
@ -283,10 +283,10 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, Hostile
|
||||||
bool found = false;
|
bool found = false;
|
||||||
bool noPriorityTargetFound = false;
|
bool noPriorityTargetFound = false;
|
||||||
|
|
||||||
std::list<HostileReference*>::const_iterator lastRef = iThreatList.end();
|
ThreatList::const_iterator lastRef = iThreatList.end();
|
||||||
lastRef--;
|
lastRef--;
|
||||||
|
|
||||||
for(std::list<HostileReference*>::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
|
for(ThreatList::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
|
||||||
{
|
{
|
||||||
currentRef = (*iter);
|
currentRef = (*iter);
|
||||||
|
|
||||||
|
|
@ -351,7 +351,7 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, Hostile
|
||||||
//=================== ThreatManager ==========================
|
//=================== ThreatManager ==========================
|
||||||
//============================================================
|
//============================================================
|
||||||
|
|
||||||
ThreatManager::ThreatManager(Unit* owner) : iCurrentVictim(NULL), iOwner(owner)
|
ThreatManager::ThreatManager(Unit* owner) : iCurrentVictim(NULL), iOwner(owner), iUpdateTimer(THREAT_UPDATE_INTERVAL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,6 +362,7 @@ void ThreatManager::clearReferences()
|
||||||
iThreatContainer.clearReferences();
|
iThreatContainer.clearReferences();
|
||||||
iThreatOfflineContainer.clearReferences();
|
iThreatOfflineContainer.clearReferences();
|
||||||
iCurrentVictim = NULL;
|
iCurrentVictim = NULL;
|
||||||
|
iUpdateTimer.Reset(THREAT_UPDATE_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
|
|
@ -461,6 +462,9 @@ void ThreatManager::tauntFadeOut(Unit *pTaunter)
|
||||||
|
|
||||||
void ThreatManager::setCurrentVictim(HostileReference* pHostileReference)
|
void ThreatManager::setCurrentVictim(HostileReference* pHostileReference)
|
||||||
{
|
{
|
||||||
|
if (pHostileReference && pHostileReference != iCurrentVictim)
|
||||||
|
iOwner->SendHighestThreatUpdate(pHostileReference);
|
||||||
|
|
||||||
iCurrentVictim = pHostileReference;
|
iCurrentVictim = pHostileReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -506,6 +510,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
|
||||||
setCurrentVictim(NULL);
|
setCurrentVictim(NULL);
|
||||||
setDirty(true);
|
setDirty(true);
|
||||||
}
|
}
|
||||||
|
iOwner->SendThreatRemove(hostileReference);
|
||||||
if(hostileReference->isOnline())
|
if(hostileReference->isOnline())
|
||||||
iThreatContainer.remove(hostileReference);
|
iThreatContainer.remove(hostileReference);
|
||||||
else
|
else
|
||||||
|
|
@ -513,3 +518,16 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThreatManager::UpdateForClient(uint32 diff)
|
||||||
|
{
|
||||||
|
if (isThreatListEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
iUpdateTimer.Update(diff);
|
||||||
|
if (iUpdateTimer.Passed())
|
||||||
|
{
|
||||||
|
iOwner->SendThreatUpdate();
|
||||||
|
iUpdateTimer.Reset(THREAT_UPDATE_INTERVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "SharedDefines.h"
|
#include "SharedDefines.h"
|
||||||
#include "Utilities/LinkedReference/Reference.h"
|
#include "Utilities/LinkedReference/Reference.h"
|
||||||
#include "UnitEvents.h"
|
#include "UnitEvents.h"
|
||||||
|
#include "Timer.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
//==============================================================
|
//==============================================================
|
||||||
|
|
@ -33,6 +33,8 @@ class Creature;
|
||||||
class ThreatManager;
|
class ThreatManager;
|
||||||
struct SpellEntry;
|
struct SpellEntry;
|
||||||
|
|
||||||
|
#define THREAT_UPDATE_INTERVAL 1 * IN_MILISECONDS // Server should send threat update to client periodically each second
|
||||||
|
|
||||||
//==============================================================
|
//==============================================================
|
||||||
// Class to calculate the real threat based
|
// Class to calculate the real threat based
|
||||||
|
|
||||||
|
|
@ -127,10 +129,13 @@ class MANGOS_DLL_SPEC HostileReference : public Reference<Unit, ThreatManager>
|
||||||
//==============================================================
|
//==============================================================
|
||||||
class ThreatManager;
|
class ThreatManager;
|
||||||
|
|
||||||
|
typedef std::list<HostileReference*> ThreatList;
|
||||||
|
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC ThreatContainer
|
class MANGOS_DLL_SPEC ThreatContainer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::list<HostileReference*> iThreatList;
|
ThreatList iThreatList;
|
||||||
bool iDirty;
|
bool iDirty;
|
||||||
protected:
|
protected:
|
||||||
friend class ThreatManager;
|
friend class ThreatManager;
|
||||||
|
|
@ -160,7 +165,8 @@ class MANGOS_DLL_SPEC ThreatContainer
|
||||||
|
|
||||||
HostileReference* getReferenceByTarget(Unit* pVictim);
|
HostileReference* getReferenceByTarget(Unit* pVictim);
|
||||||
|
|
||||||
std::list<HostileReference*>& getThreatList() { return iThreatList; }
|
ThreatList& getThreatList() { return iThreatList; }
|
||||||
|
ThreatList const& getThreatList() const { return iThreatList; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//=================================================
|
//=================================================
|
||||||
|
|
@ -186,6 +192,8 @@ class MANGOS_DLL_SPEC ThreatManager
|
||||||
|
|
||||||
void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
|
void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
|
||||||
|
|
||||||
|
void UpdateForClient(uint32 time);
|
||||||
|
|
||||||
HostileReference* getCurrentVictim() { return iCurrentVictim; }
|
HostileReference* getCurrentVictim() { return iCurrentVictim; }
|
||||||
|
|
||||||
Unit* getOwner() { return iOwner; }
|
Unit* getOwner() { return iOwner; }
|
||||||
|
|
@ -201,13 +209,18 @@ class MANGOS_DLL_SPEC ThreatManager
|
||||||
|
|
||||||
// methods to access the lists from the outside to do sume dirty manipulation (scriping and such)
|
// methods to access the lists from the outside to do sume dirty manipulation (scriping and such)
|
||||||
// I hope they are used as little as possible.
|
// I hope they are used as little as possible.
|
||||||
std::list<HostileReference*>& getThreatList() { return iThreatContainer.getThreatList(); }
|
ThreatList& getThreatList() { return iThreatContainer.getThreatList(); }
|
||||||
std::list<HostileReference*>& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
|
ThreatList const& getThreatList() const { return iThreatContainer.getThreatList(); }
|
||||||
|
ThreatList& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); }
|
||||||
|
ThreatList const& getOfflieThreatList() const { return iThreatOfflineContainer.getThreatList(); }
|
||||||
ThreatContainer& getOnlineContainer() { return iThreatContainer; }
|
ThreatContainer& getOnlineContainer() { return iThreatContainer; }
|
||||||
|
ThreatContainer const& getOnlineContainer() const { return iThreatContainer; }
|
||||||
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
|
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
|
||||||
|
ThreatContainer const& getOfflineContainer() const { return iThreatOfflineContainer; }
|
||||||
private:
|
private:
|
||||||
HostileReference* iCurrentVictim;
|
HostileReference* iCurrentVictim;
|
||||||
Unit* iOwner;
|
Unit* iOwner;
|
||||||
|
TimeTrackerSmall iUpdateTimer;
|
||||||
ThreatContainer iThreatContainer;
|
ThreatContainer iThreatContainer;
|
||||||
ThreatContainer iThreatOfflineContainer;
|
ThreatContainer iThreatOfflineContainer;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,9 @@ void Unit::Update( uint32 p_time )
|
||||||
delete *itr;
|
delete *itr;
|
||||||
m_deletedAuras.clear();
|
m_deletedAuras.clear();
|
||||||
|
|
||||||
|
if (CanHaveThreatList())
|
||||||
|
getThreatManager().UpdateForClient(p_time);
|
||||||
|
|
||||||
// update combat timer only for players and pets
|
// update combat timer only for players and pets
|
||||||
if (isInCombat() && (GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet() || ((Creature*)this)->isCharmed()))
|
if (isInCombat() && (GetTypeId() == TYPEID_PLAYER || ((Creature*)this)->isPet() || ((Creature*)this)->isCharmed()))
|
||||||
{
|
{
|
||||||
|
|
@ -10402,6 +10405,8 @@ void Unit::AddThreat(Unit* pVictim, float threat /*= 0.0f*/, bool crit /*= false
|
||||||
|
|
||||||
void Unit::DeleteThreatList()
|
void Unit::DeleteThreatList()
|
||||||
{
|
{
|
||||||
|
if(CanHaveThreatList() && !m_ThreatManager.isThreatListEmpty())
|
||||||
|
SendThreatClear();
|
||||||
m_ThreatManager.clearReferences();
|
m_ThreatManager.clearReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -12763,3 +12768,57 @@ uint32 Unit::GetCombatRatingDamageReduction(CombatRating cr, float rate, float c
|
||||||
percent = cap;
|
percent = cap;
|
||||||
return uint32 (percent * damage / 100.0f);
|
return uint32 (percent * damage / 100.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::SendThreatUpdate()
|
||||||
|
{
|
||||||
|
if (uint32 count = getThreatManager().getThreatList().size())
|
||||||
|
{
|
||||||
|
sLog.outDebug( "WORLD: Send SMSG_THREAT_UPDATE Message" );
|
||||||
|
WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8);
|
||||||
|
data.append(GetPackGUID());
|
||||||
|
data << uint32(count);
|
||||||
|
ThreatList& tlist = getThreatManager().getThreatList();
|
||||||
|
for (ThreatList::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
|
||||||
|
{
|
||||||
|
data.appendPackGUID((*itr)->getUnitGuid());
|
||||||
|
data << uint32((*itr)->getThreat());
|
||||||
|
}
|
||||||
|
SendMessageToSet(&data, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::SendHighestThreatUpdate(HostileReference* pHostilReference)
|
||||||
|
{
|
||||||
|
if (uint32 count = getThreatManager().getThreatList().size())
|
||||||
|
{
|
||||||
|
sLog.outDebug( "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message" );
|
||||||
|
WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8);
|
||||||
|
data.append(GetPackGUID());
|
||||||
|
data.appendPackGUID(pHostilReference->getUnitGuid());
|
||||||
|
data << uint32(count);
|
||||||
|
ThreatList const& tlist = getThreatManager().getThreatList();
|
||||||
|
for (ThreatList::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
|
||||||
|
{
|
||||||
|
data.appendPackGUID((*itr)->getUnitGuid());
|
||||||
|
data << uint32((*itr)->getThreat());
|
||||||
|
}
|
||||||
|
SendMessageToSet(&data, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::SendThreatClear()
|
||||||
|
{
|
||||||
|
sLog.outDebug( "WORLD: Send SMSG_THREAT_CLEAR Message" );
|
||||||
|
WorldPacket data(SMSG_THREAT_CLEAR, 8);
|
||||||
|
data.append(GetPackGUID());
|
||||||
|
SendMessageToSet(&data, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::SendThreatRemove(HostileReference* pHostileReference)
|
||||||
|
{
|
||||||
|
sLog.outDebug( "WORLD: Send SMSG_THREAT_REMOVE Message" );
|
||||||
|
WorldPacket data(SMSG_THREAT_REMOVE, 8 + 8);
|
||||||
|
data.append(GetPackGUID());
|
||||||
|
data.appendPackGUID(pHostileReference->getUnitGuid());
|
||||||
|
SendMessageToSet(&data, false);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1161,6 +1161,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, MonsterMovementFlags flags, uint32 Time, Player* player = NULL);
|
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, MonsterMovementFlags flags, uint32 Time, Player* player = NULL);
|
||||||
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, MonsterMovementFlags flags);
|
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, MonsterMovementFlags flags);
|
||||||
|
|
||||||
|
void SendHighestThreatUpdate(HostileReference* pHostileReference);
|
||||||
|
void SendThreatClear();
|
||||||
|
void SendThreatRemove(HostileReference* pHostileReference);
|
||||||
|
void SendThreatUpdate();
|
||||||
|
|
||||||
void BuildHeartBeatMsg( WorldPacket *data ) const;
|
void BuildHeartBeatMsg( WorldPacket *data ) const;
|
||||||
|
|
||||||
virtual void MoveOutOfRange(Player &) { };
|
virtual void MoveOutOfRange(Player &) { };
|
||||||
|
|
@ -1373,6 +1378,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void TauntApply(Unit* pVictim);
|
void TauntApply(Unit* pVictim);
|
||||||
void TauntFadeOut(Unit *taunter);
|
void TauntFadeOut(Unit *taunter);
|
||||||
ThreatManager& getThreatManager() { return m_ThreatManager; }
|
ThreatManager& getThreatManager() { return m_ThreatManager; }
|
||||||
|
ThreatManager const& getThreatManager() const { return m_ThreatManager; }
|
||||||
void addHatedBy(HostileReference* pHostileReference) { m_HostileRefManager.insertFirst(pHostileReference); };
|
void addHatedBy(HostileReference* pHostileReference) { m_HostileRefManager.insertFirst(pHostileReference); };
|
||||||
void removeHatedBy(HostileReference* /*pHostileReference*/ ) { /* nothing to do yet */ }
|
void removeHatedBy(HostileReference* /*pHostileReference*/ ) { /* nothing to do yet */ }
|
||||||
HostileRefManager& getHostileRefManager() { return m_HostileRefManager; }
|
HostileRefManager& getHostileRefManager() { return m_HostileRefManager; }
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8857"
|
#define REVISION_NR "8858"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue