2009-02-17 18:08:26 +01:00
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
2008-10-21 13:19:26 -05:00
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
/* ScriptData
SDName: Npc_EscortAI
SD%Complete: 100
SDComment:
SDCategory: Npc
EndScriptData */
2009-10-17 15:51:44 -07:00
2010-01-19 11:36:05 +01:00
#include "ScriptedPch.h"
#include "ScriptedEscortAI.h"
2009-10-17 15:51:44 -07:00
2009-10-17 07:42:48 -07:00
enum ePoints
2009-08-13 05:47:23 +02:00
{
POINT_LAST_POINT = 0xFFFFFF ,
POINT_HOME = 0xFFFFFE
};
2009-10-17 15:51:44 -07:00
2009-08-16 21:46:31 +02:00
npc_escortAI :: npc_escortAI ( Creature * pCreature ) : ScriptedAI ( pCreature ),
2009-08-17 00:29:53 +02:00
m_uiPlayerGUID ( 0 ),
2009-08-16 21:46:31 +02:00
MaxPlayerDistance ( DEFAULT_MAX_PLAYER_DISTANCE ),
m_uiPlayerCheckTimer ( 1000 ),
m_uiWPWaitTimer ( 2500 ),
2009-10-11 18:03:59 +02:00
m_uiEscortState ( STATE_ESCORT_NONE ),
2009-08-16 21:46:31 +02:00
m_bIsActiveAttacker ( true ),
m_bIsRunning ( false ),
DespawnAtEnd ( true ),
DespawnAtFar ( true ),
m_pQuestForEscort ( NULL ),
m_bCanInstantRespawn ( false ),
m_bCanReturnToStart ( false ),
ScriptWP ( false )
{}
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
void npc_escortAI :: AttackStart ( Unit * pWho )
2008-10-21 13:19:26 -05:00
{
2009-08-14 05:32:39 +02:00
if ( ! pWho )
2008-10-21 13:19:26 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
if ( m_creature -> Attack ( pWho , true ))
2009-04-27 21:23:42 -05:00
{
2009-08-11 00:43:06 +02:00
if ( m_creature -> GetMotionMaster () -> GetCurrentMovementGeneratorType () == POINT_MOTION_TYPE )
2009-05-19 23:48:48 +02:00
m_creature -> GetMotionMaster () -> MovementExpired ();
2009-10-17 15:51:44 -07:00
2009-08-13 02:48:34 +02:00
if ( IsCombatMovement ())
2009-08-14 05:32:39 +02:00
m_creature -> GetMotionMaster () -> MoveChase ( pWho );
2009-04-27 21:23:42 -05:00
}
}
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
//see followerAI
bool npc_escortAI :: AssistPlayerInCombat ( Unit * pWho )
{
if ( ! pWho || ! pWho -> getVictim ())
return false ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
//experimental (unknown) flag not present
if ( ! ( m_creature -> GetCreatureInfo () -> type_flags & CREATURE_TYPEFLAGS_UNK13 ))
return false ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
//not a player
if ( ! pWho -> getVictim () -> GetCharmerOrOwnerPlayerOrPlayerItself ())
return false ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
//never attack friendly
if ( m_creature -> IsFriendlyTo ( pWho ))
return false ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
//too far away and no free sight?
if ( m_creature -> IsWithinDistInMap ( pWho , GetMaxPlayerDistance ()) && m_creature -> IsWithinLOSInMap ( pWho ))
{
//already fighting someone?
if ( ! m_creature -> getVictim ())
{
AttackStart ( pWho );
return true ;
}
else
{
pWho -> SetInCombatWith ( m_creature );
m_creature -> AddThreat ( pWho , 0.0f );
return true ;
}
}
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
return false ;
}
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
void npc_escortAI :: MoveInLineOfSight ( Unit * pWho )
2008-10-21 13:19:26 -05:00
{
2009-10-11 18:03:59 +02:00
if ( ! m_creature -> hasUnitState ( UNIT_STAT_STUNNED ) && pWho -> isTargetableForAttack () && pWho -> isInAccessiblePlaceFor ( m_creature ))
{
if ( HasEscortState ( STATE_ESCORT_ESCORTING ) && AssistPlayerInCombat ( pWho ))
return ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
if ( ! m_creature -> canFly () && m_creature -> GetDistanceZ ( pWho ) > CREATURE_Z_ATTACK_RANGE )
return ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
if ( m_creature -> IsHostileTo ( pWho ))
{
float fAttackRadius = m_creature -> GetAttackDistance ( pWho );
if ( m_creature -> IsWithinDistInMap ( pWho , fAttackRadius ) && m_creature -> IsWithinLOSInMap ( pWho ))
{
if ( ! m_creature -> getVictim ())
{
pWho -> RemoveAurasDueToSpell ( SPELL_AURA_MOD_STEALTH );
AttackStart ( pWho );
}
else if ( m_creature -> GetMap () -> IsDungeon ())
{
pWho -> SetInCombatWith ( m_creature );
m_creature -> AddThreat ( pWho , 0.0f );
}
}
}
}
2009-08-14 05:32:39 +02:00
}
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
void npc_escortAI :: JustDied ( Unit * pKiller )
{
2009-10-11 18:03:59 +02:00
if ( ! HasEscortState ( STATE_ESCORT_ESCORTING ) || ! m_uiPlayerGUID || ! m_pQuestForEscort )
2009-08-14 05:32:39 +02:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-17 00:29:53 +02:00
if ( Player * pPlayer = GetPlayerForEscort ())
2009-08-14 05:32:39 +02:00
{
if ( Group * pGroup = pPlayer -> GetGroup ())
{
2009-10-17 16:20:24 -07:00
for ( GroupReference * pRef = pGroup -> GetFirstMember (); pRef != NULL ; pRef = pRef -> next ())
2009-08-14 05:32:39 +02:00
{
if ( Player * pMember = pRef -> getSource ())
{
2009-10-11 18:03:59 +02:00
if ( pMember -> GetQuestStatus ( m_pQuestForEscort -> GetQuestId ()) == QUEST_STATUS_INCOMPLETE )
pMember -> FailQuest ( m_pQuestForEscort -> GetQuestId ());
2009-08-14 05:32:39 +02:00
}
}
}
else
{
if ( pPlayer -> GetQuestStatus ( m_pQuestForEscort -> GetQuestId ()) == QUEST_STATUS_INCOMPLETE )
pPlayer -> FailQuest ( m_pQuestForEscort -> GetQuestId ());
}
}
2008-10-21 13:19:26 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
void npc_escortAI :: JustRespawned ()
{
2009-10-11 18:03:59 +02:00
m_uiEscortState = STATE_ESCORT_NONE ;
2009-10-17 15:51:44 -07:00
2009-08-13 02:48:34 +02:00
if ( ! IsCombatMovement ())
SetCombatMovement ( true );
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
//add a small delay before going to first waypoint, normal in near all cases
m_uiWPWaitTimer = 2500 ;
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
if ( m_creature -> getFaction () != m_creature -> GetCreatureInfo () -> faction_A )
me -> RestoreFaction ();
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
Reset ();
}
2009-10-17 15:51:44 -07:00
2009-08-10 15:27:42 +02:00
void npc_escortAI :: ReturnToLastPoint ()
{
float x , y , z , o ;
m_creature -> GetHomePosition ( x , y , z , o );
2009-08-13 05:47:23 +02:00
m_creature -> GetMotionMaster () -> MovePoint ( POINT_LAST_POINT , x , y , z );
2009-08-10 15:27:42 +02:00
}
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
void npc_escortAI :: EnterEvadeMode ()
{
m_creature -> RemoveAllAuras ();
m_creature -> DeleteThreatList ();
2009-05-24 18:16:43 -05:00
m_creature -> CombatStop ( true );
2008-10-21 13:19:26 -05:00
m_creature -> SetLootRecipient ( NULL );
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
if ( HasEscortState ( STATE_ESCORT_ESCORTING ))
2008-10-21 13:19:26 -05:00
{
2009-10-11 18:03:59 +02:00
AddEscortState ( STATE_ESCORT_RETURNING );
2009-08-10 15:27:42 +02:00
ReturnToLastPoint ();
debug_log ( "TSCR: EscortAI has left combat and is now returning to last point" );
2009-04-19 21:16:11 +02:00
}
else
2009-11-28 15:19:31 +01:00
{
2008-10-21 13:19:26 -05:00
m_creature -> GetMotionMaster () -> MoveTargetedHome ();
2009-11-28 15:19:31 +01:00
Reset ();
}
2008-10-21 13:19:26 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-16 22:21:57 +02:00
bool npc_escortAI :: IsPlayerOrGroupInRange ()
{
2009-08-17 00:29:53 +02:00
if ( Player * pPlayer = GetPlayerForEscort ())
2009-08-16 22:21:57 +02:00
{
if ( Group * pGroup = pPlayer -> GetGroup ())
{
2009-10-17 16:20:24 -07:00
for ( GroupReference * pRef = pGroup -> GetFirstMember (); pRef != NULL ; pRef = pRef -> next ())
2009-08-16 22:21:57 +02:00
{
Player * pMember = pRef -> getSource ();
2009-10-17 15:51:44 -07:00
2009-08-16 22:21:57 +02:00
if ( pMember && m_creature -> IsWithinDistInMap ( pMember , GetMaxPlayerDistance ()))
{
return true ;
break ;
}
}
}
else
{
if ( m_creature -> IsWithinDistInMap ( pPlayer , GetMaxPlayerDistance ()))
return true ;
}
}
return false ;
}
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
void npc_escortAI :: UpdateAI ( const uint32 uiDiff )
2008-10-21 13:19:26 -05:00
{
//Waypoint Updating
2009-10-11 18:03:59 +02:00
if ( HasEscortState ( STATE_ESCORT_ESCORTING ) && ! m_creature -> getVictim () && m_uiWPWaitTimer && ! HasEscortState ( STATE_ESCORT_RETURNING ))
2008-10-21 13:19:26 -05:00
{
2009-08-14 05:32:39 +02:00
if ( m_uiWPWaitTimer <= uiDiff )
2008-10-21 13:19:26 -05:00
{
2009-08-13 05:47:23 +02:00
//End of the line
2009-08-11 00:43:06 +02:00
if ( CurrentWP == WaypointList . end ())
2008-10-21 13:19:26 -05:00
{
2009-08-14 00:02:13 +02:00
if ( DespawnAtEnd )
2009-08-11 00:43:06 +02:00
{
debug_log ( "TSCR: EscortAI reached end of waypoints" );
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
if ( m_bCanReturnToStart )
{
float fRetX , fRetY , fRetZ ;
m_creature -> GetRespawnCoord ( fRetX , fRetY , fRetZ );
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
m_creature -> GetMotionMaster () -> MovePoint ( POINT_HOME , fRetX , fRetY , fRetZ );
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
m_uiWPWaitTimer = 0 ;
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
debug_log ( "TSCR: EscortAI are returning home to spawn location: %u, %f, %f, %f" , POINT_HOME , fRetX , fRetY , fRetZ );
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
if ( m_bCanInstantRespawn )
{
m_creature -> setDeathState ( JUST_DIED );
m_creature -> Respawn ();
}
else
m_creature -> ForcedDespawn ();
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
return ;
}
else
{
debug_log ( "TSCR: EscortAI reached end of waypoints with Despawn off" );
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
return ;
}
2009-04-19 21:16:11 +02:00
}
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
if ( ! HasEscortState ( STATE_ESCORT_PAUSED ))
2009-04-19 21:16:11 +02:00
{
2009-08-14 00:02:13 +02:00
m_creature -> GetMotionMaster () -> MovePoint ( CurrentWP -> id , CurrentWP -> x , CurrentWP -> y , CurrentWP -> z );
2009-08-16 21:46:31 +02:00
debug_log ( "TSCR: EscortAI start waypoint %u (%f, %f, %f)." , CurrentWP -> id , CurrentWP -> x , CurrentWP -> y , CurrentWP -> z );
2009-10-17 15:51:44 -07:00
2009-08-16 21:46:31 +02:00
WaypointStart ( CurrentWP -> id );
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
m_uiWPWaitTimer = 0 ;
2009-04-03 17:57:57 +02:00
}
2009-08-14 05:32:39 +02:00
}
else
m_uiWPWaitTimer -= uiDiff ;
2009-02-09 08:16:34 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-10 23:24:40 +02:00
//Check if player or any member of his group is within range
2009-10-11 18:03:59 +02:00
if ( HasEscortState ( STATE_ESCORT_ESCORTING ) && m_uiPlayerGUID && ! m_creature -> getVictim () && ! HasEscortState ( STATE_ESCORT_RETURNING ))
2009-02-09 08:16:34 -05:00
{
2009-10-27 17:07:40 -07:00
if ( m_uiPlayerCheckTimer <= uiDiff )
2008-10-21 13:19:26 -05:00
{
2009-08-16 22:21:57 +02:00
if ( DespawnAtFar && ! IsPlayerOrGroupInRange ())
2009-08-10 23:24:40 +02:00
{
2009-08-14 05:32:39 +02:00
debug_log ( "TSCR: EscortAI failed because player/group was to far away or not found" );
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
if ( m_bCanInstantRespawn )
{
m_creature -> setDeathState ( JUST_DIED );
m_creature -> Respawn ();
}
else
m_creature -> ForcedDespawn ();
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
return ;
2009-08-10 23:24:40 +02:00
}
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
m_uiPlayerCheckTimer = 1000 ;
2009-08-14 05:32:39 +02:00
}
else
m_uiPlayerCheckTimer -= uiDiff ;
2009-02-09 08:16:34 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-16 19:38:18 +02:00
UpdateEscortAI ( uiDiff );
}
2009-10-17 15:51:44 -07:00
2009-08-16 19:38:18 +02:00
void npc_escortAI :: UpdateEscortAI ( const uint32 uiDiff )
{
2009-12-10 21:06:41 +01:00
if ( ! UpdateVictim ())
2009-11-28 15:19:31 +01:00
return ;
DoMeleeAttackIfReady ();
2008-10-21 13:19:26 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-14 05:32:39 +02:00
void npc_escortAI :: MovementInform ( uint32 uiMoveType , uint32 uiPointId )
2008-10-21 13:19:26 -05:00
{
2009-10-11 18:03:59 +02:00
if ( uiMoveType != POINT_MOTION_TYPE || ! HasEscortState ( STATE_ESCORT_ESCORTING ))
2008-10-21 13:19:26 -05:00
return ;
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
//Combat start position reached, continue waypoint movement
2009-08-14 05:32:39 +02:00
if ( uiPointId == POINT_LAST_POINT )
2008-10-21 13:19:26 -05:00
{
2009-04-24 00:51:09 -04:00
debug_log ( "TSCR: EscortAI has returned to original position before combat" );
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
if ( m_bIsRunning && m_creature -> HasUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE ))
m_creature -> RemoveUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE );
else if ( ! m_bIsRunning && ! m_creature -> HasUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE ))
m_creature -> AddUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE );
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
RemoveEscortState ( STATE_ESCORT_RETURNING );
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
if ( ! m_uiWPWaitTimer )
m_uiWPWaitTimer = 1 ;
2009-04-19 21:16:11 +02:00
}
2009-08-14 05:32:39 +02:00
else if ( uiPointId == POINT_HOME )
2009-08-13 05:47:23 +02:00
{
debug_log ( "TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list." );
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
CurrentWP = WaypointList . begin ();
m_uiWPWaitTimer = 1 ;
}
2009-04-19 21:16:11 +02:00
else
2008-10-21 13:19:26 -05:00
{
//Make sure that we are still on the right waypoint
2009-08-14 05:32:39 +02:00
if ( CurrentWP -> id != uiPointId )
2008-10-21 13:19:26 -05:00
{
2010-01-26 10:54:11 +01:00
error_log ( "TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u" , uiPointId , CurrentWP -> id , m_creature -> GetEntry ());
2008-10-21 13:19:26 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
debug_log ( "TSCR: EscortAI Waypoint %u reached" , CurrentWP -> id );
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
//Call WP function
WaypointReached ( CurrentWP -> id );
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
m_uiWPWaitTimer = CurrentWP -> WaitTimeMs + 1 ;
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
++ CurrentWP ;
}
}
2009-10-17 15:51:44 -07:00
2009-05-24 18:16:43 -05:00
/*
2008-11-05 20:51:05 -06:00
void npc_escortAI::OnPossess(bool apply)
{
2009-02-04 10:33:18 -06:00
// We got possessed in the middle of being escorted, store the point
2008-11-05 20:51:05 -06:00
// where we left off to come back to when possess is removed
2009-10-11 18:03:59 +02:00
if (HasEscortState(STATE_ESCORT_ESCORTING))
2008-11-05 20:51:05 -06:00
{
if (apply)
m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);
else
{
Returning = true;
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MovePoint(WP_LAST_POINT, LastPos.x, LastPos.y, LastPos.z);
}
}
}
2009-05-24 18:16:43 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
void npc_escortAI :: AddWaypoint ( uint32 id , float x , float y , float z , uint32 WaitTimeMs )
{
Escort_Waypoint t ( id , x , y , z , WaitTimeMs );
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
WaypointList . push_back ( t );
2009-10-17 15:51:44 -07:00
2009-08-15 22:58:17 -05:00
// i think SD2 no longer uses this function
ScriptWP = true ;
/*PointMovement wp;
wp.m_uiCreatureEntry = me->GetEntry();
wp.m_uiPointId = id;
wp.m_fX = x;
wp.m_fY = y;
wp.m_fZ = z;
wp.m_uiWaitTime = WaitTimeMs;
PointMovementMap[wp.m_uiCreatureEntry].push_back(wp);*/
2008-10-21 13:19:26 -05:00
}
2009-10-17 15:51:44 -07:00
2009-03-22 23:11:55 +01:00
void npc_escortAI :: FillPointMovementListForCreature ()
{
2009-08-16 19:38:18 +02:00
std :: vector < ScriptPointMove > const & pPointsEntries = pSystemMgr . GetPointMoveList ( m_creature -> GetEntry ());
2009-10-17 15:51:44 -07:00
2009-08-16 19:38:18 +02:00
if ( pPointsEntries . empty ())
return ;
2009-10-17 15:51:44 -07:00
2009-08-16 19:38:18 +02:00
std :: vector < ScriptPointMove >:: const_iterator itr ;
2009-10-17 15:51:44 -07:00
2009-08-16 19:38:18 +02:00
for ( itr = pPointsEntries . begin (); itr != pPointsEntries . end (); ++ itr )
{
Escort_Waypoint pPoint ( itr -> uiPointId , itr -> fX , itr -> fY , itr -> fZ , itr -> uiWaitTime );
WaypointList . push_back ( pPoint );
2009-03-22 23:11:55 +01:00
}
}
2009-10-17 15:51:44 -07:00
2009-04-19 21:16:11 +02:00
void npc_escortAI :: SetRun ( bool bRun )
{
if ( bRun )
{
2009-08-11 00:43:06 +02:00
if ( ! m_bIsRunning )
2009-04-19 21:16:11 +02:00
m_creature -> RemoveUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE );
else
2009-04-24 00:51:09 -04:00
debug_log ( "TSCR: EscortAI attempt to set run mode, but is already running." );
2009-04-19 21:16:11 +02:00
}
else
{
2009-08-11 00:43:06 +02:00
if ( m_bIsRunning )
2009-04-19 21:16:11 +02:00
m_creature -> AddUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE );
else
2009-04-24 00:51:09 -04:00
debug_log ( "TSCR: EscortAI attempt to set walk mode, but is already walking." );
2009-04-19 21:16:11 +02:00
}
2009-08-11 00:43:06 +02:00
m_bIsRunning = bRun ;
2009-04-19 21:16:11 +02:00
}
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
//TODO: get rid of this many variables passed in function.
void npc_escortAI :: Start ( bool bIsActiveAttacker , bool bRun , uint64 uiPlayerGUID , const Quest * pQuest , bool bInstantRespawn , bool bCanLoopPath )
2008-10-21 13:19:26 -05:00
{
2009-08-11 00:43:06 +02:00
if ( m_creature -> getVictim ())
2008-10-21 13:19:26 -05:00
{
2009-10-11 18:03:59 +02:00
error_log ( "TSCR ERROR: EscortAI attempt to Start while in combat." );
2008-10-21 13:19:26 -05:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
if ( HasEscortState ( STATE_ESCORT_ESCORTING ))
2009-04-19 21:16:11 +02:00
{
2009-10-11 18:03:59 +02:00
error_log ( "TSCR: EscortAI attempt to Start while already escorting." );
2009-04-19 21:16:11 +02:00
return ;
}
2009-10-17 15:51:44 -07:00
2009-08-15 22:58:17 -05:00
if ( ! ScriptWP ) // sd2 never adds wp in script, but tc does
{
2009-10-17 15:51:44 -07:00
2009-08-16 02:12:14 +02:00
if ( ! WaypointList . empty ())
WaypointList . clear ();
2009-10-17 15:51:44 -07:00
2009-08-16 02:12:14 +02:00
FillPointMovementListForCreature ();
2009-10-17 15:51:44 -07:00
2009-08-15 22:58:17 -05:00
}
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
if ( WaypointList . empty ())
{
2009-12-19 14:48:12 +01:00
error_db_log ( "TSCR: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint. Quest: %u)." , pQuest ? pQuest -> GetQuestId () : 0 );
2009-12-19 13:38:30 +01:00
return ;
2008-10-21 13:19:26 -05:00
}
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
//set variables
m_bIsActiveAttacker = bIsActiveAttacker ;
m_bIsRunning = bRun ;
2009-10-17 15:51:44 -07:00
2009-08-17 00:29:53 +02:00
m_uiPlayerGUID = uiPlayerGUID ;
2009-08-13 05:47:23 +02:00
m_pQuestForEscort = pQuest ;
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
m_bCanInstantRespawn = bInstantRespawn ;
m_bCanReturnToStart = bCanLoopPath ;
2009-10-17 15:51:44 -07:00
2009-08-13 05:47:23 +02:00
if ( m_bCanReturnToStart && m_bCanInstantRespawn )
debug_log ( "TSCR: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn." );
2009-10-17 15:51:44 -07:00
2009-08-14 00:02:13 +02:00
if ( m_creature -> GetMotionMaster () -> GetCurrentMovementGeneratorType () == WAYPOINT_MOTION_TYPE )
2009-05-19 23:48:48 +02:00
{
m_creature -> GetMotionMaster () -> MovementExpired ();
m_creature -> GetMotionMaster () -> MoveIdle ();
debug_log ( "TSCR: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle." );
}
2009-10-17 15:51:44 -07:00
2009-08-11 00:43:06 +02:00
//disable npcflags
m_creature -> SetUInt32Value ( UNIT_NPC_FLAGS , UNIT_NPC_FLAG_NONE );
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
debug_log ( "TSCR: EscortAI started with %u waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = %u" , WaypointList . size (), m_bIsActiveAttacker , m_bIsRunning , m_uiPlayerGUID );
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
CurrentWP = WaypointList . begin ();
2009-10-17 15:51:44 -07:00
2008-10-21 13:19:26 -05:00
//Set initial speed
2009-08-11 00:43:06 +02:00
if ( m_bIsRunning )
2008-10-21 13:19:26 -05:00
m_creature -> RemoveUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE );
2009-04-19 21:16:11 +02:00
else
m_creature -> AddUnitMovementFlag ( MOVEMENTFLAG_WALK_MODE );
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
AddEscortState ( STATE_ESCORT_ESCORTING );
}
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
void npc_escortAI :: SetEscortPaused ( bool bPaused )
{
if ( ! HasEscortState ( STATE_ESCORT_ESCORTING ))
return ;
2009-10-17 15:51:44 -07:00
2009-10-11 18:03:59 +02:00
if ( bPaused )
AddEscortState ( STATE_ESCORT_PAUSED );
else
RemoveEscortState ( STATE_ESCORT_PAUSED );
2008-10-21 13:19:26 -05:00
}