aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Combat/ThreatManager.cpp
diff options
context:
space:
mode:
authorSpp <spp@jorge.gr>2011-08-04 13:16:09 +0200
committerSpp <spp@jorge.gr>2011-08-04 13:16:09 +0200
commit1c882084f3b512677c8e90ffdd58d608be051b6a (patch)
tree88fea1d2f2af2128caea8a2e5693ede95097cd95 /src/server/game/Combat/ThreatManager.cpp
parent68d34ab3c26d5fe06cd9c5f742d6ef2ee22f58df (diff)
Core: Cosmetic changes in Threat related code (per request) and remove of extra call to SpellMgr singleton inside that singleton
Diffstat (limited to 'src/server/game/Combat/ThreatManager.cpp')
-rwxr-xr-xsrc/server/game/Combat/ThreatManager.cpp267
1 files changed, 142 insertions, 125 deletions
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index 1f06bb8dd9a..242110f4a22 100755
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -31,31 +31,58 @@
//================= ThreatCalcHelper ===========================
//==============================================================
-// The pHatingUnit is not used yet
-float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* /*pHatingUnit*/, float fThreat, SpellSchoolMask schoolMask, SpellInfo const *pThreatSpell)
+// The hatingUnit is not used yet
+float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
{
- if (pThreatSpell)
+ if (threatSpell)
{
- if (pThreatSpell->AttributesEx & SPELL_ATTR1_NO_THREAT)
+ if (threatSpell->AttributesEx & SPELL_ATTR1_NO_THREAT)
return 0.0f;
- if (Player* modOwner = pHatedUnit->GetSpellModOwner())
- modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, fThreat);
+ if (Player* modOwner = hatedUnit->GetSpellModOwner())
+ modOwner->ApplySpellMod(threatSpell->Id, SPELLMOD_THREAT, threat);
}
- return pHatedUnit->ApplyTotalThreatModifier(fThreat, schoolMask);
+ return hatedUnit->ApplyTotalThreatModifier(threat, schoolMask);
+}
+
+bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* /*threatSpell*/)
+{
+ //function deals with adding threat and adding players and pets into ThreatList
+ //mobs, NPCs, guards have ThreatList and HateOfflineList
+ //players and pets have only InHateListOf
+ //HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.)
+
+ if (!hatedUnit || !hatingUnit)
+ return false;
+
+ // not to self
+ if (hatedUnit == hatingUnit)
+ return false;
+
+ // not to GM
+ if (hatedUnit->GetTypeId() == TYPEID_PLAYER && hatedUnit->ToPlayer()->isGameMaster())
+ return false;
+
+ // not to dead and not for dead
+ if (!hatedUnit->isAlive() || !hatingUnit->isAlive())
+ return false;
+
+ ASSERT(hatingUnit->GetTypeId() == TYPEID_UNIT);
+
+ return true;
}
//============================================================
//================= HostileReference ==========================
//============================================================
-HostileReference::HostileReference(Unit* pUnit, ThreatManager *pThreatManager, float fThreat)
+HostileReference::HostileReference(Unit* refUnit, ThreatManager* threatManager, float threat)
{
- iThreat = fThreat;
+ iThreat = threat;
iTempThreatModifier = 0.0f;
- link(pUnit, pThreatManager);
- iUnitGuid = pUnit->GetGUID();
+ link(refUnit, threatManager);
+ iUnitGuid = refUnit->GetGUID();
iOnline = true;
iAccessible = true;
}
@@ -85,35 +112,42 @@ void HostileReference::sourceObjectDestroyLink()
//============================================================
// Inform the source, that the status of the reference changed
-void HostileReference::fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent)
+void HostileReference::fireStatusChanged(ThreatRefStatusChangeEvent& threatRefStatusChangeEvent)
{
if (getSource())
- getSource()->processThreatEvent(&pThreatRefStatusChangeEvent);
+ getSource()->processThreatEvent(&threatRefStatusChangeEvent);
}
//============================================================
-void HostileReference::addThreat(float fModThreat)
+void HostileReference::addThreat(float modThreat)
{
- iThreat += fModThreat;
+ iThreat += modThreat;
// the threat is changed. Source and target unit have to be available
// if the link was cut before relink it again
if (!isOnline())
updateOnlineStatus();
- if (fModThreat != 0.0f)
+ if (modThreat != 0.0f)
{
- ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, fModThreat);
+ ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, modThreat);
fireStatusChanged(event);
}
- if (isValid() && fModThreat >= 0.0f)
+ if (isValid() && modThreat >= 0.0f)
{
- Unit* victim_owner = getTarget()->GetCharmerOrOwner();
- if (victim_owner && victim_owner->isAlive())
- getSource()->addThreat(victim_owner, 0.0f); // create a threat to the owner of a pet, if the pet attacks
+ Unit* victimOwner = getTarget()->GetCharmerOrOwner();
+ if (victimOwner && victimOwner->isAlive())
+ getSource()->addThreat(victimOwner, 0.0f); // create a threat to the owner of a pet, if the pet attacks
}
}
+void HostileReference::addThreatPercent(int32 percent)
+{
+ float tmpThreat = iThreat;
+ AddPctN(tmpThreat, percent);
+ addThreat(tmpThreat - iThreat);
+}
+
//============================================================
// check, if source can reach target and set the status
@@ -131,7 +165,7 @@ void HostileReference::updateOnlineStatus()
// target is no player or not gamemaster
// target is not in flight
if (isValid() &&
- ((getTarget()->GetTypeId() != TYPEID_PLAYER || !((Player*)getTarget())->isGameMaster()) ||
+ ((getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->isGameMaster()) ||
!getTarget()->HasUnitState(UNIT_STAT_IN_FLIGHT)))
{
Creature* creature = getSourceUnit()->ToCreature();
@@ -152,11 +186,11 @@ void HostileReference::updateOnlineStatus()
//============================================================
// set the status and fire the event on status change
-void HostileReference::setOnlineOfflineState(bool pIsOnline)
+void HostileReference::setOnlineOfflineState(bool isOnline)
{
- if (iOnline != pIsOnline)
+ if (iOnline != isOnline)
{
- iOnline = pIsOnline;
+ iOnline = isOnline;
if (!iOnline)
setAccessibleState(false); // if not online that not accessable as well
@@ -167,11 +201,11 @@ void HostileReference::setOnlineOfflineState(bool pIsOnline)
//============================================================
-void HostileReference::setAccessibleState(bool pIsAccessible)
+void HostileReference::setAccessibleState(bool isAccessible)
{
- if (iAccessible != pIsAccessible)
+ if (iAccessible != isAccessible)
{
- iAccessible = pIsAccessible;
+ iAccessible = isAccessible;
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ASSECCIBLE_STATUS, this);
fireStatusChanged(event);
@@ -213,40 +247,36 @@ void ThreatContainer::clearReferences()
//============================================================
// Return the HostileReference of NULL, if not found
-HostileReference* ThreatContainer::getReferenceByTarget(Unit* pVictim)
+HostileReference* ThreatContainer::getReferenceByTarget(Unit* victim)
{
- HostileReference* result = NULL;
+ if (!victim)
+ return NULL;
- uint64 guid = pVictim->GetGUID();
+ uint64 guid = victim->GetGUID();
for (std::list<HostileReference*>::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
- {
- if ((*i)->getUnitGuid() == guid)
- {
- result = (*i);
- break;
- }
- }
+ if ((*i) && (*i)->getUnitGuid() == guid)
+ return (*i);
- return result;
+ return NULL;
}
//============================================================
// Add the threat, if we find the reference
-HostileReference* ThreatContainer::addThreat(Unit* pVictim, float fThreat)
+HostileReference* ThreatContainer::addThreat(Unit* victim, float threat)
{
- HostileReference* ref = getReferenceByTarget(pVictim);
+ HostileReference* ref = getReferenceByTarget(victim);
if (ref)
- ref->addThreat(fThreat);
+ ref->addThreat(threat);
return ref;
}
//============================================================
-void ThreatContainer::modifyThreatPercent(Unit *pVictim, int32 iPercent)
+void ThreatContainer::modifyThreatPercent(Unit *victim, int32 percent)
{
- if (HostileReference* ref = getReferenceByTarget(pVictim))
- ref->addThreatPercent(iPercent);
+ if (HostileReference* ref = getReferenceByTarget(victim))
+ ref->addThreatPercent(percent);
}
//============================================================
@@ -254,10 +284,9 @@ void ThreatContainer::modifyThreatPercent(Unit *pVictim, int32 iPercent)
void ThreatContainer::update()
{
- if (iDirty && iThreatList.size() >1)
- {
+ if (iDirty && iThreatList.size() > 1)
iThreatList.sort(Trinity::ThreatOrderPred());
- }
+
iDirty = false;
}
@@ -265,7 +294,7 @@ void ThreatContainer::update()
// return the next best victim
// could be the current victim
-HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostileReference* pCurrentVictim)
+HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileReference* currentVictim)
{
HostileReference* currentRef = NULL;
bool found = false;
@@ -282,13 +311,13 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, Hostile
ASSERT(target); // if the ref has status online the target must be there !
// some units are prefered in comparison to others
- if (!noPriorityTargetFound && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask()) || target->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE)))
+ if (!noPriorityTargetFound && (target->IsImmunedToDamage(attacker->GetMeleeDamageSchoolMask()) || target->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE)))
{
if (iter != lastRef)
{
// current victim is a second choice target, so don't compare threat with it below
- if (currentRef == pCurrentVictim)
- pCurrentVictim = NULL;
+ if (currentRef == currentVictim)
+ currentVictim = NULL;
++iter;
continue;
}
@@ -301,21 +330,21 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, Hostile
}
}
- if (pAttacker->canCreatureAttack(target)) // skip non attackable currently targets
+ if (attacker->canCreatureAttack(target)) // skip non attackable currently targets
{
- if (pCurrentVictim) // select 1.3/1.1 better target in comparison current target
+ if (currentVictim) // select 1.3/1.1 better target in comparison current target
{
// list sorted and and we check current target, then this is best case
- if (pCurrentVictim == currentRef || currentRef->getThreat() <= 1.1f * pCurrentVictim->getThreat())
+ if (currentVictim == currentRef || currentRef->getThreat() <= 1.1f * currentVictim->getThreat())
{
- currentRef = pCurrentVictim; // for second case
+ currentRef = currentVictim; // for second case
found = true;
break;
}
- if (currentRef->getThreat() > 1.3f * pCurrentVictim->getThreat() ||
- (currentRef->getThreat() > 1.1f * pCurrentVictim->getThreat() &&
- pAttacker->IsWithinMeleeRange(target)))
+ if (currentRef->getThreat() > 1.3f * currentVictim->getThreat() ||
+ (currentRef->getThreat() > 1.1f * currentVictim->getThreat() &&
+ attacker->IsWithinMeleeRange(target)))
{ //implement 110% threat rule for targets in melee range
found = true; //and 130% rule for targets in ranged distances
break; //for selecting alive targets
@@ -355,71 +384,58 @@ void ThreatManager::clearReferences()
//============================================================
-void ThreatManager::addThreat(Unit* pVictim, float fThreat, SpellSchoolMask schoolMask, SpellInfo const *pThreatSpell)
+void ThreatManager::addThreat(Unit* victim, float threat, SpellSchoolMask schoolMask, SpellInfo const *threatSpell)
{
- //function deals with adding threat and adding players and pets into ThreatList
- //mobs, NPCs, guards have ThreatList and HateOfflineList
- //players and pets have only InHateListOf
- //HateOfflineList is used co contain unattackable victims (in-flight, in-water, GM etc.)
-
- // not to self
- if (pVictim == getOwner())
- return;
-
- // not to GM
- if (!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->ToPlayer()->isGameMaster()))
+ if (!ThreatCalcHelper::isValidProcess(victim, getOwner(), threatSpell))
return;
- // not to dead and not for dead
- if (!pVictim->isAlive() || !getOwner()->isAlive())
- return;
-
- ASSERT(getOwner()->GetTypeId() == TYPEID_UNIT);
+ doAddThreat(victim, ThreatCalcHelper::calcThreat(victim, iOwner, threat, schoolMask, threatSpell));
+}
- float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, fThreat, schoolMask, pThreatSpell);
+void ThreatManager::doAddThreat(Unit* victim, float threat)
+{
+ uint32 reducedThreadPercent = victim->GetReducedThreatPercent();
// must check > 0.0f, otherwise dead loop
- if (threat > 0.0f && pVictim->GetReducedThreatPercent())
+ if (threat > 0.0f && reducedThreadPercent)
{
- uint32 reducedThreadPercent = pVictim->GetReducedThreatPercent();
+ Unit* redirectTarget = victim->GetMisdirectionTarget();
+ if (redirectTarget)
+ if (Aura* glyphAura = redirectTarget->GetAura(63326)) // Glyph of Vigilance
+ reducedThreadPercent += glyphAura->GetSpellInfo()->Effects[0].CalcValue();
- Unit *unit = pVictim->GetMisdirectionTarget();
- if (unit)
- if (Aura* pAura = unit->GetAura(63326)) // Glyph of Vigilance
- reducedThreadPercent += pAura->GetSpellInfo()->Effects[0].CalcValue();
-
- float reducedThreat = threat * reducedThreadPercent / 100;
+ float reducedThreat = threat * reducedThreadPercent / 100.0f;
threat -= reducedThreat;
- if (unit)
- _addThreat(unit, reducedThreat);
+ if (redirectTarget)
+ _addThreat(redirectTarget, reducedThreat);
}
- _addThreat(pVictim, threat);
+ _addThreat(victim, threat);
}
-void ThreatManager::_addThreat(Unit *pVictim, float fThreat)
+void ThreatManager::_addThreat(Unit* victim, float threat)
{
- HostileReference* ref = iThreatContainer.addThreat(pVictim, fThreat);
+ HostileReference* ref = iThreatContainer.addThreat(victim, threat);
// Ref is not in the online refs, search the offline refs next
if (!ref)
- ref = iThreatOfflineContainer.addThreat(pVictim, fThreat);
+ ref = iThreatOfflineContainer.addThreat(victim, threat);
- if (!ref) // there was no ref => create a new one
+ if (!ref) // there was no ref => create a new one
{
// threat has to be 0 here
- HostileReference* hostilReference = new HostileReference(pVictim, this, 0);
- iThreatContainer.addReference(hostilReference);
- hostilReference->addThreat(fThreat); // now we add the real threat
- if (pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->ToPlayer()->isGameMaster())
- hostilReference->setOnlineOfflineState(false); // GM is always offline
+ HostileReference* hostileRef = new HostileReference(victim, this, 0);
+ iThreatContainer.addReference(hostileRef);
+ hostileRef->addThreat(threat); // now we add the real threat
+ if (victim->GetTypeId() == TYPEID_PLAYER && victim->ToPlayer()->isGameMaster())
+ hostileRef->setOnlineOfflineState(false); // GM is always offline
}
}
//============================================================
-void ThreatManager::modifyThreatPercent(Unit *pVictim, int32 iPercent)
+void ThreatManager::modifyThreatPercent(Unit* victim, int32 percent)
{
- iThreatContainer.modifyThreatPercent(pVictim, iPercent);
+ iThreatContainer.modifyThreatPercent(victim, percent);
}
//============================================================
@@ -434,12 +450,12 @@ Unit* ThreatManager::getHostilTarget()
//============================================================
-float ThreatManager::getThreat(Unit *pVictim, bool pAlsoSearchOfflineList)
+float ThreatManager::getThreat(Unit *victim, bool alsoSearchOfflineList)
{
float threat = 0.0f;
- HostileReference* ref = iThreatContainer.getReferenceByTarget(pVictim);
- if (!ref && pAlsoSearchOfflineList)
- ref = iThreatOfflineContainer.getReferenceByTarget(pVictim);
+ HostileReference* ref = iThreatContainer.getReferenceByTarget(victim);
+ if (!ref && alsoSearchOfflineList)
+ ref = iThreatOfflineContainer.getReferenceByTarget(victim);
if (ref)
threat = ref->getThreat();
return threat;
@@ -447,9 +463,9 @@ float ThreatManager::getThreat(Unit *pVictim, bool pAlsoSearchOfflineList)
//============================================================
-void ThreatManager::tauntApply(Unit* pTaunter)
+void ThreatManager::tauntApply(Unit* taunter)
{
- HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter);
+ HostileReference* ref = iThreatContainer.getReferenceByTarget(taunter);
if (getCurrentVictim() && ref && (ref->getThreat() < getCurrentVictim()->getThreat()))
{
if (ref->getTempThreatModifier() == 0.0f) // Ok, temp threat is unused
@@ -459,9 +475,9 @@ void ThreatManager::tauntApply(Unit* pTaunter)
//============================================================
-void ThreatManager::tauntFadeOut(Unit *pTaunter)
+void ThreatManager::tauntFadeOut(Unit *taunter)
{
- HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter);
+ HostileReference* ref = iThreatContainer.getReferenceByTarget(taunter);
if (ref)
ref->resetTempThreat();
}
@@ -485,45 +501,45 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
{
threatRefStatusChangeEvent->setThreatManager(this); // now we can set the threat manager
- HostileReference* hostilReference = threatRefStatusChangeEvent->getReference();
+ HostileReference* hostilRef = threatRefStatusChangeEvent->getReference();
switch(threatRefStatusChangeEvent->getType())
{
case UEV_THREAT_REF_THREAT_CHANGE:
- if ((getCurrentVictim() == hostilReference && threatRefStatusChangeEvent->getFValue()<0.0f) ||
- (getCurrentVictim() != hostilReference && threatRefStatusChangeEvent->getFValue()>0.0f))
+ if ((getCurrentVictim() == hostilRef && threatRefStatusChangeEvent->getFValue()<0.0f) ||
+ (getCurrentVictim() != hostilRef && threatRefStatusChangeEvent->getFValue()>0.0f))
setDirty(true); // the order in the threat list might have changed
break;
case UEV_THREAT_REF_ONLINE_STATUS:
- if (!hostilReference->isOnline())
+ if (!hostilRef->isOnline())
{
- if (hostilReference == getCurrentVictim())
+ if (hostilRef == getCurrentVictim())
{
setCurrentVictim(NULL);
setDirty(true);
}
- iThreatContainer.remove(hostilReference);
- iThreatOfflineContainer.addReference(hostilReference);
+ iThreatContainer.remove(hostilRef);
+ iThreatOfflineContainer.addReference(hostilRef);
}
else
{
- if (getCurrentVictim() && hostilReference->getThreat() > (1.1f * getCurrentVictim()->getThreat()))
+ if (getCurrentVictim() && hostilRef->getThreat() > (1.1f * getCurrentVictim()->getThreat()))
setDirty(true);
- iThreatContainer.addReference(hostilReference);
- iThreatOfflineContainer.remove(hostilReference);
+ iThreatContainer.addReference(hostilRef);
+ iThreatOfflineContainer.remove(hostilRef);
}
break;
case UEV_THREAT_REF_REMOVE_FROM_LIST:
- if (hostilReference == getCurrentVictim())
+ if (hostilRef == getCurrentVictim())
{
setCurrentVictim(NULL);
setDirty(true);
}
- iOwner->SendRemoveFromThreatListOpcode(hostilReference);
- if (hostilReference->isOnline())
- iThreatContainer.remove(hostilReference);
+ iOwner->SendRemoveFromThreatListOpcode(hostilRef);
+ if (hostilRef->isOnline())
+ iThreatContainer.remove(hostilRef);
else
- iThreatOfflineContainer.remove(hostilReference);
+ iThreatOfflineContainer.remove(hostilRef);
break;
}
}
@@ -532,6 +548,7 @@ bool ThreatManager::isNeedUpdateToClient(uint32 time)
{
if (isThreatListEmpty())
return false;
+
if (time >= iUpdateTimer)
{
iUpdateTimer = THREAT_UPDATE_INTERVAL;
@@ -544,11 +561,11 @@ bool ThreatManager::isNeedUpdateToClient(uint32 time)
// Reset all aggro without modifying the threadlist.
void ThreatManager::resetAllAggro()
{
- std::list<HostileReference*> &threatlist = getThreatList();
- if (threatlist.empty())
+ std::list<HostileReference*> &threatList = getThreatList();
+ if (threatList.empty())
return;
- for (std::list<HostileReference*>::iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
+ for (std::list<HostileReference*>::iterator itr = threatList.begin(); itr != threatList.end(); ++itr)
{
(*itr)->setThreat(0);
}