source-engine/game/server/ai_behavior_lead.h

237 lines
6.0 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= 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