AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
ThreatContainer Class Reference

#include "ThreatMgr.h"

Public Types

typedef std::list< HostileReference * > StorageType
 

Public Member Functions

 ThreatContainer ()=default
 
 ~ThreatContainer ()
 
HostileReferenceAddThreat (Unit *victim, float threat)
 
void ModifyThreatByPercent (Unit *victim, int32 percent)
 
HostileReferenceSelectNextVictim (Creature *attacker, HostileReference *currentVictim) const
 
HostileReferenceSelectNextVictimTieBreaker (Creature *attacker, ThreatContainer::StorageType::const_iterator currentIter, bool noPriorityTargetFound) const
 
bool IsPreferredTarget (Creature *attacker, Unit *target) const
 
void setDirty (bool isDirty)
 
bool isDirty () const
 
bool empty () const
 
HostileReferencegetMostHated () const
 
HostileReferencegetReferenceByTarget (Unit const *victim) const
 
HostileReferencegetReferenceByTarget (ObjectGuid const &guid) const
 
StorageType const & GetThreatList () const
 

Private Member Functions

void remove (HostileReference *hostileRef)
 
void addReference (HostileReference *hostileRef)
 
void clearReferences ()
 
void update ()
 

Private Attributes

StorageType iThreatList
 
bool iDirty {false}
 

Friends

class ThreatMgr
 

Detailed Description

Member Typedef Documentation

◆ StorageType

Constructor & Destructor Documentation

◆ ThreatContainer()

ThreatContainer::ThreatContainer ( )
default

◆ ~ThreatContainer()

ThreatContainer::~ThreatContainer ( )
inline
151{ clearReferences(); }
void clearReferences()
Definition ThreatMgr.cpp:248

References clearReferences().

Member Function Documentation

◆ addReference()

void ThreatContainer::addReference ( HostileReference hostileRef)
inlineprivate
189 {
190 iThreatList.push_back(hostileRef);
191 }
StorageType iThreatList
Definition ThreatMgr.h:198

References iThreatList.

Referenced by ThreatMgr::_addThreat(), and ThreatMgr::processThreatEvent().

◆ AddThreat()

HostileReference * ThreatContainer::AddThreat ( Unit victim,
float  threat 
)
287{
289 if (ref)
290 ref->AddThreat(threat);
291 return ref;
292}
Definition ThreatMgr.h:48
void AddThreat(float modThreat)
Definition ThreatMgr.cpp:138
HostileReference * getReferenceByTarget(Unit const *victim) const
Definition ThreatMgr.cpp:261

References HostileReference::AddThreat(), and getReferenceByTarget().

Referenced by ThreatMgr::_addThreat().

◆ clearReferences()

void ThreatContainer::clearReferences ( )
private
249{
250 for (ThreatContainer::StorageType::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
251 {
252 (*i)->unlink();
253 delete (*i);
254 }
255
256 iThreatList.clear();
257}

References iThreatList.

Referenced by ThreatMgr::clearReferences(), and ~ThreatContainer().

◆ empty()

bool ThreatContainer::empty ( ) const
inline
168 {
169 return iThreatList.empty();
170 }

References iThreatList.

Referenced by ThreatMgr::areThreatListsEmpty(), Spell::EffectTaunt(), and ThreatMgr::isThreatListEmpty().

◆ getMostHated()

HostileReference * ThreatContainer::getMostHated ( ) const
inline
173 {
174 return iThreatList.empty() ? nullptr : iThreatList.front();
175 }

References iThreatList.

Referenced by Spell::EffectTaunt().

◆ getReferenceByTarget() [1/2]

HostileReference * ThreatContainer::getReferenceByTarget ( ObjectGuid const &  guid) const
270{
271 for (ThreatContainer::StorageType::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i)
272 {
273 HostileReference* ref = (*i);
274 if (ref && ref->getUnitGuid() == guid)
275 {
276 return ref;
277 }
278 }
279
280 return nullptr;
281}
ObjectGuid getUnitGuid() const
Definition ThreatMgr.h:106

References HostileReference::getUnitGuid(), and iThreatList.

◆ getReferenceByTarget() [2/2]

◆ GetThreatList()

◆ isDirty()

bool ThreatContainer::isDirty ( ) const
inline
165{ return iDirty; }
bool iDirty
Definition ThreatMgr.h:199

References iDirty.

Referenced by setDirty().

◆ IsPreferredTarget()

bool ThreatContainer::IsPreferredTarget ( Creature attacker,
Unit target 
) const
458{
460 return false;
461
463 return false;
464
466 return false;
467
468 if (target->HasAuraTypeWithCaster(SPELL_AURA_IGNORED, attacker->GetGUID()))
469 return false;
470
471 if (attacker->HasUnitState(UNIT_STATE_ROOT) && attacker->IsCombatMovementAllowed() && !attacker->IsWithinMeleeRange(target))
472 return false;
473
474 return true;
475}
@ SPELL_AURA_IGNORED
Definition SpellAuraDefines.h:284
@ AURA_INTERRUPT_FLAG_TAKE_DAMAGE
Definition SpellDefines.h:44
@ UNIT_STATE_CONFUSED
Definition UnitDefines.h:181
@ UNIT_STATE_ROOT
Definition UnitDefines.h:180
bool IsCombatMovementAllowed() const
Definition Creature.h:435
SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType=BASE_ATTACK, uint8=0) const override
Definition Creature.h:163
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:113
bool HasNegativeAuraWithInterruptFlag(uint32 flag, ObjectGuid guid=ObjectGuid::Empty)
Definition Unit.cpp:5922
bool HasAuraTypeWithCaster(AuraType auratype, ObjectGuid caster) const
Definition Unit.cpp:5863
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:665
bool HasUnitState(const uint32 f) const
Definition Unit.h:726
bool IsImmunedToDamageOrSchool(SpellSchoolMask meleeSchoolMask) const
Definition Unit.cpp:13080

