Core: Cosmetic changes in Threat related code (per request) and remove of extra call to SpellMgr singleton inside that singleton
This commit is contained in:
@@ -29,39 +29,37 @@ HostileRefManager::~HostileRefManager()
|
||||
}
|
||||
|
||||
//=================================================
|
||||
// send threat to all my hateres for the pVictim
|
||||
// The pVictim is hated than by them as well
|
||||
// send threat to all my hateres for the victim
|
||||
// The victim is hated than by them as well
|
||||
// use for buffs and healing threat functionality
|
||||
|
||||
void HostileRefManager::threatAssist(Unit *pVictim, float fThreat, SpellInfo const *pThreatSpell, bool pSingleTarget)
|
||||
void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell)
|
||||
{
|
||||
HostileReference* ref;
|
||||
|
||||
float size = pSingleTarget ? 1.0f : getSize(); // if pSingleTarget do not divide threat
|
||||
ref = getFirst();
|
||||
while (ref != NULL)
|
||||
HostileReference* ref = getFirst();
|
||||
float threat = ThreatCalcHelper::calcThreat(victim, iOwner, baseThreat, (threatSpell ? threatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), threatSpell);
|
||||
threat /= getSize();
|
||||
while (ref)
|
||||
{
|
||||
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, fThreat, (pThreatSpell ? pThreatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell);
|
||||
if (pVictim == getOwner())
|
||||
ref->addThreat(threat / size); // It is faster to modify the threat durectly if possible
|
||||
if (victim == getOwner())
|
||||
ref->addThreat(threat); // It is faster to modify the threat durectly if possible
|
||||
else
|
||||
ref->getSource()->addThreat(pVictim, threat / size);
|
||||
ref->getSource()->addThreat(victim, threat);
|
||||
ref = ref->next();
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================
|
||||
|
||||
void HostileRefManager::addTempThreat(float fThreat, bool apply)
|
||||
void HostileRefManager::addTempThreat(float threat, bool apply)
|
||||
{
|
||||
HostileReference* ref = getFirst();
|
||||
|
||||
while (ref != NULL)
|
||||
while (ref)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
if (ref->getTempThreatModifier() == 0.0f)
|
||||
ref->addTempThreat(fThreat);
|
||||
ref->addTempThreat(threat);
|
||||
}
|
||||
else
|
||||
ref->resetTempThreat();
|
||||
@@ -72,14 +70,12 @@ void HostileRefManager::addTempThreat(float fThreat, bool apply)
|
||||
|
||||
//=================================================
|
||||
|
||||
void HostileRefManager::addThreatPercent(int32 iPercent)
|
||||
void HostileRefManager::addThreatPercent(int32 percent)
|
||||
{
|
||||
HostileReference* ref;
|
||||
|
||||
ref = getFirst();
|
||||
while (ref != NULL)
|
||||
HostileReference* ref = getFirst();
|
||||
while (ref)
|
||||
{
|
||||
ref->addThreatPercent(iPercent);
|
||||
ref->addThreatPercent(percent);
|
||||
ref = ref->next();
|
||||
}
|
||||
}
|
||||
@@ -87,14 +83,12 @@ void HostileRefManager::addThreatPercent(int32 iPercent)
|
||||
//=================================================
|
||||
// The online / offline status is given to the method. The calculation has to be done before
|
||||
|
||||
void HostileRefManager::setOnlineOfflineState(bool bIsOnline)
|
||||
void HostileRefManager::setOnlineOfflineState(bool isOnline)
|
||||
{
|
||||
HostileReference* ref;
|
||||
|
||||
ref = getFirst();
|
||||
while (ref != NULL)
|
||||
HostileReference* ref = getFirst();
|
||||
while (ref)
|
||||
{
|
||||
ref->setOnlineOfflineState(bIsOnline);
|
||||
ref->setOnlineOfflineState(isOnline);
|
||||
ref = ref->next();
|
||||
}
|
||||
}
|
||||
@@ -149,13 +143,13 @@ void HostileRefManager::deleteReferencesForFaction(uint32 faction)
|
||||
//=================================================
|
||||
// delete one reference, defined by Unit
|
||||
|
||||
void HostileRefManager::deleteReference(Unit *pCreature)
|
||||
void HostileRefManager::deleteReference(Unit *creature)
|
||||
{
|
||||
HostileReference* ref = getFirst();
|
||||
while (ref)
|
||||
{
|
||||
HostileReference* nextRef = ref->next();
|
||||
if (ref->getSource()->getOwner() == pCreature)
|
||||
if (ref->getSource()->getOwner() == creature)
|
||||
{
|
||||
ref->removeReference();
|
||||
delete ref;
|
||||
@@ -168,15 +162,15 @@ void HostileRefManager::deleteReference(Unit *pCreature)
|
||||
//=================================================
|
||||
// set state for one reference, defined by Unit
|
||||
|
||||
void HostileRefManager::setOnlineOfflineState(Unit *pCreature, bool bIsOnline)
|
||||
void HostileRefManager::setOnlineOfflineState(Unit *creature, bool isOnline)
|
||||
{
|
||||
HostileReference* ref = getFirst();
|
||||
while (ref)
|
||||
{
|
||||
HostileReference* nextRef = ref->next();
|
||||
if (ref->getSource()->getOwner() == pCreature)
|
||||
if (ref->getSource()->getOwner() == creature)
|
||||
{
|
||||
ref->setOnlineOfflineState(bIsOnline);
|
||||
ref->setOnlineOfflineState(isOnline);
|
||||
break;
|
||||
}
|
||||
ref = nextRef;
|
||||
|
||||
@@ -34,19 +34,19 @@ class HostileRefManager : public RefManager<Unit, ThreatManager>
|
||||
private:
|
||||
Unit *iOwner;
|
||||
public:
|
||||
explicit HostileRefManager(Unit *pOwner) { iOwner = pOwner; }
|
||||
explicit HostileRefManager(Unit *owner) { iOwner = owner; }
|
||||
~HostileRefManager();
|
||||
|
||||
Unit* getOwner() { return iOwner; }
|
||||
|
||||
// send threat to all my hateres for the pVictim
|
||||
// The pVictim is hated than by them as well
|
||||
// send threat to all my hateres for the victim
|
||||
// The victim is hated than by them as well
|
||||
// use for buffs and healing threat functionality
|
||||
void threatAssist(Unit *pVictim, float fThreat, SpellInfo const *threatSpell = 0, bool pSingleTarget = false);
|
||||
void threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell = NULL);
|
||||
|
||||
void addTempThreat(float fThreat, bool apply);
|
||||
void addTempThreat(float threat, bool apply);
|
||||
|
||||
void addThreatPercent(int32 iPercent);
|
||||
void addThreatPercent(int32 percent);
|
||||
|
||||
// The references are not needed anymore
|
||||
// tell the source to remove them from the list and free the mem
|
||||
@@ -59,13 +59,13 @@ class HostileRefManager : public RefManager<Unit, ThreatManager>
|
||||
|
||||
void updateThreatTables();
|
||||
|
||||
void setOnlineOfflineState(bool bIsOnline);
|
||||
void setOnlineOfflineState(bool isOnline);
|
||||
|
||||
// set state for one reference, defined by Unit
|
||||
void setOnlineOfflineState(Unit *pCreature, bool bIsOnline);
|
||||
void setOnlineOfflineState(Unit *creature, bool isOnline);
|
||||
|
||||
// delete one reference, defined by Unit
|
||||
void deleteReference(Unit *pCreature);
|
||||
void deleteReference(Unit *creature);
|
||||
|
||||
void UpdateVisibility();
|
||||
};
|
||||
|
||||
@@ -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())
|
||||
if (!ThreatCalcHelper::isValidProcess(victim, getOwner(), threatSpell))
|
||||
return;
|
||||
|
||||
// not to GM
|
||||
if (!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->ToPlayer()->isGameMaster()))
|
||||
return;
|
||||
|
||||
// not to dead and not for dead
|
||||
if (!pVictim->isAlive() || !getOwner()->isAlive())
|
||||
return;
|
||||
|
||||
ASSERT(getOwner()->GetTypeId() == TYPEID_UNIT);
|
||||
|
||||
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, fThreat, schoolMask, pThreatSpell);
|
||||
|
||||
// must check > 0.0f, otherwise dead loop
|
||||
if (threat > 0.0f && pVictim->GetReducedThreatPercent())
|
||||
{
|
||||
uint32 reducedThreadPercent = pVictim->GetReducedThreatPercent();
|
||||
|
||||
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;
|
||||
threat -= reducedThreat;
|
||||
if (unit)
|
||||
_addThreat(unit, reducedThreat);
|
||||
}
|
||||
|
||||
_addThreat(pVictim, threat);
|
||||
doAddThreat(victim, ThreatCalcHelper::calcThreat(victim, iOwner, threat, schoolMask, threatSpell));
|
||||
}
|
||||
|
||||
void ThreatManager::_addThreat(Unit *pVictim, float fThreat)
|
||||
void ThreatManager::doAddThreat(Unit* victim, float threat)
|
||||
{
|
||||
HostileReference* ref = iThreatContainer.addThreat(pVictim, fThreat);
|
||||
uint32 reducedThreadPercent = victim->GetReducedThreatPercent();
|
||||
|
||||
// must check > 0.0f, otherwise dead loop
|
||||
if (threat > 0.0f && reducedThreadPercent)
|
||||
{
|
||||
Unit* redirectTarget = victim->GetMisdirectionTarget();
|
||||
if (redirectTarget)
|
||||
if (Aura* glyphAura = redirectTarget->GetAura(63326)) // Glyph of Vigilance
|
||||
reducedThreadPercent += glyphAura->GetSpellInfo()->Effects[0].CalcValue();
|
||||
|
||||
float reducedThreat = threat * reducedThreadPercent / 100.0f;
|
||||
threat -= reducedThreat;
|
||||
if (redirectTarget)
|
||||
_addThreat(redirectTarget, reducedThreat);
|
||||
}
|
||||
|
||||
_addThreat(victim, threat);
|
||||
}
|
||||
|
||||
void ThreatManager::_addThreat(Unit* victim, float threat)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#define _THREATMANAGER
|
||||
|
||||
#include "Common.h"
|
||||
#include "Util.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "LinkedReference/Reference.h"
|
||||
#include "UnitEvents.h"
|
||||
@@ -39,29 +38,24 @@ class SpellInfo;
|
||||
//==============================================================
|
||||
// Class to calculate the real threat based
|
||||
|
||||
class ThreatCalcHelper
|
||||
struct ThreatCalcHelper
|
||||
{
|
||||
public:
|
||||
static float calcThreat(Unit* pHatedUnit, Unit* pHatingUnit, float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell = NULL);
|
||||
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL);
|
||||
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = NULL);
|
||||
};
|
||||
|
||||
//==============================================================
|
||||
class HostileReference : public Reference<Unit, ThreatManager>
|
||||
{
|
||||
public:
|
||||
HostileReference(Unit* pUnit, ThreatManager *pThreatManager, float fThreat);
|
||||
HostileReference(Unit* refUnit, ThreatManager* threatManager, float threat);
|
||||
|
||||
//=================================================
|
||||
void addThreat(float fModThreat);
|
||||
void addThreat(float modThreat);
|
||||
|
||||
void setThreat(float fThreat) { addThreat(fThreat - getThreat()); }
|
||||
void setThreat(float threat) { addThreat(threat - getThreat()); }
|
||||
|
||||
void addThreatPercent(int32 pPercent)
|
||||
{
|
||||
float tmpThreat = iThreat;
|
||||
AddPctN(tmpThreat, pPercent);
|
||||
addThreat(tmpThreat - iThreat);
|
||||
}
|
||||
void addThreatPercent(int32 percent);
|
||||
|
||||
float getThreat() const { return iThreat; }
|
||||
|
||||
@@ -73,14 +67,14 @@ class HostileReference : public Reference<Unit, ThreatManager>
|
||||
|
||||
// used for temporary setting a threat and reducting it later again.
|
||||
// the threat modification is stored
|
||||
void setTempThreat(float fThreat)
|
||||
void setTempThreat(float threat)
|
||||
{
|
||||
addTempThreat(fThreat - getThreat());
|
||||
addTempThreat(threat - getThreat());
|
||||
}
|
||||
|
||||
void addTempThreat(float fThreat)
|
||||
void addTempThreat(float threat)
|
||||
{
|
||||
iTempThreatModifier = fThreat;
|
||||
iTempThreatModifier = threat;
|
||||
if (iTempThreatModifier != 0.0f)
|
||||
addThreat(iTempThreatModifier);
|
||||
}
|
||||
@@ -100,12 +94,12 @@ class HostileReference : public Reference<Unit, ThreatManager>
|
||||
// check, if source can reach target and set the status
|
||||
void updateOnlineStatus();
|
||||
|
||||
void setOnlineOfflineState(bool pIsOnline);
|
||||
void setOnlineOfflineState(bool isOnline);
|
||||
|
||||
void setAccessibleState(bool pIsAccessible);
|
||||
void setAccessibleState(bool isAccessible);
|
||||
//=================================================
|
||||
|
||||
bool operator == (const HostileReference& pHostileReference) const { return pHostileReference.getUnitGuid() == getUnitGuid(); }
|
||||
bool operator == (const HostileReference& hostileRef) const { return hostileRef.getUnitGuid() == getUnitGuid(); }
|
||||
|
||||
//=================================================
|
||||
|
||||
@@ -132,7 +126,7 @@ class HostileReference : public Reference<Unit, ThreatManager>
|
||||
void sourceObjectDestroyLink();
|
||||
private:
|
||||
// Inform the source, that the status of that reference was changed
|
||||
void fireStatusChanged(ThreatRefStatusChangeEvent& pThreatRefStatusChangeEvent);
|
||||
void fireStatusChanged(ThreatRefStatusChangeEvent& threatRefStatusChangeEvent);
|
||||
|
||||
Unit* getSourceUnit();
|
||||
private:
|
||||
@@ -154,30 +148,31 @@ class ThreatContainer
|
||||
protected:
|
||||
friend class ThreatManager;
|
||||
|
||||
void remove(HostileReference* pRef) { iThreatList.remove(pRef); }
|
||||
void addReference(HostileReference* pHostileReference) { iThreatList.push_back(pHostileReference); }
|
||||
void remove(HostileReference* hostileRef) { iThreatList.remove(hostileRef); }
|
||||
void addReference(HostileReference* hostileRef) { iThreatList.push_back(hostileRef); }
|
||||
void clearReferences();
|
||||
|
||||
// Sort the list if necessary
|
||||
void update();
|
||||
public:
|
||||
ThreatContainer() { iDirty = false; }
|
||||
~ThreatContainer() { clearReferences(); }
|
||||
|
||||
HostileReference* addThreat(Unit* pVictim, float fThreat);
|
||||
HostileReference* addThreat(Unit* victim, float threat);
|
||||
|
||||
void modifyThreatPercent(Unit *pVictim, int32 iPercent);
|
||||
void modifyThreatPercent(Unit *victim, int32 percent);
|
||||
|
||||
HostileReference* selectNextVictim(Creature* pAttacker, HostileReference* pCurrentVictim);
|
||||
HostileReference* selectNextVictim(Creature* attacker, HostileReference* currentVictim);
|
||||
|
||||
void setDirty(bool pDirty) { iDirty = pDirty; }
|
||||
void setDirty(bool isDirty) { iDirty = isDirty; }
|
||||
|
||||
bool isDirty() const { return iDirty; }
|
||||
|
||||
bool empty() const { return(iThreatList.empty()); }
|
||||
bool empty() const { return iThreatList.empty(); }
|
||||
|
||||
HostileReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); }
|
||||
|
||||
HostileReference* getReferenceByTarget(Unit* pVictim);
|
||||
HostileReference* getReferenceByTarget(Unit* victim);
|
||||
|
||||
std::list<HostileReference*>& getThreatList() { return iThreatList; }
|
||||
};
|
||||
@@ -189,16 +184,19 @@ class ThreatManager
|
||||
public:
|
||||
friend class HostileReference;
|
||||
|
||||
explicit ThreatManager(Unit *pOwner);
|
||||
explicit ThreatManager(Unit *owner);
|
||||
|
||||
~ThreatManager() { clearReferences(); }
|
||||
|
||||
void clearReferences();
|
||||
|
||||
void addThreat(Unit* pVictim, float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const *threatSpell = NULL);
|
||||
void modifyThreatPercent(Unit *pVictim, int32 iPercent);
|
||||
void addThreat(Unit* victim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL);
|
||||
|
||||
float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false);
|
||||
void doAddThreat(Unit* victim, float threat);
|
||||
|
||||
void modifyThreatPercent(Unit *victim, int32 percent);
|
||||
|
||||
float getThreat(Unit *victim, bool alsoSearchOfflineList = false);
|
||||
|
||||
bool isThreatListEmpty() { return iThreatContainer.empty(); }
|
||||
|
||||
@@ -212,12 +210,12 @@ class ThreatManager
|
||||
|
||||
Unit* getHostilTarget();
|
||||
|
||||
void tauntApply(Unit* pTaunter);
|
||||
void tauntFadeOut(Unit *pTaunter);
|
||||
void tauntApply(Unit* taunter);
|
||||
void tauntFadeOut(Unit *taunter);
|
||||
|
||||
void setCurrentVictim(HostileReference* pHostileReference);
|
||||
void setCurrentVictim(HostileReference* hostileRef);
|
||||
|
||||
void setDirty(bool bDirty) { iThreatContainer.setDirty(bDirty); }
|
||||
void setDirty(bool isDirty) { iThreatContainer.setDirty(isDirty); }
|
||||
|
||||
// Reset all aggro without modifying the threadlist.
|
||||
void resetAllAggro();
|
||||
@@ -225,11 +223,11 @@ class ThreatManager
|
||||
// Reset all aggro of unit in threadlist satisfying the predicate.
|
||||
template<class PREDICATE> void resetAggro(PREDICATE predicate)
|
||||
{
|
||||
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)
|
||||
{
|
||||
HostileReference* ref = (*itr);
|
||||
|
||||
@@ -248,7 +246,7 @@ class ThreatManager
|
||||
ThreatContainer& getOnlineContainer() { return iThreatContainer; }
|
||||
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
|
||||
private:
|
||||
void _addThreat(Unit *pVictim, float fThreat);
|
||||
void _addThreat(Unit *victim, float threat);
|
||||
|
||||
HostileReference* iCurrentVictim;
|
||||
Unit* iOwner;
|
||||
@@ -266,7 +264,7 @@ namespace Trinity
|
||||
{
|
||||
public:
|
||||
ThreatOrderPred(bool ascending = false) : m_ascending(ascending) {}
|
||||
bool operator() (const HostileReference *a, const HostileReference *b) const
|
||||
bool operator() (HostileReference const* a, HostileReference const* b) const
|
||||
{
|
||||
return m_ascending ? a->getThreat() < b->getThreat() : a->getThreat() > b->getThreat();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user