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
342
343
344
345
346
347
348
349
350
351
352
353
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef FUNC_TANK_H
#define FUNC_TANK_H
#ifdef _WIN32
#pragma once
#endif
#include "triggers.h"
#define SF_TANK_ACTIVE 0x0001
#define SF_TANK_PLAYER 0x0002
#define SF_TANK_HUMANS 0x0004
#define SF_TANK_ALIENS 0x0008
#define SF_TANK_LINEOFSIGHT 0x0010
#define SF_TANK_CANCONTROL 0x0020
#define SF_TANK_DAMAGE_KICK 0x0040 // Kick when take damage
#define SF_TANK_AIM_AT_POS 0x0080 // Aim at a particular position
#define SF_TANK_AIM_ASSISTANCE 0x0100
#define SF_TANK_NPC 0x0200
#define SF_TANK_NPC_CONTROLLABLE 0x0400 // 1024
#define SF_TANK_NPC_SET_CONTROLLER 0x0800 // 2048
#define SF_TANK_ALLOW_PLAYER_HITS 0x1000 // 4096 Allow friendly NPCs to fire upon enemies near the player
#define SF_TANK_IGNORE_RANGE_IN_VIEWCONE 0x2000 // 8192 Don't use range as a factor in determining if something is in view cone
#define SF_TANK_NOTSOLID 0x8000 // 32768
#define SF_TANK_SOUNDON 0x10000 // FIXME: This is not really a spawnflag! It holds transient state!!!
#define SF_TANK_HACKPLAYERHIT 0x20000 // 131072 Make this func_tank cheat and hit the player regularly
#define FUNCTANK_DISTANCE_MAX 1200 // 100 ft.
#define FUNCTANK_DISTANCE_MIN_TO_ENEMY 180
#define FUNCTANK_FIREVOLUME 1000
#define FUNCTANK_NPC_ROUTE_TIME 5.0f
// Effect handling
// If the func_tank has a chosen method of handling effects, use that
// instead of the individual effect settings. (muzzleflash, sound, tracer, etc)
enum FUNCTANK_EFFECT_HANDLING
{
EH_NONE, // Use the effect settings
EH_AR2, // Use AR2 effects
EH_COMBINE_CANNON // Large Combine cannon
};
enum TANKBULLET
{
TANK_BULLET_NONE = 0,
TANK_BULLET_SMALL = 1,
TANK_BULLET_MEDIUM = 2,
TANK_BULLET_LARGE = 3,
};
#define MORTAR_BLAST_RADIUS 350
// Custom damage
// env_laser (duration is 0.5 rate of fire)
// rockets
// explosion?
class CFuncTank : public CBaseEntity
{
DECLARE_CLASS( CFuncTank, CBaseEntity );
public:
CFuncTank();
~CFuncTank();
void Spawn( void );
void Activate( void );
void Precache( void );
bool CreateVPhysics( void );
bool KeyValue( const char *szKeyName, const char *szValue );
void UpdateOnRemove();
void SetYawRate( float flYawRate ) { m_yawRate = flYawRate; }
void SetPitchRate( float flPitchRate ) { m_pitchRate = flPitchRate; }
int ObjectCaps( void )
{
return ( BaseClass::ObjectCaps() | FCAP_IMPULSE_USE | FCAP_USE_IN_RADIUS );
}
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual void FuncTankPreThink() { return; }
void Think( void );
virtual void FuncTankPostThink() { return; }
int GetAmmoCount( void ) { return m_iAmmoCount; }
// NPC
bool NPC_FindManPoint( Vector &vecPos );
bool NPC_HasEnemy( void );
void NPC_Fire( void );
void NPC_InterruptRoute( void );
void NPC_JustSawPlayer( CBaseEntity *pTarget );
void NPC_SetInRoute( bool bInRoute ) { m_bNPCInRoute = bInRoute; }
void NPC_SetIdleAngle( Vector vecIdle ) { m_vecNPCIdleTarget = vecIdle; }
// LOS
bool IsEntityInViewCone( CBaseEntity *pEntity );
bool HasLOSTo( CBaseEntity *pEntity );
// Controller
CBaseCombatCharacter *GetController( void );
bool StartControl( CBaseCombatCharacter *pController );
void StopControl( void );
Vector GetTargetPosition() { return m_vTargetPosition; }
void SetTargetPosition( const Vector &vecPos ) { m_vTargetPosition = vecPos; }
const float YawCenter() const { return m_yawCenter; }
const float YawCenterWorld() const { return m_yawCenterWorld; }
const float YawRange() const { return m_yawRange; }
const float PitchCenter() const { return m_pitchCenter; }
const float PitchCenterWorld() const { return m_pitchCenterWorld; }
const float PitchRange() const { return m_pitchRange; }
virtual void PhysicsSimulate( void );
virtual void OnStartControlled() {}
virtual void OnStopControlled() {}
// SF Tests.
inline bool IsControllable( void ) { return ( m_spawnflags & SF_TANK_CANCONTROL ) ? true : false; }
inline bool IsActive( void ) { return ( m_spawnflags & SF_TANK_ACTIVE ) ? true : false; }
inline bool IsNPCControllable( void ) { return ( m_spawnflags & SF_TANK_NPC_CONTROLLABLE ) ? true : false; }
inline bool IsNPCSetController( void ) { return ( m_spawnflags & SF_TANK_NPC_SET_CONTROLLER ) ? true : false; }
virtual void DoMuzzleFlash( void );
virtual const char *GetTracerType( void );
protected:
virtual float GetShotSpeed() { return 0; }
virtual Vector WorldBarrelPosition( void );
void UpdateMatrix( void );
float GetNextAttack() const { return m_flNextAttack; }
virtual void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
virtual void Fire( int bulletCount, const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker, bool bIgnoreSpread );
void TankTrace( const Vector &vecStart, const Vector &vecForward, const Vector &vecSpread, trace_t &tr );
int GetRandomBurst( void );
float GetRandomFireTime( void );
void CalcPlayerCrosshairTarget( Vector *pVecTarget );
void CalcNPCEnemyTarget( Vector *pVecTarget );
inline bool IsPlayerManned( void ) { return m_hController && m_hController->IsPlayer() && ( m_spawnflags & SF_TANK_PLAYER ); }
inline bool IsNPCManned( void ) { return m_hController && m_hController->MyNPCPointer() && ( m_spawnflags & SF_TANK_NPC ); }
private:
void TrackTarget( void );
int DrawDebugTextOverlays(void);
void DrawDebugGeometryOverlays(void);
virtual void FiringSequence( const Vector &barrelEnd, const Vector &forward, CBaseEntity *pAttacker );
void StartRotSound( void );
void StopRotSound( void );
// Input handlers.
void InputActivate( inputdata_t &inputdata );
void InputDeactivate( inputdata_t &inputdata );
void InputSetFireRate( inputdata_t &inputdata );
void InputSetDamage( inputdata_t &inputdata );
void InputSetTargetDir( inputdata_t &inputdata );
void InputSetTargetPosition( inputdata_t &inputdata );
void InputSetTargetEntityName( inputdata_t &inputdata );
protected:
virtual void InputSetTargetEntity( inputdata_t &inputdata );
virtual void InputClearTargetEntity( inputdata_t &inputdata );
private:
void InputFindNPCToManTank( inputdata_t &inputdata );
void InputStopFindingNPCs( inputdata_t &inputdata );
void InputStartFindingNPCs( inputdata_t &inputdata );
void InputForceNPCOff( inputdata_t &inputdata );
void InputSetMaxRange( inputdata_t &inputdata );
inline bool CanFire( void );
bool InRange( float range );
bool InRange2( float flRange2 );
void TraceAttack( CBaseEntity *pAttacker, float flDamage, const Vector &vecDir, trace_t *ptr, int bitsDamageType);
QAngle AimBarrelAt( const Vector &parentTarget );
DECLARE_DATADESC();
bool OnControls( CBaseEntity *pTest );
bool HasController( void );
CBaseEntity *FindTarget( string_t targetName, CBaseEntity *pActivator );
// NPC
void NPC_FindController( void );
bool NPC_InRoute( void ) { return m_bNPCInRoute; }
bool NPC_InterruptController( void );
// Aim the tank at the player crosshair
void AimBarrelAtPlayerCrosshair( QAngle *pAngles );
// Aim the tank at the NPC's enemy
void AimBarrelAtNPCEnemy( QAngle *pAngles );
// Aim the tank at the func_tank's enemy
void AimFuncTankAtTarget( void );
// Returns true if the desired angles are out of range
bool RotateTankToAngles( const QAngle &angles, float *pDistX = NULL, float *pDistY = NULL );
// We lost our target!
void LostTarget( void );
// Purpose:
void ComputeLeadingPosition( const Vector &vecShootPosition, CBaseEntity *pTarget, Vector *pLeadPosition );
protected:
virtual void ControllerPostFrame( void );
virtual void TankActivate(void);
virtual void TankDeactivate(void);
float m_fireLast; // Last time I fired
float m_fireRate; // How many rounds/second
EHANDLE m_hTarget;
TANKBULLET m_bulletType; // Bullet type
int m_iBulletDamage; // 0 means use Bullet type's default damage
int m_iBulletDamageVsPlayer; // Damage vs player. 0 means use m_iBulletDamage
#ifdef HL2_EPISODIC
string_t m_iszAmmoType; // The name of the ammodef that we use when we fire. Bullet damage still comes from keyvalues.
int m_iAmmoType; // The cached index of the ammodef that we use when we fire.
#else
int m_iSmallAmmoType;
int m_iMediumAmmoType;
int m_iLargeAmmoType;
#endif // HL2_EPISODIC
int m_spread; // firing spread
EntityMatrix m_parentMatrix;
Vector m_sightOrigin; // Last sight of target
EHANDLE m_hFuncTankTarget;
int m_nBulletCount;
private:
// This is either the player manning the func_tank, or an NPC. The NPC is either manning the tank, or running
// to the man point. If he's en-route, m_bNPCInRoute will be true.
CHandle<CBaseCombatCharacter> m_hController;
float m_flNextAttack;
Vector m_vecControllerUsePos;
float m_yawCenter; // "Center" yaw
float m_yawCenterWorld; // "Center" yaw in world space
float m_yawRate; // Max turn rate to track targets
float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30 degress from center)
// Zero is full rotation
float m_yawTolerance; // Tolerance angle
float m_pitchCenter; // "Center" pitch
float m_pitchCenterWorld; // "Center" pitch in world space
float m_pitchRate; // Max turn rate on pitch
float m_pitchRange; // Range of pitch motion as above
float m_pitchTolerance; // Tolerance angle
float m_fireTime; // How much time has been used to fire the weapon so far.
float m_lastSightTime;// Last time I saw target
float m_persist; // Persistence of firing (how long do I shoot when I can't see)
float m_persist2; // Secondary persistence of firing (randomly shooting when I can't see)
float m_persist2burst;// How long secondary persistence burst lasts
float m_minRange; // Minimum range to aim/track
float m_maxRange; // Max range to aim/track
float m_flMinRange2;
float m_flMaxRange2;
int m_iAmmoCount; // ammo
Vector m_barrelPos; // Length of the freakin barrel
float m_spriteScale; // Scale of any sprites we shoot
string_t m_iszSpriteSmoke;
string_t m_iszSpriteFlash;
string_t m_iszMaster; // Master entity (game_team_master or multisource)
string_t m_soundStartRotate;
string_t m_soundStopRotate;
string_t m_soundLoopRotate;
float m_flPlayerGracePeriod;
float m_flIgnoreGraceUpto;
float m_flPlayerLockTimeBeforeFire;
float m_flLastSawNonPlayer;
string_t m_targetEntityName;
Vector m_vTargetPosition;
Vector m_vecNPCIdleTarget;
// Used for when the gun is attached to another entity
string_t m_iszBarrelAttachment;
int m_nBarrelAttachment;
string_t m_iszBaseAttachment;
// Used when the gun is actually a part of the parent entity, and pose params aim it
string_t m_iszYawPoseParam;
string_t m_iszPitchPoseParam;
float m_flYawPoseCenter;
float m_flPitchPoseCenter;
bool m_bUsePoseParameters;
// Lead the target?
bool m_bPerformLeading;
float m_flStartLeadFactor;
float m_flStartLeadFactorTime;
float m_flNextLeadFactor;
float m_flNextLeadFactorTime;
COutputEvent m_OnFire;
COutputEvent m_OnLoseTarget;
COutputEvent m_OnAquireTarget;
COutputEvent m_OnAmmoDepleted;
COutputEvent m_OnGotController;
COutputEvent m_OnLostController;
COutputEvent m_OnGotPlayerController;
COutputEvent m_OnLostPlayerController;
COutputEvent m_OnReadyToFire;
CHandle<CBaseTrigger> m_hControlVolume;
string_t m_iszControlVolume;
float m_flNextControllerSearch;
bool m_bShouldFindNPCs;
bool m_bNPCInRoute;
string_t m_iszNPCManPoint;
bool m_bReadyToFire;
int m_iEffectHandling;
};
#endif // FUNC_TANK_H
|