References AURA_INTERRUPT_FLAG_TAKE_DAMAGE, Object::GetGUID(), Creature::GetMeleeDamageSchoolMask(), Unit::HasAuraTypeWithCaster(), Unit::HasNegativeAuraWithInterruptFlag(), Unit::HasUnitState(), Creature::IsCombatMovementAllowed(), Unit::IsImmunedToDamageOrSchool(), Unit::IsWithinMeleeRange(), SPELL_AURA_IGNORED, UNIT_STATE_CONFUSED, and UNIT_STATE_ROOT.

Referenced by SelectNextVictim(), and SelectNextVictimTieBreaker().

◆ ModifyThreatByPercent()

void ThreatContainer::ModifyThreatByPercent ( Unit victim,
int32  percent 
)
297{
298 if (HostileReference* ref = getReferenceByTarget(victim))
299 ref->addThreatPercent(percent);
300}

References HostileReference::addThreatPercent(), and getReferenceByTarget().

Referenced by ThreatMgr::ModifyThreatByPercent().

◆ remove()

void ThreatContainer::remove ( HostileReference hostileRef)
inlineprivate
184 {
185 iThreatList.remove(hostileRef);
186 }

References iThreatList.

Referenced by ThreatMgr::processThreatEvent().

◆ SelectNextVictim()

HostileReference * ThreatContainer::SelectNextVictim ( Creature attacker,
HostileReference currentVictim 
) const
318{
319 // pussywizard: pretty much remade this whole function
320
321 HostileReference* currentRef = nullptr;
322 bool found = false;
323 bool noPriorityTargetFound = false;
324
325 // pussywizard: currentVictim is needed to compare if threat was exceeded by 10%/30% for melee/range targets (only then switching current target)
326 if (currentVictim)
327 {
328 Unit* cvUnit = currentVictim->getTarget();
329 if (!attacker->CanCreatureAttack(cvUnit)) // pussywizard: if currentVictim is not valid => don't compare the threat with it, just take the highest threat valid target
330 currentVictim = nullptr;
331 else if (!IsPreferredTarget(attacker, cvUnit)) // pussywizard: no 10%/30% if currentVictim is immune to damage or has auras breakable by damage
332 currentVictim = nullptr;
333 }
334
335 ThreatContainer::StorageType::const_iterator lastRef = iThreatList.end();
336 --lastRef;
337
338 // pussywizard: iterate from highest to lowest threat
339 for (ThreatContainer::StorageType::const_iterator iter = iThreatList.begin(); iter != iThreatList.end() && !found;)
340 {
341 currentRef = (*iter);
342
343 Unit* target = currentRef->getTarget();
344 ASSERT(target); // if the ref has status online the target must be there !
345
346 // pussywizard: don't go to threat comparison if this ref is immune to damage or has aura breakable on damage (second choice target)
347 // pussywizard: if this is the last entry on the threat list, then all targets are second choice, set bool to true and loop threat list again, ignoring this section
348 if (!noPriorityTargetFound && !IsPreferredTarget(attacker, target))
349 {
350 if (iter != lastRef)
351 {
352 ++iter;
353 continue;
354 }
355 else
356 {
357 noPriorityTargetFound = true;
358 iter = iThreatList.begin();
359 continue;
360 }
361 }
362
363 // pussywizard: skip not valid targets
364 if (attacker->CanCreatureAttack(target))
365 {
366 if (currentVictim) // pussywizard: if not nullptr then target must have 10%/30% more threat
367 {
368 if (currentVictim == currentRef) // pussywizard: nothing found previously was good and enough, currentRef passed all necessary tests, so end now
369 {
370 found = true;
371 break;
372 }
373
374 // pussywizard: implement 110% threat rule for targets in melee range and 130% rule for targets in ranged distances
375 if (currentRef->GetThreat() > 1.3f * currentVictim->GetThreat()) // pussywizard: enough in all cases, end
376 {
377 found = true;
378 break;
379 }
380 else if (currentRef->GetThreat() > 1.1f * currentVictim->GetThreat()) // pussywizard: enought only if target in melee range
381 {
382 if (attacker->IsWithinMeleeRange(target))
383 {
384 found = true;
385 break;
386 }
387 }
388 else // pussywizard: nothing found previously was good and enough, this and next entries on the list have less than 110% threat, and currentVictim is present and valid as checked before the loop (otherwise it's nullptr), so end now
389 {
390 currentRef = currentVictim;
391 found = true;
392 break;
393 }
394 }
395 else // pussywizard: no currentVictim, first passing all checks is chosen (highest threat, list is sorted)
396 {
397 // tie-breaker if multiple targets have the same threat: select closest target
398 currentRef = SelectNextVictimTieBreaker(attacker, iter, noPriorityTargetFound);
399 found = true;
400 break;
401 }
402 }
403 ++iter;
404 }
405 if (!found)
406 currentRef = nullptr;
407
408 return currentRef;
409}
#define ASSERT
Definition Errors.h:68
bool CanCreatureAttack(Unit const *victim, bool skipDistCheck=false) const
Definition Creature.cpp:2583
float GetThreat() const
Definition ThreatMgr.h:62
TO * getTarget() const
Definition Reference.h:95
HostileReference * SelectNextVictimTieBreaker(Creature *attacker, ThreatContainer::StorageType::const_iterator currentIter, bool noPriorityTargetFound) const
Definition ThreatMgr.cpp:412
bool IsPreferredTarget(Creature *attacker, Unit *target) const
Definition ThreatMgr.cpp:457
Definition Unit.h:655

