This repository has been archived by the owner on Oct 3, 2022. It is now read-only.
/
npc_combine.h
337 lines (278 loc) · 10.3 KB
/
npc_combine.h
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
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef NPC_COMBINE_H
#define NPC_COMBINE_H
#ifdef _WIN32
#pragma once
#endif
#include "ai_basenpc.h"
#include "ai_basehumanoid.h"
#include "ai_behavior.h"
#include "ai_behavior_assault.h"
#include "ai_behavior_standoff.h"
#include "ai_behavior_follow.h"
#include "ai_behavior_functank.h"
#include "ai_behavior_rappel.h"
#include "ai_behavior_actbusy.h"
#include "ai_sentence.h"
#include "ai_baseactor.h"
// Used when only what combine to react to what the spotlight sees
#define SF_COMBINE_NO_LOOK (1 << 16)
#define SF_COMBINE_NO_GRENADEDROP ( 1 << 17 )
#define SF_COMBINE_NO_AR2DROP ( 1 << 18 )
//=========================================================
// >> CNPC_Combine
//=========================================================
class CNPC_Combine :
public CAI_BaseActor
{
DECLARE_DATADESC();
DEFINE_CUSTOM_AI;
DECLARE_CLASS( CNPC_Combine, CAI_BaseActor );
public:
CNPC_Combine();
// Create components
virtual bool CreateComponents();
bool CanThrowGrenade( const Vector &vecTarget );
bool CheckCanThrowGrenade( const Vector &vecTarget );
virtual bool CanGrenadeEnemy( bool bUseFreeKnowledge = true );
virtual bool CanAltFireEnemy( bool bUseFreeKnowledge );
virtual bool CanTeleportFromEnemy( bool bUseFreeKnowledge = true );
virtual bool CanTeleportToLOF( bool bUseFreeKnowledge = true );
virtual bool CanTossTeleportGrenade( Vector const &posTarget );
int GetGrenadeConditions( float flDot, float flDist );
int RangeAttack2Conditions( float flDot, float flDist ); // For innate grenade attack
int MeleeAttack1Conditions( float flDot, float flDist ); // For kick/punch
bool FVisible( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
virtual bool IsCurTaskContinuousMove();
virtual float GetDefaultJumpGravity() const { return 1.8f; }
virtual Vector GetCrouchEyeOffset( void );
void Event_Killed( const CTakeDamageInfo &info );
void SetActivity( Activity NewActivity );
NPC_STATE SelectIdealState ( void );
// Input handlers.
void InputLookOn( inputdata_t &inputdata );
void InputLookOff( inputdata_t &inputdata );
void InputStartPatrolling( inputdata_t &inputdata );
void InputStopPatrolling( inputdata_t &inputdata );
void InputAssault( inputdata_t &inputdata );
void InputHitByBugbait( inputdata_t &inputdata );
void InputThrowGrenadeAtTarget( inputdata_t &inputdata );
void InputThrowTeleportGrenadeAtTarget( inputdata_t &inputdata );
bool UpdateEnemyMemory( CBaseEntity *pEnemy, const Vector &position, CBaseEntity *pInformer = NULL );
void Spawn( void );
void Precache( void );
void Activate();
Class_T Classify( void );
bool IsElite() { return m_fIsElite; }
void DelayAltFireAttack( float flDelay );
void DelaySquadAltFireAttack( float flDelay );
float MaxYawSpeed( void );
bool ShouldMoveAndShoot();
bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );;
void HandleAnimEvent( animevent_t *pEvent );
Vector Weapon_ShootPosition( );
Vector EyeOffset( Activity nActivity );
Vector EyePosition( void );
Vector BodyTarget( const Vector &posSrc, bool bNoisy = true );
Vector GetAltFireTarget();
void StartTask( const Task_t *pTask );
void RunTask( const Task_t *pTask );
void PostNPCInit();
void GatherConditions();
virtual void PrescheduleThink();
Activity NPC_TranslateActivity( Activity eNewActivity );
void BuildScheduleTestBits( void );
virtual int SelectSchedule( void );
virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
int SelectScheduleAttack();
bool CreateBehaviors();
bool OnBeginMoveAndShoot();
void OnEndMoveAndShoot();
// Combat
WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon );
bool HasShotgun();
bool ActiveWeaponIsFullyLoaded();
bool HandleInteraction(int interactionType, void *data, CBaseCombatCharacter *sourceEnt);
const char* GetSquadSlotDebugName( int iSquadSlot );
bool IsUsingTacticalVariant( int variant );
bool IsUsingPathfindingVariant( int variant ) { return m_iPathfindingVariant == variant; }
bool IsRunningApproachEnemySchedule();
// -------------
// Sounds
// -------------
void DeathSound( void );
void PainSound( void );
void IdleSound( void );
void AlertSound( void );
void LostEnemySound( void );
void FoundEnemySound( void );
void AnnounceAssault( void );
void AnnounceEnemyType( CBaseEntity *pEnemy );
void AnnounceEnemyKill( CBaseEntity *pEnemy );
void NotifyDeadFriend( CBaseEntity* pFriend );
virtual float HearingSensitivity( void ) { return 1.0; };
int GetSoundInterests( void );
virtual bool QueryHearSound( CSound *pSound );
// Speaking
void SpeakSentence( int sentType );
virtual int TranslateSchedule( int scheduleType );
void OnStartSchedule( int scheduleType );
virtual bool ShouldPickADeathPose( void );
virtual bool PassesDamageFilter( const CTakeDamageInfo &info );
protected:
virtual bool ComputeTeleportToss(
bool bUseFreeKnowledge, bool bPreferCoverPos,
float flAngMin, float flAngMax, float flAngPreference,
float flDistMin, float flDistMax, float flDistPreference,
float flTravelMinDist, float flTravelMaxDist, float flTravelDistPreference );
virtual void Advisor_OnStartedLevitating();
virtual void Advisor_OnFinishedLevitating();
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
virtual void UpdateOnRemove();
protected:
void SetKickDamage( int nDamage ) { m_nKickDamage = nDamage; }
CAI_Sentence< CNPC_Combine > *GetSentences() { return &m_Sentences; }
private:
//=========================================================
// Combine S schedules
//=========================================================
enum
{
SCHED_COMBINE_SUPPRESS = BaseClass::NEXT_SCHEDULE,
SCHED_COMBINE_COMBAT_FAIL,
SCHED_COMBINE_VICTORY_DANCE,
SCHED_COMBINE_COMBAT_FACE,
SCHED_COMBINE_HIDE_AND_RELOAD,
SCHED_COMBINE_SIGNAL_SUPPRESS,
SCHED_COMBINE_ENTER_OVERWATCH,
SCHED_COMBINE_OVERWATCH,
SCHED_COMBINE_ASSAULT,
SCHED_COMBINE_ESTABLISH_LINE_OF_FIRE,
SCHED_COMBINE_PRESS_ATTACK,
SCHED_COMBINE_WAIT_IN_COVER,
SCHED_COMBINE_RANGE_ATTACK1,
SCHED_COMBINE_RANGE_ATTACK2,
SCHED_COMBINE_TAKE_COVER1,
SCHED_COMBINE_TAKE_COVER_FROM_BEST_SOUND,
SCHED_COMBINE_RUN_AWAY_FROM_BEST_SOUND,
SCHED_COMBINE_GRENADE_COVER1,
SCHED_COMBINE_TOSS_GRENADE_COVER1,
SCHED_COMBINE_TAKECOVER_FAILED,
SCHED_COMBINE_GRENADE_AND_RELOAD,
SCHED_COMBINE_PATROL,
SCHED_COMBINE_BUGBAIT_DISTRACTION,
SCHED_COMBINE_CHARGE_TURRET,
SCHED_COMBINE_DROP_GRENADE,
SCHED_COMBINE_CHARGE_PLAYER,
SCHED_COMBINE_PATROL_ENEMY,
SCHED_COMBINE_BURNING_STAND,
SCHED_COMBINE_AR2_ALTFIRE,
SCHED_COMBINE_FORCED_GRENADE_THROW,
SCHED_COMBINE_MOVE_TO_FORCED_GREN_LOS,
SCHED_COMBINE_FACE_IDEAL_YAW,
SCHED_COMBINE_MOVE_TO_MELEE,
SCHED_COMBINE_TELEPORT_GRENADE_FROM_ENEMY,
SCHED_COMBINE_TELEPORT_GRENADE_LOF,
SCHED_COMBINE_FORCED_TELEPORT_GRENADE_THROW,
SCHED_COMBINE_ADVISOR_LEVITATE,
NEXT_SCHEDULE,
};
//=========================================================
// Combine Tasks
//=========================================================
enum
{
TASK_COMBINE_FACE_TOSS_DIR = BaseClass::NEXT_TASK,
TASK_COMBINE_IGNORE_ATTACKS,
TASK_COMBINE_SIGNAL_BEST_SOUND,
TASK_COMBINE_DEFER_SQUAD_GRENADES,
TASK_COMBINE_CHASE_ENEMY_CONTINUOUSLY,
TASK_COMBINE_DIE_INSTANTLY,
TASK_COMBINE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET,
TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS,
TASK_COMBINE_SET_STANDING,
TASK_WAIT_FOR_TELEPORT,
TASK_ADVISOR_LEVITATE,
NEXT_TASK
};
//=========================================================
// Combine Conditions
//=========================================================
enum Combine_Conds
{
COND_COMBINE_NO_FIRE = BaseClass::NEXT_CONDITION,
COND_COMBINE_DEAD_FRIEND,
COND_COMBINE_SHOULD_PATROL,
COND_COMBINE_HIT_BY_BUGBAIT,
COND_COMBINE_DROP_GRENADE,
COND_COMBINE_ON_FIRE,
COND_COMBINE_ATTACK_SLOT_AVAILABLE,
NEXT_CONDITION
};
private:
// Select the combat schedule
int SelectCombatSchedule();
// Should we charge the player?
bool ShouldChargePlayer();
// Chase the enemy, updating the target position as the player moves
void StartTaskChaseEnemyContinuously( const Task_t *pTask );
void RunTaskChaseEnemyContinuously( const Task_t *pTask );
class CCombineStandoffBehavior : public CAI_ComponentWithOuter<CNPC_Combine, CAI_StandoffBehavior>
{
typedef CAI_ComponentWithOuter<CNPC_Combine, CAI_StandoffBehavior> BaseClass;
virtual int SelectScheduleAttack()
{
int result = GetOuter()->SelectScheduleAttack();
if ( result == SCHED_NONE )
result = BaseClass::SelectScheduleAttack();
return result;
}
};
// Rappel
virtual bool IsWaitingToRappel( void ) { return m_RappelBehavior.IsWaitingToRappel(); }
void BeginRappel() { m_RappelBehavior.BeginRappel(); }
private:
void OnTossedTeleportProjectile( CBaseEntity *pProjectile );
void OnTeleportProjectileAction( CBaseEntity *pProjectile, bool bTeleport );
void FullyLoadWeaponClips();
private:
int m_nKickDamage;
Vector m_vecTossVelocity;
EHANDLE m_hForcedGrenadeTarget;
bool m_bShouldPatrol;
bool m_bFirstEncounter;// only put on the handsign show in the squad's first encounter.
// Time Variables
float m_flNextPainSoundTime;
float m_flNextAlertSoundTime;
float m_flNextGrenadeCheck;
float m_flNextLostSoundTime;
float m_flAlertPatrolTime; // When to stop doing alert patrol
float m_flNextAltFireTime; // Elites only. Next time to begin considering alt-fire attack.
int m_nShots;
float m_flShotDelay;
float m_flStopMoveShootTime;
CAI_Sentence< CNPC_Combine > m_Sentences;
int m_iNumGrenades;
int m_iTeleportGrenades;
float m_flLastTeleportGrenadeTime;
float m_flNextTeleportGrenadeTime;
EHANDLE m_hTeleportProjectile;
EHANDLE m_hTeleportProjectileForcedTarget;
CAI_AssaultBehavior m_AssaultBehavior;
CCombineStandoffBehavior m_StandoffBehavior;
CAI_FollowBehavior m_FollowBehavior;
CAI_FuncTankBehavior m_FuncTankBehavior;
CAI_RappelBehavior m_RappelBehavior;
CAI_ActBusyBehavior m_ActBusyBehavior;
public:
int m_iLastAnimEventHandled;
bool m_fIsElite;
Vector m_vecAltFireTarget;
int m_iTacticalVariant;
int m_iPathfindingVariant;
};
#endif // NPC_COMBINE_H