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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Hint node utilities and functions.
//
// $NoKeywords: $
//=============================================================================//
#ifndef AI_HINT_H
#define AI_HINT_H
#pragma once
#include "ai_initutils.h"
#include "tier1/utlmap.h"
//Flags for FindHintNode
#define bits_HINT_NODE_NONE 0x00000000
#define bits_HINT_NODE_VISIBLE 0x00000001
#define bits_HINT_NODE_NEAREST 0x00000002 // Choose the node nearest me
#define bits_HINT_NODE_RANDOM 0x00000004 // Find a random hintnode meeting other criteria
#define bits_HINT_NODE_CLEAR 0x00000008 // Only choose nodes that have clear room for my bounding box (requires NPC)
#define bits_HINT_NODE_USE_GROUP 0x00000010 // Use the NPC's hintgroup when searching for a node (requires NPC)
#define bits_HINT_NODE_VISIBLE_TO_PLAYER 0x00000020
#define bits_HINT_NODE_NOT_VISIBLE_TO_PLAYER 0x00000040
#define bits_HINT_NODE_REPORT_FAILURES 0x00000080
#define bits_HINT_NODE_IN_VIEWCONE 0x00000100
#define bits_HINT_NODE_IN_AIMCONE 0x00000200
#define bits_HINT_NPC_IN_NODE_FOV 0x00000400 // Is the searcher inside the hint node's FOV?
#define bits_HINT_NOT_CLOSE_TO_ENEMY 0x00000800 // Hint must not be within 30 feet of my enemy
#define bits_HINT_HAS_LOS_TO_PLAYER 0x00001000 // Like VISIBLE_TO_PLAYER but doesn't care about player's facing
#define bits_HAS_EYEPOSITION_LOS_TO_PLAYER 0x00002000 // Like HAS LOS TO PLAYER, but checks NPC's eye position at the node, not node origin.
//-----------------------------------------------------------------------------
//
// hints - these MUST coincide with the HINTS listed under
// info_node in the FGD file!
//
// For debugging, they must also coincide with g_pszHintDescriptions.
//
//-----------------------------------------------------------------------------
enum Hint_e
{
HINT_ANY = -1,
HINT_NONE = 0,
HINT_NOT_USED_WORLD_DOOR,
HINT_WORLD_WINDOW,
HINT_NOT_USED_WORLD_BUTTON,
HINT_NOT_USED_WORLD_MACHINERY,
HINT_NOT_USED_WORLD_LEDGE,
HINT_NOT_USED_WORLD_LIGHT_SOURCE,
HINT_NOT_USED_WORLD_HEAT_SOURCE,
HINT_NOT_USED_WORLD_BLINKING_LIGHT,
HINT_NOT_USED_WORLD_BRIGHT_COLORS,
HINT_NOT_USED_WORLD_HUMAN_BLOOD,
HINT_NOT_USED_WORLD_ALIEN_BLOOD,
HINT_WORLD_WORK_POSITION,
HINT_WORLD_VISUALLY_INTERESTING,
HINT_WORLD_VISUALLY_INTERESTING_DONT_AIM,
HINT_WORLD_INHIBIT_COMBINE_MINES,
HINT_WORLD_VISUALLY_INTERESTING_STEALTH,
HINT_TACTICAL_COVER_MED = 100,
HINT_TACTICAL_COVER_LOW,
HINT_TACTICAL_SPAWN,
HINT_TACTICAL_PINCH, // Exit / entrance to an arena
HINT_NOT_USED_TACTICAL_GUARD,
HINT_TACTICAL_ENEMY_DISADVANTAGED, //Disadvantageous position for the enemy
HINT_NOT_USED_HEALTH_KIT,
HINT_NOT_USED_URBAN_STREETCORNER = 200,
HINT_NOT_USED_URBAN_STREETLAMP,
HINT_NOT_USED_URBAN_DARK_SPOT,
HINT_NOT_USED_URBAN_POSTER,
HINT_NOT_USED_URBAN_SHELTER,
HINT_NOT_USED_ASSASSIN_SECLUDED = 300,
HINT_NOT_USED_ASSASSIN_RAFTERS,
HINT_NOT_USED_ASSASSIN_GROUND,
HINT_NOT_USED_ASSASSIN_MONKEYBARS,
HINT_ANTLION_BURROW_POINT = 400,
HINT_ANTLION_THUMPER_FLEE_POINT,
HINT_HEADCRAB_BURROW_POINT = 450,
HINT_HEADCRAB_EXIT_POD_POINT,
HINT_NOT_USED_ROLLER_PATROL_POINT = 500,
HINT_NOT_USED_ROLLER_CLEANUP_POINT,
HINT_NOT_USED_PSTORM_ROCK_SPAWN = 600,
HINT_CROW_FLYTO_POINT = 700,
// TF2 Hints
HINT_BUG_PATROL_POINT = 800,
// HL2 Hints
HINT_FOLLOW_WAIT_POINT = 900,
HINT_JUMP_OVERRIDE = 901,
HINT_PLAYER_SQUAD_TRANSITON_POINT = 902,
HINT_NPC_EXIT_POINT = 903,
HINT_STRIDER_NODE = 904,
HINT_PLAYER_ALLY_MOVE_AWAY_DEST = 950,
HINT_PLAYER_ALLY_FEAR_DEST,
// HL1 port hints
HINT_HL1_WORLD_MACHINERY = 1000,
HINT_HL1_WORLD_BLINKING_LIGHT,
HINT_HL1_WORLD_HUMAN_BLOOD,
HINT_HL1_WORLD_ALIEN_BLOOD,
// CS port hints
HINT_CSTRIKE_HOSTAGE_ESCAPE = 1100,
};
const char *GetHintTypeDescription( Hint_e iHintType );
const char *GetHintTypeDescription( CAI_Hint *pHint );
//-----------------------------------------------------------------------------
// CHintCriteria
//-----------------------------------------------------------------------------
class CHintCriteria
{
public:
CHintCriteria();
~CHintCriteria();
bool HasFlag( int bitmask ) const { return ( m_iFlags & bitmask ) != 0; }
void SetFlag( int bitmask );
void ClearFlag( int bitmask );
void SetGroup( string_t group );
string_t GetGroup( void ) const { return m_strGroup; }
int GetFirstHintType( void ) const { return m_iFirstHintType; }
int GetLastHintType( void ) const { return m_iLastHintType; }
bool MatchesHintType( int hintType ) const;
bool MatchesSingleHintType() const;
bool HasIncludeZones( void ) const { return ( m_zoneInclude.Count() != 0 ); }
bool HasExcludeZones( void ) const { return ( m_zoneExclude.Count() != 0 ); }
void AddIncludePosition( const Vector &position, float radius );
void AddExcludePosition( const Vector &position, float radius );
void SetHintType( int hintType );
void SetHintTypeRange( int firstType, int lastType );
void AddHintType( int hintType );
bool InIncludedZone( const Vector &testPosition ) const;
bool InExcludedZone( const Vector &testPosition ) const;
int NumHintTypes() const;
int GetHintType( int idx ) const;
private:
struct hintZone_t
{
Vector position;
float radiussqr;
};
typedef CUtlVector < hintZone_t > zoneList_t;
void AddZone( zoneList_t &list, const Vector &position, float radius );
bool InZone( const zoneList_t &zone, const Vector &testPosition ) const;
CUtlVector<int> m_HintTypes;
int m_iFlags;
int m_iFirstHintType;
int m_iLastHintType;
string_t m_strGroup;
zoneList_t m_zoneInclude;
zoneList_t m_zoneExclude;
};
class CAI_Node;
//-----------------------------------------------------------------------------
// CAI_HintManager
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE(AIHintIter_t);
class CAIHintVector : public CUtlVector< CAI_Hint * >
{
public:
CAIHintVector() : CUtlVector< CAI_Hint * >( 1, 0 )
{
}
CAIHintVector( const CAIHintVector& src )
{
CopyArray( src.Base(), src.Count() );
}
CAIHintVector &operator=( const CAIHintVector &src )
{
CopyArray( src.Base(), src.Count() );
return *this;
}
};
class CAI_HintManager
{
friend class CAI_Hint;
public:
// Hint node creation
static CAI_Hint *CreateHint( HintNodeData *pNodeData, const char *pMapData = NULL );
static void DrawHintOverlays(float flDrawDuration);
static void AddHint( CAI_Hint *pTestHint );
static void RemoveHint( CAI_Hint *pTestHint );
static void AddHintByType( CAI_Hint *pHint );
static void RemoveHintByType( CAI_Hint *pHintToRemove );
// Interface for searching the hint node list
static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria );
static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria );
static CAI_Hint *FindHint( const Vector &position, const CHintCriteria &hintCriteria );
static CAI_Hint *FindHint( CAI_BaseNPC *pNPC, Hint_e nHintType, int nFlags, float flMaxDist, const Vector *pMaxDistFrom = NULL );
// Purpose: Finds a random suitable hint within the requested radious of the npc
static CAI_Hint *FindHintRandom( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria );
static int FindAllHints( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult );
static int FindAllHints( const Vector &position, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult ) { return FindAllHints( NULL, position, hintCriteria, pResult ); }
static int FindAllHints( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, CUtlVector<CAI_Hint *> *pResult ) { return FindAllHints( pNPC, pNPC->GetAbsOrigin(), hintCriteria, pResult ); }
static int GetFlags( const char *token );
static CAI_Hint *GetFirstHint( AIHintIter_t *pIter );
static CAI_Hint *GetNextHint( AIHintIter_t *pIter );
static void DumpHints();
static void ValidateHints();
private:
enum
{
// MUST BE POWER OF 2
HINT_HISTORY = (1<<3),
HINT_HISTORY_MASK = (HINT_HISTORY-1)
};
static CAI_Hint *AddFoundHint( CAI_Hint *hint );
static int GetFoundHintCount();
static CAI_Hint *GetFoundHint( int index );
static CAI_Hint *GetLastFoundHint();
static void ResetFoundHints();
static bool IsInFoundHintList( CAI_Hint *hint );
static int gm_nFoundHintIndex;
static CAI_Hint *gm_pLastFoundHints[ HINT_HISTORY ]; // Last used hint
static CAIHintVector gm_AllHints; // A linked list of all hints
static CUtlMap< int, CAIHintVector > gm_TypedHints;
};
//-----------------------------------------------------------------------------
// CAI_Hint
//-----------------------------------------------------------------------------
class CAI_Hint : public CServerOnlyEntity
{
DECLARE_CLASS( CAI_Hint, CServerOnlyEntity );
public:
CAI_Hint( void );
~CAI_Hint( void );
// Interface for specific nodes
bool Lock( CBaseEntity *pNPC ); // Makes unavailable for hints
void Unlock( float delay = 0.0 ); // Makes available for hints after delay
bool IsLocked(void); // Whether this node is available for use.
bool IsLockedBy( CBaseEntity *pNPC ); // Whether this node is available for use.
void GetPosition(CBaseCombatCharacter *pBCC, Vector *vPosition);
void GetPosition( Hull_t hull, Vector *vPosition );
Vector GetDirection( void );
float Yaw( void );
CAI_Node *GetNode( void );
string_t GetGroup( void ) const { return m_NodeData.strGroup; }
CBaseEntity *User( void ) const { return m_hHintOwner; };
Hint_e HintType( void ) const { return (Hint_e)m_NodeData.nHintType; };
void SetHintType( int hintType, bool force = false );
string_t HintActivityName( void ) const { return m_NodeData.iszActivityName; }
int GetTargetNode( void ) const { return m_nTargetNodeID; }
bool IsDisabled( void ) const { return (m_NodeData.iDisabled != 0); }
void SetDisabled( bool bDisabled ) { m_NodeData.iDisabled = bDisabled; }
void DisableForSeconds( float flSeconds );
void EnableThink();
void FixupTargetNode();
void NPCStartedUsing( CAI_BaseNPC *pNPC );
void NPCStoppedUsing( CAI_BaseNPC *pNPC );
HintIgnoreFacing_t GetIgnoreFacing() const { return m_NodeData.fIgnoreFacing; }
NPC_STATE GetMinState() const { return m_NodeData.minState; }
NPC_STATE GetMaxState() const { return m_NodeData.maxState; }
int GetNodeId() { return m_NodeData.nNodeID; }
int GetWCId() { return m_NodeData.nWCNodeID; }
bool HintMatchesCriteria( CAI_BaseNPC *pNPC, const CHintCriteria &hintCriteria, const Vector &position, float *flNearestDistance, bool bIgnoreLock = false, bool bIgnoreHintType = false );
bool IsInNodeFOV( CBaseEntity *pOther );
private:
void Spawn( void );
virtual void Activate();
virtual void UpdateOnRemove( void );
int DrawDebugTextOverlays(void);
virtual int ObjectCaps( void ) { return (BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); }
virtual void OnRestore();
bool IsViewable( void );
// Input handlers
void InputEnableHint( inputdata_t &inputdata );
void InputDisableHint( inputdata_t &inputdata );
private:
HintNodeData m_NodeData;
int m_nTargetNodeID;
EHANDLE m_hHintOwner; // Is hint locked (being used by NPC / NPC en-route to use it)
float m_flNextUseTime; // When can I be used again?
COutputEHANDLE m_OnNPCStartedUsing; // Triggered when an NPC has actively begun to use the node.
COutputEHANDLE m_OnNPCStoppedUsing; // Triggered when an NPC has finished using this node.
float m_nodeFOV;
Vector m_vecForward;
// The next hint in list of all hints
friend class CAI_HintManager;
DECLARE_DATADESC();
};
#define SF_ALLOW_JUMP_UP 65536
#endif //AI_HINT_H
|