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
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Base class for helicopters & helicopter-type vehicles
//
// $NoKeywords: $
//=============================================================================//
#ifndef CBASEHELICOPTER_H
#define CBASEHELICOPTER_H
#ifdef _WIN32
#pragma once
#endif
#include "ai_basenpc.h"
#include "ai_trackpather.h"
//---------------------------------------------------------
// Helicopter flags
//---------------------------------------------------------
enum HelicopterFlags_t
{
BITS_HELICOPTER_GUN_ON = 0x00000001, // Gun is on and aiming
BITS_HELICOPTER_MISSILE_ON = 0x00000002, // Missile turrets are on and aiming
};
//---------------------------------------------------------
//---------------------------------------------------------
#define SF_NOWRECKAGE 0x08
#define SF_NOROTORWASH 0x20
#define SF_AWAITINPUT 0x40
//---------------------------------------------------------
//---------------------------------------------------------
// Pathing data
#define BASECHOPPER_LEAD_DISTANCE 800.0f
#define BASECHOPPER_MIN_CHASE_DIST_DIFF 128.0f // Distance threshold used to determine when a target has moved enough to update our navigation to it
#define BASECHOPPER_AVOID_DIST 256.0f
#define BASECHOPPER_MAX_SPEED 400.0f
#define BASECHOPPER_MAX_FIRING_SPEED 250.0f
#define BASECHOPPER_MIN_ROCKET_DIST 1000.0f
#define BASECHOPPER_MAX_GUN_DIST 2000.0f
//---------------------------------------------------------
// Physics rotor pushing
#define BASECHOPPER_WASH_RADIUS 256
#define BASECHOPPER_WASH_PUSH_MIN 30 // Initial force * their mass applied to objects in the wash
#define BASECHOPPER_WASH_PUSH_MAX 40 // Maximum force * their mass applied to objects in the wash
#define BASECHOPPER_WASH_RAMP_TIME 1.0 // Time it takes to ramp from the initial to the max force on an object in the wash (at the center of the wash)
#define BASECHOPPER_WASH_MAX_MASS 300 // Don't attempt to push anything over this mass
#define BASECHOPPER_WASH_MAX_OBJECTS 6 // Maximum number of objects the wash will push at once
// Wash physics pushing
struct washentity_t
{
DECLARE_DATADESC();
EHANDLE hEntity;
float flWashStartTime;
};
#define BASECHOPPER_WASH_ALTITUDE 1024.0f
//=========================================================
//=========================================================
class CBaseHelicopter : public CAI_TrackPather
{
public:
DECLARE_CLASS( CBaseHelicopter, CAI_TrackPather );
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
CBaseHelicopter( void );
void Spawn( void );
void Precache( void );
virtual void UpdateOnRemove();
void Event_Killed( const CTakeDamageInfo &info );
void StopLoopingSounds();
int BloodColor( void ) { return DONT_BLEED; }
void GibMonster( void );
Class_T Classify ( void ) { return CLASS_COMBINE; }
void CallDyingThink( void ) { DyingThink(); }
bool HasEnemy( void ) { return GetEnemy() != NULL; }
virtual void GatherEnemyConditions( CBaseEntity *pEnemy );
virtual bool ChooseEnemy( void );
virtual void HelicopterPostThink( void ) { };
virtual void FlyTouch( CBaseEntity *pOther );
virtual void CrashTouch( CBaseEntity *pOther );
virtual void HelicopterThink( void );
virtual void DyingThink( void );
virtual void NullThink( void );
virtual void Startup ( void );
virtual void Flight( void );
virtual void ShowDamage( void ) {};
void UpdatePlayerDopplerShift( void );
virtual void Hunt( void );
virtual bool IsCrashing( void ) { return m_lifeState != LIFE_ALIVE; }
virtual float GetAcceleration( void ) { return 5; }
virtual void ApplySidewaysDrag( const Vector &vecRight );
virtual void ApplyGeneralDrag( void );
void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
virtual bool FireGun( void );
virtual float GetRotorVolume( void );
virtual void InitializeRotorSound( void );
virtual void UpdateRotorSoundPitch( int iPitch );
virtual void AimRocketGun(void) {};
virtual void FireRocket( Vector vLaunchPos, Vector vLaunchDir ) {};
virtual bool GetTrackPatherTarget( Vector *pPos );
virtual CBaseEntity *GetTrackPatherTargetEnt();
void DrawDebugGeometryOverlays(void);
// Rotor washes
virtual void DrawRotorWash( float flAltitude, const Vector &vecRotorOrigin );
void DoRotorPhysicsPush( const Vector &vecRotorOrigin, float flAltitude );
bool DoWashPush( washentity_t *pWash, const Vector &vecWashOrigin );
void StopRotorWash( void );
// Purpose: Marks the entity for deletion
void InputKill( inputdata_t &inputdata );
void DelayedKillThink( );
virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
// Helicopters never burn
virtual void Ignite( float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner ) { return; }
protected:
void HelicopterMove( );
// Updates the enemy
void UpdateEnemy();
// Override the desired position if your derived helicopter is doing something special
virtual void UpdateDesiredPosition( void );
// Updates the facing direction
virtual void UpdateFacingDirection();
// Fire weapons
void FireWeapons();
// Computes the actual position to fly to
void ComputeActualTargetPosition( float flSpeed, float flTime, float flPerpDist, Vector *pDest, bool bApplyNoise = true );
// Gets the max speed of the helicopter
virtual float GetMaxSpeed();
virtual float GetMaxSpeedFiring();
// Updates the enemy
virtual float EnemySearchDistance( );
// Rotor wash think
void RotorWashThink( void );
// Purpose: Push an airboat in our wash
void DoWashPushOnAirboat( CBaseEntity *pAirboat, const Vector &vecWashToAirboat, float flWashAmount );
// Updates the rotor wash volume
virtual void UpdateRotorWashVolume();
// Rotor sound
void InputEnableRotorSound( inputdata_t &inputdata );
void InputDisableRotorSound( inputdata_t &inputdata );
protected:
CSoundPatch *m_pRotorSound; // Rotor loop played when the player can see the helicopter
CSoundPatch *m_pRotorBlast; // Sound played when the helicopter's pushing around physics objects
float m_flForce;
int m_fHelicopterFlags;
Vector m_vecDesiredFaceDir;
float m_flLastSeen;
float m_flPrevSeen;
int m_iSoundState; // don't save this
Vector m_vecTargetPosition;
float m_flMaxSpeed; // Maximum speed of the helicopter.
float m_flMaxSpeedFiring; // Maximum speed of the helicopter whilst firing guns.
float m_flGoalSpeed; // Goal speed
float m_flInitialSpeed;
float m_flRandomOffsetTime;
Vector m_vecRandomOffset;
float m_flRotorWashEntitySearchTime;
bool m_bSuppressSound;
EHANDLE m_hRotorWash; // Attached rotorwash entity
// Inputs
void InputActivate( inputdata_t &inputdata );
// Inputs
void InputGunOn( inputdata_t &inputdata );
void InputGunOff( inputdata_t &inputdata );
void InputMissileOn( inputdata_t &inputdata );
void InputMissileOff( inputdata_t &inputdata );
void InputEnableRotorWash( inputdata_t &inputdata );
void InputDisableRotorWash( inputdata_t &inputdata );
void InputMoveTopSpeed( inputdata_t &inputdata ); // Causes the helicopter to immediately accelerate to its desired velocity
void InputMoveSpecifiedSpeed( inputdata_t &inputdata );
void InputSetAngles( inputdata_t &inputdata ); // Sets the angles of the helicopter
protected:
// Custom conservative collision volumes
Vector m_cullBoxMins;
Vector m_cullBoxMaxs;
// Wash physics pushing
CUtlVector< washentity_t > m_hEntitiesPushedByWash;
void SetStartupTime( float time ) { m_flStartupTime = time; }
private:
CNetworkVar( float, m_flStartupTime );
};
//-----------------------------------------------------------------------------
// This entity is used to create little force spheres that the helicopter
// should avoid.
//-----------------------------------------------------------------------------
class CAvoidSphere : public CBaseEntity
{
DECLARE_DATADESC();
public:
DECLARE_CLASS( CAvoidSphere, CBaseEntity );
void Init( float flRadius );
virtual void Activate();
virtual void UpdateOnRemove();
static void ComputeAvoidanceForces( CBaseEntity *pEntity, float flEntityRadius, float flAvoidTime, Vector *pVecAvoidForce );
private:
typedef CHandle<CAvoidSphere> AvoidSphereHandle_t;
float m_flRadius;
static CUtlVector< AvoidSphereHandle_t > s_AvoidSpheres;
};
//-----------------------------------------------------------------------------
// This entity is used to create little force boxes that the helicopter
// should avoid.
//-----------------------------------------------------------------------------
class CAvoidBox : public CBaseEntity
{
DECLARE_DATADESC();
public:
DECLARE_CLASS( CAvoidBox, CBaseEntity );
virtual void Spawn( );
virtual void Activate();
virtual void UpdateOnRemove();
static void ComputeAvoidanceForces( CBaseEntity *pEntity, float flEntityRadius, float flAvoidTime, Vector *pVecAvoidForce );
private:
typedef CHandle<CAvoidBox> AvoidBoxHandle_t;
static CUtlVector< AvoidBoxHandle_t > s_AvoidBoxes;
};
#endif // CBASEHELICOPTER_H
|