All pastes #1245422 Raw Edit

Mine

public text v1 · immutable
#1245422 ·published 2008-11-04 23:51 UTC
rendered paste body
#define QUEST_ID                  xxxxxx         // related quest, 0 if no quest
#define ESCORT_TIMER              xxxxxx         // set quest time limit in seconds   0 if NO TIME LIMIT
#define MAX_FOLLOW_DISTANCE       xxx            // max distance before escort fails

/************************* Generic Follower AI *************************/

struct MANGOS_DLL_DECL generic_followerAI : public ScriptedAI
{
    npc_fluff_escortAI(Creature *c) : ScriptedAI(c) {Reset();}

    uint64 pGUID;
    uint32 EscortTimer;
    bool TimeLimit;
    float FollowDistance;

    void Reset()
    {
        pGUID = 0;
        EscortTimer = ESCORT_TIMER;
        if(!EscortTimer)
            TimeLimit = false;
        else TimeLimit = true;
        
        FollowDistance = 30.0f;
        if (MAX_FOLLOW_DISTANCE)
            FollowDistance = MAX_FOLLOW_DISTANCE;
    }

    void Aggro(Unit *who) { }
    void MoveInLineOfSight(Unit* who)
    {
        if (!who)
            return;

/* Add LOS check for attack start here if you want it to attack enemies */


/* THIS PART ALLOWS THE NPC TO PICK AN OWNER, BASED ON HAVING 'QUEST_ID' INCOMPLETE */
        if (!QUEST_ID)
            return;

        if (!pGUID)
        {
            if (m_creature->IsWithinDistInMap(who, 10.0f) && (who->GetTypeId() == TYPEID_PLAYER) && ((Player*)who)->GetQuestStatus(QUEST_ID) == QUEST_STATUS_INCOMPLETE)
            {
                pGUID = who->GetGUID();
                EscortPhase = 0;
                if(pGUID)
                {
                    Player* pEscort = NULL;
                    pEscort = (Player*)Unit::GetUnit((*m_creature), pGUID);
                    if (pEscort)
                    {
                        m_creature->GetMotionMaster()->MoveFollow(pEscort, 2.0, 0.0);
                    }
                }
            }
        }
    }
    
    
/* CALL THROUGH GOSSIP OPTION OR THROUGH QUEST ACCEPT SCRIPT */
    void InitiateFollow(uint64 owner) 
    { 
        pGUID = owner; 
        Player* pEscort = NULL;
        pEscort = (Player*)Unit::GetUnit((*m_creature), pGUID);
        if (pEscort)
        {
            m_creature->GetMotionMaster()->MoveFollow(pEscort, 2.0, 0.0);
        }
    }


    void ActionSequence(uint32 action) { }

    void UpdateAI(const uint32 diff)
    {
        if (pGUID)
        {
            Player* pEscort = NULL;
            pEscort = (Player*)Unit::GetUnit((*m_creature), pGUID);
            if (!pEscort)
                return;

            if (pEscort->isDead())
            {
                if (QUEST_ID)
                    pEscort->FailQuest(QUEST_ID);
                m_creature->GetMotionMaster()->Clear(false);
                m_creature->SetVisibility(VISIBILITY_OFF);
                m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                pGUID = 0;
                return;
            }
            
            if (m_creature->isDead())
            {
                if (QUEST_ID)
                    pEscort->FailQuest(QUEST_ID);
                m_creature->SetVisibility(VISIBILITY_OFF);
                pGUID = 0;
                return;
            }
            
            if (!m_creature->IsWithinDistInMap(pEscort, FollowDistance))
            {
                if (QUEST_ID)
                    pEscort->FailQuest(QUEST_ID);
                m_creature->GetMotionMaster()->Clear(false);
                m_creature->SetVisibility(VISIBILITY_OFF);
                m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                pGUID = 0;
                return;
            }

            if (TimeLimit)
            {
                if (EscortTimer < diff)
                {
                    if (QUEST_ID)
                        pEscort->FailQuest(QUEST_ID);
                    m_creature->GetMotionMaster()->Clear(false);
                    m_creature->SetVisibility(VISIBILITY_OFF);
                    m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                    pGUID = 0;
                    return;
                } else { EscortTimer -= diff; }
            }
        }
    }
};