Show
Ignore:
Timestamp:
11/19/08 13:38:54 (17 years ago)
Author:
yumileroy
Message:

[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.

Original author: megamage
Date: 2008-10-28 16:28:42-05:00

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/bindings/scripts/include/sc_creature.cpp

    r118 r130  
    260260 
    261261    return NULL; 
     262} 
     263 
     264struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> 
     265{ 
     266    const Unit* me; 
     267    TargetDistanceOrder(const Unit* Target) : me(Target) {}; 
     268    // functor for operator ">" 
     269    bool operator()(const Unit* _Left, const Unit* _Right) const 
     270    { 
     271        return (me->GetDistance(_Left) < me->GetDistance(_Right)); 
     272    } 
     273}; 
     274 
     275Unit* ScriptedAI::SelectUnit(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly) 
     276{ 
     277    if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) 
     278    { 
     279        std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList(); 
     280        if(m_threatlist.empty()) return NULL; 
     281        std::list<Unit*> targetList; 
     282        std::list<HostilReference*>::iterator itr = m_threatlist.begin(); 
     283        for(; itr!= m_threatlist.end(); ++itr) 
     284        { 
     285            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
     286            if(!target 
     287                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     288                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     289            { 
     290                continue; 
     291            } 
     292            targetList.push_back(target); 
     293        } 
     294        if(position >= targetList.size()) 
     295            return NULL; 
     296        targetList.sort(TargetDistanceOrder(m_creature)); 
     297        if(targetType == SELECT_TARGET_NEAREST) 
     298        { 
     299            std::list<Unit*>::iterator i = targetList.begin(); 
     300            advance(i, position); 
     301            return *i; 
     302        } 
     303        else 
     304        { 
     305            std::list<Unit*>::reverse_iterator i = targetList.rbegin(); 
     306            advance(i, position); 
     307            return *i; 
     308        } 
     309    } 
     310    else 
     311    { 
     312        std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList(); 
     313        std::list<HostilReference*>::iterator i; 
     314        Unit *target; 
     315        while(position < m_threatlist.size()) 
     316        { 
     317            if(targetType == SELECT_TARGET_BOTTOMAGGRO) 
     318            { 
     319                i = m_threatlist.end(); 
     320                advance(i, - (int32)position - 1); 
     321            } 
     322            else 
     323            { 
     324                i = m_threatlist.begin(); 
     325                if(targetType == SELECT_TARGET_TOPAGGRO) 
     326                    advance(i, position); 
     327                else // random 
     328                    advance(i, position + rand()%(m_threatlist.size() - position)); 
     329            } 
     330 
     331            target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); 
     332            if(!target 
     333                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     334                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     335            { 
     336                m_threatlist.erase(i); 
     337            } 
     338            else 
     339            { 
     340                return target; 
     341            } 
     342        } 
     343    } 
     344 
     345    return NULL; 
     346} 
     347 
     348void ScriptedAI::SelectUnitList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly) 
     349{ 
     350    if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) 
     351    { 
     352        std::list<HostilReference*> &m_threatlist = m_creature->getThreatManager().getThreatList(); 
     353        if(m_threatlist.empty()) return; 
     354        std::list<HostilReference*>::iterator itr = m_threatlist.begin(); 
     355        for(; itr!= m_threatlist.end(); ++itr) 
     356        { 
     357            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
     358            if(!target 
     359                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     360                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     361            { 
     362                continue; 
     363            } 
     364            targetList.push_back(target); 
     365        } 
     366        targetList.sort(TargetDistanceOrder(m_creature)); 
     367        targetList.resize(num); 
     368        if(targetType == SELECT_TARGET_FARTHEST) 
     369            targetList.reverse(); 
     370    } 
     371    else 
     372    { 
     373        std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList(); 
     374        std::list<HostilReference*>::iterator i; 
     375        Unit *target; 
     376        while(m_threatlist.size()) 
     377        { 
     378            if(targetType == SELECT_TARGET_BOTTOMAGGRO) 
     379            { 
     380                i = m_threatlist.end(); 
     381                --i; 
     382            } 
     383            else 
     384            { 
     385                i = m_threatlist.begin(); 
     386                if(targetType == SELECT_TARGET_RANDOM) 
     387                    advance(i, rand()%m_threatlist.size()); 
     388            } 
     389 
     390            target = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); 
     391            m_threatlist.erase(i); 
     392            if(!target 
     393                || playerOnly && target->GetTypeId() != TYPEID_PLAYER 
     394                || dist && !m_creature->IsWithinDistInMap(target, dist)) 
     395            { 
     396                continue;                 
     397            } 
     398            targetList.push_back(target); 
     399        } 
     400    } 
    262401} 
    263402