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; }
}
}
}
};