Skip to content

Commit

Permalink
Don't iterate auras to find taunters.
Browse files Browse the repository at this point in the history
GetTauntTarget is supposedly taking up a lot of cpu time. This is an attempt at optimization.
  • Loading branch information
ratkosrb committed Aug 2, 2023
1 parent 883d69b commit 0e7c8d1
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 49 deletions.
57 changes: 28 additions & 29 deletions src/game/Objects/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7369,55 +7369,54 @@ void Unit::TauntFadeOut(Unit* taunter)

//======================================================================

Unit* Unit::GetTauntTarget() const
void Unit::RemoveTauntCaster(ObjectGuid guid)
{
AuraList const& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT);
if (tauntAuras.empty())
return nullptr;
// remove only 1 occurance, starting from the front
// since guids are pushed back on taunt aura apply
for (auto itr = m_tauntGuids.begin(); itr != m_tauntGuids.end(); ++itr)
{
if ((*itr) == guid)
{
m_tauntGuids.erase(itr);
return;
}
}
}

Unit* caster = nullptr;
//======================================================================

// The last taunt aura caster is alive an we are happy to attack him
if ((caster = tauntAuras.back()->GetCaster()) && IsValidAttackTarget(caster))
return caster;
else if (tauntAuras.size() > 1)
Unit* Unit::GetTauntTarget() const
{
// taunters are pushed back, last caster will be at the end
for (auto itr = m_tauntGuids.rbegin(); itr != m_tauntGuids.rend(); ++itr)
{
// We do not have last taunt aura caster but we have more taunt auras,
// so find first available target

// Auras are pushed_back, last caster will be on the end
AuraList::const_iterator aura = --tauntAuras.end();
do
if (Unit* pTaunter = GetMap()->GetUnit(*itr))
{
--aura;
if ((caster = (*aura)->GetCaster()) && caster->IsInMap(this) && IsValidAttackTarget(caster))
{
return caster;
break;
}
} while (aura != tauntAuras.begin());
if (IsValidAttackTarget(pTaunter))
return pTaunter;
}
}

return nullptr;
}

bool Unit::SelectHostileTarget()
{
//function provides main threat functionality
//next-victim-selection algorithm and evade mode are called
//threat list sorting etc.
// function provides main threat functionality
// next-victim-selection algorithm and evade mode are called
// threat list sorting etc.

MANGOS_ASSERT(IsCreature());

if (!this->IsAlive())
if (!IsAlive())
return false;

//This function only useful once AI has been initialized
// This function is only useful once AI has been initialized
if (!((Creature*)this)->AI())
return false;

// Nostalrius: delai de 5 sec avant attaque apres spawn.
if (ToCreature()->IsTempPacified())
// Nostalrius: 5 sec delay before attack after spawn.
if (((Creature*)this)->IsTempPacified())
return false;

Unit* target = GetTauntTarget();
Expand Down
3 changes: 3 additions & 0 deletions src/game/Objects/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ class Unit : public SpellCaster
float m_meleeZReach;
ThreatManager m_ThreatManager; // Manage all Units threatening us
HostileRefManager m_HostileRefManager; // Manage all Units that are threatened by us
std::vector<ObjectGuid> m_tauntGuids;
protected:
uint32 m_attackTimer[MAX_ATTACK];
AttackerSet m_attackers;
Expand Down Expand Up @@ -1086,6 +1087,8 @@ class Unit : public SpellCaster
Unit* GetTauntTarget() const;
void TauntApply(Unit* pVictim);
void TauntFadeOut(Unit* taunter);
void AddTauntCaster(ObjectGuid guid) { m_tauntGuids.push_back(guid); }
void RemoveTauntCaster(ObjectGuid guid);

// Threat related methods
bool CanHaveThreatList() const;
Expand Down
5 changes: 5 additions & 0 deletions src/game/Spells/SpellAuras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4109,6 +4109,11 @@ void Aura::HandleModTaunt(bool apply, bool Real)

Unit* target = GetTarget();

if (apply)
target->AddTauntCaster(GetCasterGuid());
else
target->RemoveTauntCaster(GetCasterGuid());

if (!target->IsAlive() || !target->CanHaveThreatList())
return;

Expand Down
15 changes: 6 additions & 9 deletions src/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,16 @@ struct boss_ironayaAI : public ScriptedAI
if (!hasCastedKnockaway && m_creature->GetHealthPercent() < 50.0f)
{
m_creature->CastSpell(m_creature->GetVictim(), SPELL_KNOCKAWAY, false);
m_creature->GetThreatManager().modifyThreatPercent(m_creature->GetVictim(), -100);

// current aggro target is knocked away pick new target
Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0);
Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0);

if (!Target || Target == m_creature->GetVictim())
{
Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1);
}
if (!pTarget || pTarget == m_creature->GetVictim())
pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1);

if (Target)
{
m_creature->TauntApply(Target);
}
if (pTarget)
AttackStart(pTarget);

//Shouldn't cast this again
hasCastedKnockaway = true;
Expand Down
18 changes: 7 additions & 11 deletions src/scripts/eastern_kingdoms/uldaman/uldaman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,23 +156,19 @@ struct mob_jadespine_basiliskAI : public ScriptedAI
if (Cslumber_Timer < diff)
{
//Cast
// DoCastSpellIfCan(m_creature->GetVictim(),SPELL_CRYSTALLINE_SLUMBER);
m_creature->CastSpell(m_creature->GetVictim(), SPELL_CRYSTALLINE_SLUMBER, false);
m_creature->GetThreatManager().modifyThreatPercent(m_creature->GetVictim(), -100);

//Stop attacking target thast asleep and pick new target
//Stop attacking target thats asleep and pick new target
Cslumber_Timer = 28000;

Unit* Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0);
Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0);

if (!Target || Target == m_creature->GetVictim())
{
Target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
}
if (!pTarget || pTarget == m_creature->GetVictim())
pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1);

if (Target)
{
m_creature->TauntApply(Target);
}
if (pTarget)
AttackStart(pTarget);
}
else Cslumber_Timer -= diff;

Expand Down

0 comments on commit 0e7c8d1

Please sign in to comment.