//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef AI_BEHAVIOR_LEAD_H #define AI_BEHAVIOR_LEAD_H #include "simtimer.h" #include "ai_behavior.h" #if defined( _WIN32 ) #pragma once #endif typedef const char *AIConcept_t; // Speak concepts #define TLK_LEAD_START "TLK_LEAD_START" #define TLK_LEAD_ARRIVAL "TLK_LEAD_ARRIVAL" #define TLK_LEAD_SUCCESS "TLK_LEAD_SUCCESS" #define TLK_LEAD_FAILURE "lead_fail" #define TLK_LEAD_COMINGBACK "TLK_LEAD_COMINGBACK" #define TLK_LEAD_CATCHUP "TLK_LEAD_CATCHUP" #define TLK_LEAD_RETRIEVE "TLK_LEAD_RETRIEVE" #define TLK_LEAD_ATTRACTPLAYER "TLK_LEAD_ATTRACTPLAYER" #define TLK_LEAD_WAITOVER "TLK_LEAD_WAITOVER" #define TLK_LEAD_MISSINGWEAPON "TLK_LEAD_MISSING_WEAPON" #define TLK_LEAD_IDLE "TLK_LEAD_IDLE" //----------------------------------------------------------------------------- // class CAI_LeadBehavior // // Purpose: // //----------------------------------------------------------------------------- enum LeadBehaviorEvents_t { LBE_ARRIVAL, LBE_ARRIVAL_DONE, LBE_SUCCESS, LBE_FAILURE, LBE_DONE, }; //------------------------------------- // // Handler class interface to listen to and modify actions of the lead behavior. // Could be an NPC, or another entity (like a goal entity) // class CAI_LeadBehaviorHandler { public: virtual void OnEvent( int event ) {} virtual const char *GetConceptModifiers( const char *pszConcept ) { return NULL; } }; //------------------------------------- enum AI_LeadFlags_t { AILF_NO_DEF_SUCCESS = 0x01, AILF_NO_DEF_FAILURE = 0x02, AILF_USE_GOAL_FACING = 0x04, }; struct AI_LeadArgs_t { const char *pszGoal; const char *pszWaitPoint; unsigned flags; float flWaitDistance; float flLeadDistance; float flRetrieveDistance; float flSuccessDistance; bool bRun; int iRetrievePlayer; int iRetrieveWaitForSpeak; int iComingBackWaitForSpeak; bool bStopScenesWhenPlayerLost; bool bDontSpeakStart; bool bLeadDuringCombat; bool bGagLeader; DECLARE_SIMPLE_DATADESC(); }; class CAI_LeadBehavior : public CAI_SimpleBehavior { DECLARE_CLASS( CAI_LeadBehavior, CAI_SimpleBehavior ); public: CAI_LeadBehavior() : m_pSink(NULL), m_LostTimer( 3.0, 4.0 ), m_LostLOSTimer( 2.0, 3.0 ) { memset( &m_args, 0, sizeof(m_args) ); ClearGoal(); } virtual void OnRestore(); virtual const char *GetName() { return "Lead"; } virtual int DrawDebugTextOverlays( int text_offset ); virtual bool IsNavigationUrgent(); void LeadPlayer( const AI_LeadArgs_t &leadArgs, CAI_LeadBehaviorHandler *pSink = NULL ); void StopLeading( void ); virtual bool CanSelectSchedule(); void BeginScheduleSelection(); virtual bool IsCurTaskContinuousMove(); bool SetGoal( const AI_LeadArgs_t &args ); void ClearGoal() { m_goal = vec3_origin; m_waitpoint = vec3_origin; m_pSink = NULL; m_weaponname = NULL_STRING; } bool HasGoal() const { return (m_goal != vec3_origin); } bool HasWaitPoint() const { return (m_waitpoint != vec3_origin); } bool Connect( CAI_LeadBehaviorHandler *); bool Disconnect( CAI_LeadBehaviorHandler *); void SetWaitForWeapon( string_t iszWeaponName ) { m_weaponname = iszWeaponName; m_flWeaponSafetyTimeOut = gpGlobals->curtime + 60; } enum { // Schedules SCHED_LEAD_PLAYER = BaseClass::NEXT_SCHEDULE, SCHED_LEAD_PAUSE, SCHED_LEAD_PAUSE_COMBAT, SCHED_LEAD_RETRIEVE, SCHED_LEAD_RETRIEVE_WAIT, SCHED_LEAD_SUCCEED, SCHED_LEAD_AWAIT_SUCCESS, SCHED_LEAD_WAITFORPLAYER, SCHED_LEAD_WAITFORPLAYERIDLE, SCHED_LEAD_PLAYERNEEDSWEAPON, SCHED_LEAD_SPEAK_START, SCHED_LEAD_SPEAK_THEN_RETRIEVE_PLAYER, SCHED_LEAD_SPEAK_THEN_LEAD_PLAYER, NEXT_SCHEDULE, // Tasks TASK_GET_PATH_TO_LEAD_GOAL = BaseClass::NEXT_TASK, TASK_STOP_LEADING, TASK_LEAD_FACE_GOAL, TASK_LEAD_ARRIVE, TASK_LEAD_SUCCEED, TASK_LEAD_GET_PATH_TO_WAITPOINT, TASK_LEAD_WAVE_TO_PLAYER, TASK_LEAD_PLAYER_NEEDS_WEAPON, TASK_LEAD_SPEAK_START, TASK_LEAD_MOVE_TO_RANGE, TASK_LEAD_RETRIEVE_WAIT, TASK_LEAD_WALK_PATH, NEXT_TASK, // Conditions COND_LEAD_FOLLOWER_LOST = BaseClass::NEXT_CONDITION, COND_LEAD_FOLLOWER_LAGGING, COND_LEAD_FOLLOWER_NOT_LAGGING, COND_LEAD_FOLLOWER_VERY_CLOSE, COND_LEAD_SUCCESS, COND_LEAD_HAVE_FOLLOWER_LOS, COND_LEAD_FOLLOWER_MOVED_FROM_MARK, COND_LEAD_FOLLOWER_MOVING_TOWARDS_ME, NEXT_CONDITION }; private: void GatherConditions(); virtual int SelectSchedule(); virtual int TranslateSchedule( int scheduleType ); virtual void StartTask( const Task_t *pTask ); virtual void RunTask( const Task_t *pTask ); bool GetClosestPointOnRoute( const Vector &targetPos, Vector *pVecClosestPoint ); bool PlayerIsAheadOfMe( bool bForce = false ); bool Speak( AIConcept_t concept ); bool IsSpeaking(); // -------------------------------- // // Sink notifiers. Isolated to limit exposure to actual sink storage, // provide debugging pinch pount, and allow for class-local logic // in addition to sink logic // void NotifyEvent( int event ) { if ( m_pSink ) m_pSink->OnEvent( event ) ; } const char * GetConceptModifiers( const char *pszConcept ) { return ( m_pSink ) ? m_pSink->GetConceptModifiers( pszConcept ) : NULL; } // -------------------------------- AI_LeadArgs_t m_args; CAI_LeadBehaviorHandler *m_pSink; EHANDLE m_hSinkImplementor; // -------------------------------- Vector m_goal; float m_goalyaw; Vector m_waitpoint; float m_waitdistance; float m_leaddistance; float m_retrievedistance; float m_successdistance; string_t m_weaponname; bool m_run; bool m_gagleader; bool m_hasspokenstart; bool m_hasspokenarrival; bool m_hasPausedScenes; float m_flSpeakNextNagTime; float m_flWeaponSafetyTimeOut; float m_flNextLeadIdle; bool m_bInitialAheadTest; CAI_MoveMonitor m_MoveMonitor; CRandStopwatch m_LostTimer; CRandStopwatch m_LostLOSTimer; DEFINE_CUSTOM_SCHEDULE_PROVIDER; DECLARE_DATADESC(); }; //----------------------------------------------------------------------------- #endif // AI_BEHAVIOR_LEAD_H