feat(Core/AI): convert SelectAggroTarget to enum class (#9893)

This commit is contained in:
Kargatum
2021-12-29 05:13:12 +07:00
committed by GitHub
parent e928d8b67e
commit c81891fc11
236 changed files with 622 additions and 598 deletions

View File

@@ -90,12 +90,12 @@ bool UnitAI::DoSpellAttackIfReady(uint32 spell)
return false;
}
Unit* UnitAI::SelectTarget(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly, int32 aura)
Unit* UnitAI::SelectTarget(SelectTargetMethod targetType, uint32 position, float dist, bool playerOnly, int32 aura)
{
return SelectTarget(targetType, position, DefaultTargetSelector(me, dist, playerOnly, aura));
}
void UnitAI::SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly, int32 aura)
void UnitAI::SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectTargetMethod targetType, float dist, bool playerOnly, int32 aura)
{
SelectTargetList(targetList, DefaultTargetSelector(me, dist, playerOnly, aura), num, targetType);
}
@@ -152,7 +152,7 @@ void UnitAI::DoCast(uint32 spellId)
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
bool playerOnly = spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER);
//float range = GetSpellMaxRange(spellInfo, false);
target = SelectTarget(SELECT_TARGET_RANDOM, 0, spellInfo->GetMaxRange(false), playerOnly);
target = SelectTarget(SelectTargetMethod::Random, 0, spellInfo->GetMaxRange(false), playerOnly);
break;
}
case AITARGET_ALLY:
@@ -172,7 +172,7 @@ void UnitAI::DoCast(uint32 spellId)
&& targetSelector(me->GetVictim()))
target = me->GetVictim();
else
target = SelectTarget(SELECT_TARGET_RANDOM, 0, targetSelector);
target = SelectTarget(SelectTargetMethod::Random, 0, targetSelector);
break;
}
}
@@ -212,7 +212,7 @@ void UnitAI::DoCastRandomTarget(uint32 spellId, uint32 threatTablePosition, floa
return;
}
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, threatTablePosition, dist, playerOnly))
if (Unit* target = SelectTarget(SelectTargetMethod::Random, threatTablePosition, dist, playerOnly))
{
me->CastSpell(target, spellId, triggered);
}

View File