References ASSERT, Creature::CanCreatureAttack(), Reference< TO, FROM >::getTarget(), HostileReference::GetThreat(), IsPreferredTarget(), Unit::IsWithinMeleeRange(), iThreatList, and SelectNextVictimTieBreaker().

Referenced by ThreatMgr::getHostileTarget().

◆ SelectNextVictimTieBreaker()

HostileReference * ThreatContainer::SelectNextVictimTieBreaker ( Creature attacker,
ThreatContainer::StorageType::const_iterator  currentIter,
bool  noPriorityTargetFound 
) const
413{
414 HostileReference* bestRef = *currentIter;
415 float bestThreat = bestRef->GetThreat();
416 float shortestDistSq = attacker->GetExactDistSq(bestRef->getTarget());
417
418 auto tieIter = std::next(currentIter);
419
420 while (tieIter != iThreatList.end())
421 {
422 HostileReference* nextRef = *tieIter;
423
424 if (!nextRef)
425 {
426 ++tieIter;
427 continue;
428 }
429
430 // Threatlist is sorted, so we can stop as soon as we find a lower threat
431 if (bestThreat - nextRef->GetThreat() > 0.01f)
432 break;
433
434 Unit* target = nextRef->getTarget();
435
436 if (!target)
437 {
438 ++tieIter;
439 continue;
440 }
441
442 if (attacker->CanCreatureAttack(target) && (noPriorityTargetFound || IsPreferredTarget(attacker, target)))
443 {
444 float distSq = attacker->GetExactDistSq(target);
445 if (distSq < shortestDistSq)
446 {
447 bestRef = nextRef;
448 shortestDistSq = distSq;
449 }
450 }
451 ++tieIter;
452 }
453 return bestRef;
454}
float GetExactDistSq(float x, float y, float z) const
Definition Position.h:174

References Creature::CanCreatureAttack(), Position::GetExactDistSq(), Reference< TO, FROM >::getTarget(), HostileReference::GetThreat(), IsPreferredTarget(), and iThreatList.

Referenced by SelectNextVictim().

◆ setDirty()

void ThreatContainer::setDirty ( bool  isDirty)
inline
163{ iDirty = isDirty; }
bool isDirty() const
Definition ThreatMgr.h:165

References iDirty, and isDirty().

Referenced by ThreatMgr::setDirty().

◆ update()

void ThreatContainer::update ( )
private
306{
307 if (iDirty && iThreatList.size() > 1)
309
310 iDirty = false;
311}
Definition ThreatMgr.h:324

References iDirty, and iThreatList.

Referenced by ThreatMgr::getHostileTarget().

Friends And Related Symbol Documentation

◆ ThreatMgr

friend class ThreatMgr
friend

Member Data Documentation

◆ iDirty

bool ThreatContainer::iDirty {false}
private
199{false};

Referenced by isDirty(), setDirty(), and update().

◆ iThreatList


The documentation for this class was generated from the following files: