mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 10:26:28 +01:00
[svn] Add new function SelectUnit and SelectUnitList to select target or targets with check "isPlayer" and "isWithinDist". Also add target type SELECT_TARGET_NEAREST and SELECT_TARGET_FARTHEST.
SpellEffect Fix for 40802,29364,43723,41931. Patch provided by WarHead. Update script of Fathom Lord. Patch provided by Blaymoira. --HG-- branch : trunk
This commit is contained in:
@@ -261,6 +261,145 @@ Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
|
||||
{
|
||||
const Unit* me;
|
||||
TargetDistanceOrder(const Unit* Target) : me(Target) {};
|
||||
// functor for operator ">"
|
||||
bool operator()(const Unit* _Left, const Unit* _Right) const
|
||||
{
|
||||
return (me->GetDistance(_Left) < me->GetDistance(_Right));
|
||||
}
|
||||
};
|
||||
|
||||
Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly)
|
||||
{
|
||||
if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
|
||||
{
|
||||
std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList();
|
||||
if(m_threatlist.empty()) return NULL;
|
||||
std::list<Unit*> targetList;
|
||||
std::list<HostilReference*>::iterator itr = m_threatlist.begin();
|
||||
for(; itr!= m_threatlist.end(); ++itr)
|
||||
{
|
||||
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
|
||||
if(!target
|
||||
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
|
||||
|| dist && !m_creature->IsWithinDistInMap(target, dist))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
targetList.push_back(target);
|
||||
}
|
||||
if(position >= targetList.size())
|
||||
return NULL;
|
||||
targetList.sort(TargetDistanceOrder(m_creature));
|
||||
if(targetType == SELECT_TARGET_NEAREST)
|
||||
{
|
||||
std::list<Unit*>::iterator i = targetList.begin();
|
||||
advance(i, position);
|
||||
return *i;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::list<Unit*>::reverse_iterator i = targetList.rbegin();
|
||||
advance(i, position);
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList();
|
||||
std::list<HostilReference*>::iterator i;
|
||||
Unit *target;
|
||||
while(position < m_threatlist.size())
|
||||
{
|
||||
if(targetType == SELECT_TARGET_BOTTOMAGGRO)
|
||||
{
|
||||
i = m_threatlist.end();
|
||||
advance(i, - (int32)position - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = m_threatlist.begin();
|
||||
if(targetType == SELECT_TARGET_TOPAGGRO)
|
||||
advance(i, position);
|
||||
else // random
|
||||
advance(i, position + rand()%(m_threatlist.size() - position));
|
||||
}
|
||||
|
||||
target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||
if(!target
|
||||
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
|
||||
|| dist && !m_creature->IsWithinDistInMap(target, dist))
|
||||
{
|
||||
m_threatlist.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly)
|
||||
{
|
||||
if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
|
||||
{
|
||||
std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList();
|
||||
if(m_threatlist.empty()) return;
|
||||
std::list<HostilReference*>::iterator itr = m_threatlist.begin();
|
||||
for(; itr!= m_threatlist.end(); ++itr)
|
||||
{
|
||||
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
|
||||
if(!target
|
||||
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
|
||||
|| dist && !m_creature->IsWithinDistInMap(target, dist))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
targetList.push_back(target);
|
||||
}
|
||||
targetList.sort(TargetDistanceOrder(m_creature));
|
||||
targetList.resize(num);
|
||||
if(targetType == SELECT_TARGET_FARTHEST)
|
||||
targetList.reverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList();
|
||||
std::list<HostilReference*>::iterator i;
|
||||
Unit *target;
|
||||
while(m_threatlist.size())
|
||||
{
|
||||
if(targetType == SELECT_TARGET_BOTTOMAGGRO)
|
||||
{
|
||||
i = m_threatlist.end();
|
||||
--i;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = m_threatlist.begin();
|
||||
if(targetType == SELECT_TARGET_RANDOM)
|
||||
advance(i, rand()%m_threatlist.size());
|
||||
}
|
||||
|
||||
target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
|
||||
m_threatlist.erase(i);
|
||||
if(!target
|
||||
|| playerOnly && target->GetTypeId() != TYPEID_PLAYER
|
||||
|| dist && !m_creature->IsWithinDistInMap(target, dist))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
targetList.push_back(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects)
|
||||
{
|
||||
//No target so we can't cast
|
||||
|
||||
@@ -146,6 +146,8 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
|
||||
|
||||
//Selects a unit from the creature's current aggro list
|
||||
Unit* SelectUnit(SelectAggroTarget target, uint32 position);
|
||||
Unit* SelectUnit(SelectAggroTarget target, uint32 position, float dist, bool playerOnly);
|
||||
void SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget target, float dist, bool playerOnly);
|
||||
|
||||
//Returns spells that meet the specified criteria from the creatures spell list
|
||||
SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect);
|
||||
|
||||
Reference in New Issue
Block a user