@@ -28,14 +28,14 @@ class Quest;
class Unit;
struct AISpellInfoType;
//Selection method used by SelectTarget
enum SelectAggroTarget
// Selection method used by SelectTarget
enum class SelectTargetMethod
{
SELECT_TARGET_RANDOM = 0, //Just selects a random target
SELECT_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
SELECT_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
SELECT_TARGET_NEAREST,
SELECT_TARGET_FARTHEST,
Random, // just pick a random target
MaxThreat, // prefer targets higher in the threat list
MinThreat, // prefer targets lower in the threat list
MaxDistance, // prefer targets further from us
MinDistance // prefer targets closer to us
};
// default predicate function to select target based on distance, player and/or aura criteria
@@ -199,10 +199,22 @@ public:
virtual void SetGUID(ObjectGuid /*guid*/, int32 /*id*/ = 0) {}
virtual ObjectGuid GetGUID(int32 /*id*/ = 0) const { return ObjectGuid::Empty; }
Unit* SelectTarget(SelectAggroTarget targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, int32 aura = 0);
// Select the targets satifying the predicate.
// predicate shall extend Acore::unary_function<Unit*, bool>
template <class PREDICATE> Unit* SelectTarget(SelectAggroTarget targetType, uint32 position, PREDICATE const& predicate)
// Select the best target (in <targetType> order) from the threat list that fulfill the following:
// - Not among the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat order,
// if <targetType> is SelectTargetMethod::Random).
// - Within at most <dist> yards (if dist > 0.0f)
// - At least -<dist> yards away (if dist < 0.0f)
// - Is a player (if playerOnly = true)
// - Not the current tank (if withTank = false)
// - Has aura with ID <aura> (if aura > 0)
// - Does not have aura with ID -<aura> (if aura < 0)
Unit* SelectTarget(SelectTargetMethod targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, int32 aura = 0);
// Select the best target (in <targetType> order) satisfying <predicate> from the threat list.
// If <offset> is nonzero, the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat
// order, if <targetType> is SelectTargetMethod::Random) are skipped.
template <class PREDICATE>
Unit* SelectTarget(SelectTargetMethod targetType, uint32 position, PREDICATE const& predicate)
{
ThreatContainer::StorageType const& threatlist = me->getThreatMgr().getThreatList();
if (position >= threatlist.size())
@@ -216,26 +228,26 @@ public:
if (position >= targetList.size())
return nullptr;
if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
if (targetType == SelectTargetMethod::MaxDistance || targetType == SelectTargetMethod::MinDistance)
targetList.sort(Acore::ObjectDistanceOrderPred(me));
switch (targetType)
{
case SELECT_TARGET_NEAREST:
case SELECT_TARGET_TOPAGGRO:
case SelectTargetMethod::MaxDistance:
case SelectTargetMethod::MaxThreat:
{
std::list<Unit*>::iterator itr = targetList.begin();
std::advance(itr, position);
return *itr;
}
case SELECT_TARGET_FARTHEST:
case SELECT_TARGET_BOTTOMAGGRO:
case SelectTargetMethod::MinDistance:
case SelectTargetMethod::MinThreat:
{
std::list<Unit*>::reverse_iterator ritr = targetList.rbegin();
std::advance(ritr, position);
return *ritr;
}
case SELECT_TARGET_RANDOM:
case SelectTargetMethod::Random:
{
std::list<Unit*>::iterator itr = targetList.begin();
std::advance(itr, urand(position, targetList.size() - 1));
@@ -248,11 +260,23 @@ public:
return nullptr;
}
void SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectAggroTarget targetType, float dist = 0.0f, bool playerOnly = false, int32 aura = 0);
// Select the best (up to) <num> targets (in <targetType> order) from the threat list that fulfill the following:
// - Not among the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat order,
// if <targetType> is SelectTargetMethod::Random).
// - Within at most <dist> yards (if dist > 0.0f)
// - At least -<dist> yards away (if dist < 0.0f)
// - Is a player (if playerOnly = true)
// - Not the current tank (if withTank = false)
// - Has aura with ID <aura> (if aura > 0)
// - Does not have aura with ID -<aura> (if aura < 0)
// The resulting targets are stored in <targetList> (which is cleared first).
void SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectTargetMethod targetType, float dist = 0.0f, bool playerOnly = false, int32 aura = 0);
// Select the targets satifying the predicate.
// predicate shall extend Acore::unary_function<Unit*, bool>
template <class PREDICATE> void SelectTargetList(std::list<Unit*>& targetList, PREDICATE const& predicate, uint32 maxTargets, SelectAggroTarget targetType)
// Select the best (up to) <num> targets (in <targetType> order) satisfying <predicate> from the threat list and stores them in <targetList> (which is cleared first).
// If <offset> is nonzero, the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat
// order, if <targetType> is SelectTargetMethod::Random) are skipped.
template <class PREDICATE>
void SelectTargetList(std::list<Unit*>& targetList, PREDICATE const& predicate, uint32 maxTargets, SelectTargetMethod targetType)
{
ThreatContainer::StorageType const& threatlist = me->getThreatMgr().getThreatList();
if (threatlist.empty())
@@ -265,13 +289,13 @@ public:
if (targetList.size() < maxTargets)
return;
if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
if (targetType == SelectTargetMethod::MaxDistance || targetType == SelectTargetMethod::MinDistance)
targetList.sort(Acore::ObjectDistanceOrderPred(me));
if (targetType == SELECT_TARGET_FARTHEST || targetType == SELECT_TARGET_BOTTOMAGGRO)
if (targetType == SelectTargetMethod::MinDistance || targetType == SelectTargetMethod::MinThreat)
targetList.reverse();
if (targetType == SELECT_TARGET_RANDOM)
if (targetType == SelectTargetMethod::Random)
Acore::Containers::RandomResize(targetList, maxTargets);
else
targetList.resize(maxTargets);

View File

@@ -702,7 +702,7 @@ void WorldBossAI::_JustDied()
void WorldBossAI::_EnterCombat()
{
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
if (target)
AttackStart(target);
}
@@ -710,7 +710,7 @@ void WorldBossAI::_EnterCombat()
void WorldBossAI::JustSummoned(Creature* summon)
{
summons.Summon(summon);
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
if (target)
summon->AI()->AttackStart(target);
}

View File

@@ -3442,10 +3442,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MaxThreat, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
l->push_back(u);
}
else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
else if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MaxThreat, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
l->push_back(u);
}
break;
@@ -3454,10 +3454,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MinThreat, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
l->push_back(u);
}
else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
else if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MinThreat, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
l->push_back(u);
}
break;
@@ -3466,10 +3466,10 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
l->push_back(u);
}
else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
else if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::Random, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
l->push_back(u);
}
break;
@@ -3478,17 +3478,17 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::Random, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)))
l->push_back(u);
}
else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
else if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::Random, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))
l->push_back(u);
}
break;
case SMART_TARGET_FARTHEST:
if (me)
{
if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_FARTHEST, 0, FarthestTargetSelector(me, e.target.farthest.maxDist, e.target.farthest.playerOnly, e.target.farthest.isInLos)))
if (Unit* u = me->AI()->SelectTarget(SelectTargetMethod::MinDistance, 0, FarthestTargetSelector(me, e.target.farthest.maxDist, e.target.farthest.playerOnly, e.target.farthest.isInLos)))
l->push_back(u);
}
break;