1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
//========= 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
|