aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/server/vehicle_baseserver.h
blob: cdf1f75a8a231562826b3c017451460ed4d20e6a (plain) (blame)
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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================//

#ifndef VEHICLE_BASESERVER_H
#define VEHICLE_BASESERVER_H
#ifdef _WIN32
#pragma once
#endif

#include "vehicle_sounds.h"
#include "entityblocker.h"

class CSoundPatch;

struct vbs_sound_update_t
{
	float	flFrameTime;
	float	flCurrentSpeedFraction;
	float	flWorldSpaceSpeed;
	bool	bThrottleDown;
	bool	bReverse;
	bool	bTurbo;
	bool	bVehicleInWater;
	bool	bExitVehicle;

	void Defaults()
	{
		flFrameTime = gpGlobals->frametime;
		flCurrentSpeedFraction = 0;
		flWorldSpaceSpeed = 0;
		bThrottleDown = false;
		bReverse = false;
		bTurbo = false;
		bVehicleInWater = false;
		bExitVehicle = false;
	}
};

// -----------------------------------------
//  Information about the passenger in the car 
// -----------------------------------------
class CPassengerInfo
{
public:
	CPassengerInfo( void ) : m_nRole( -1 ), m_nSeat( -1 ), m_strRoleName( NULL_STRING ), m_strSeatName( NULL_STRING ) {}

	DECLARE_SIMPLE_DATADESC();

	int GetSeat( void ) const { return m_nSeat; }
	int	GetRole( void ) const { return m_nRole; }
	CBaseCombatCharacter *GetPassenger( void ) const { return m_hPassenger; }

private:
	int									m_nRole;		// Role (by index)
	int									m_nSeat;		// Seat (by index)
	string_t							m_strRoleName;	// Used in restoration for fix-up
	string_t							m_strSeatName;	// Used in restoration for fix-up
	CHandle<CBaseCombatCharacter>		m_hPassenger;	// Actual passenger

	friend class CBaseServerVehicle;
};

// -----------------------------------------
//  Seat transition information (animation and priority)
// -----------------------------------------

class CPassengerSeatTransition
{
public:
	CPassengerSeatTransition( void ) : m_strAnimationName( NULL_STRING ), m_nPriority( -1 ) {};

	string_t GetAnimationName( void ) const { return m_strAnimationName; }
	int		 GetPriority( void ) const { return m_nPriority; }

private:
	string_t	m_strAnimationName;	// Name of animation to play
	int			m_nPriority;		// Priority of the transition

	friend class CBaseServerVehicle;
};

// -----------------------------------------
//  Seat in a vehicle (attachment and a collection of animations to reach it)
// -----------------------------------------
class CPassengerSeat
{
public:
	CPassengerSeat( void ) : m_nAttachmentID( -1 ) {};
	int GetAttachmentID( void ) const { return m_nAttachmentID; }

private:
	string_t								m_strSeatName;			// Used for save/load fixup
	int										m_nAttachmentID;		// Goal attachment
	CUtlVector<CPassengerSeatTransition>	m_EntryTransitions;		// Entry information
	CUtlVector<CPassengerSeatTransition>	m_ExitTransitions;		// Exit information

	friend class CBaseServerVehicle;
};

// -----------------------------------------
//  Passenger role information
// -----------------------------------------
class CPassengerRole
{
public:
	CPassengerRole( void ) : m_strName( NULL_STRING ) {};
	string_t GetName( void ) const { return m_strName; }

private:
	string_t						m_strName;			// Name of the set
	CUtlVector<CPassengerSeat>		m_PassengerSeats;	// Passenger info

	friend class CBaseServerVehicle;
};

//-----------------------------------------------------------------------------
// Purpose: Base class for drivable vehicle handling. Contain it in your 
//			drivable vehicle.
//-----------------------------------------------------------------------------
class CBaseServerVehicle : public IServerVehicle
{
public:
	DECLARE_SIMPLE_DATADESC();
	DECLARE_CLASS_NOBASE( CBaseServerVehicle );

	CBaseServerVehicle( void );
	~CBaseServerVehicle( void );

	virtual void			Precache( void );

// IVehicle
public:
	virtual CBaseCombatCharacter *GetPassenger( int nRole = VEHICLE_ROLE_DRIVER );

	virtual int				GetPassengerRole( CBaseCombatCharacter *pPassenger );
	virtual void			GetVehicleViewPosition( int nRole, Vector *pOrigin, QAngle *pAngles, float *pFOV = NULL );
	virtual bool			IsPassengerUsingStandardWeapons( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
	virtual void			SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move );
	virtual void			ProcessMovement( CBasePlayer *pPlayer, CMoveData *pMoveData );
	virtual void			FinishMove( CBasePlayer *player, CUserCmd *ucmd, CMoveData *move );
	virtual void			ItemPostFrame( CBasePlayer *pPlayer );

// IServerVehicle
public:
	virtual CBaseEntity		*GetVehicleEnt( void ) { return m_pVehicle; }
	virtual void			SetPassenger( int nRole, CBaseCombatCharacter *pPassenger );
	virtual bool			IsPassengerVisible( int nRole = VEHICLE_ROLE_DRIVER ) { return false; }
	virtual bool			IsPassengerDamagable( int nRole  = VEHICLE_ROLE_DRIVER ) { return true; }
	virtual bool			PassengerShouldReceiveDamage( CTakeDamageInfo &info );

	virtual bool			IsVehicleUpright( void ) { return true; }
	virtual bool			IsPassengerEntering( void ) { Assert( 0 ); return false; }
	virtual bool			IsPassengerExiting( void ) { Assert( 0 ); return false; }
	
	virtual void			HandlePassengerEntry( CBaseCombatCharacter *pPassenger, bool bAllowEntryOutsideZone = false );
	virtual bool			HandlePassengerExit( CBaseCombatCharacter *pPassenger );

	virtual void			GetPassengerSeatPoint( int nRole, Vector *pPoint, QAngle *pAngles );
	virtual bool			GetPassengerExitPoint( int nRole, Vector *pPoint, QAngle *pAngles );
	virtual Class_T			ClassifyPassenger( CBaseCombatCharacter *pPassenger, Class_T defaultClassification ) { return defaultClassification; }
	virtual float			PassengerDamageModifier( const CTakeDamageInfo &info ) { return 1.0; }
	virtual const vehicleparams_t	*GetVehicleParams( void ) { return NULL; }
	virtual bool			IsVehicleBodyInWater( void ) { return false; }
	virtual IPhysicsVehicleController *GetVehicleController() { return NULL; }

	// NPC Driving
	virtual bool			NPC_CanDrive( void ) { return true; }
	virtual void			NPC_SetDriver( CNPC_VehicleDriver *pDriver ) { return; }
	virtual void			NPC_DriveVehicle( void ) { return; }
	virtual void			NPC_ThrottleCenter( void );
	virtual void			NPC_ThrottleReverse( void );
	virtual void			NPC_ThrottleForward( void );
	virtual void			NPC_Brake( void );
	virtual void			NPC_TurnLeft( float flDegrees );
	virtual void			NPC_TurnRight( float flDegrees );
	virtual void			NPC_TurnCenter( void );
	virtual void			NPC_PrimaryFire( void );
	virtual void			NPC_SecondaryFire( void );
	virtual bool			NPC_HasPrimaryWeapon( void ) { return false; }
	virtual bool			NPC_HasSecondaryWeapon( void ) { return false; }
	virtual void			NPC_AimPrimaryWeapon( Vector vecTarget ) { return; }
	virtual void			NPC_AimSecondaryWeapon( Vector vecTarget ) { return; }

	// Weapon handling
	virtual void			Weapon_PrimaryRanges( float *flMinRange, float *flMaxRange );
	virtual void			Weapon_SecondaryRanges( float *flMinRange, float *flMaxRange );	
	virtual float			Weapon_PrimaryCanFireAt( void );		// Return the time at which this vehicle's primary weapon can fire again
	virtual float			Weapon_SecondaryCanFireAt( void );		// Return the time at which this vehicle's secondary weapon can fire again

	// ----------------------------------------------------------------------------
	// NPC passenger data

public:

	bool			NPC_AddPassenger( CBaseCombatCharacter *pPassenger, string_t strRoleName, int nSeat );
	bool			NPC_RemovePassenger( CBaseCombatCharacter *pPassenger );
	virtual bool	NPC_GetPassengerSeatPosition( CBaseCombatCharacter *pPassenger, Vector *vecResultPos, QAngle *vecResultAngle );
	virtual bool	NPC_GetPassengerSeatPositionLocal( CBaseCombatCharacter *pPassenger, Vector *vecResultPos, QAngle *vecResultAngles );
	virtual int		NPC_GetPassengerSeatAttachment( CBaseCombatCharacter *pPassenger );
	virtual int		NPC_GetAvailableSeat( CBaseCombatCharacter *pPassenger, string_t strRoleName, VehicleSeatQuery_e nQueryType );
	bool			NPC_HasAvailableSeat( string_t strRoleName );


	virtual const PassengerSeatAnims_t	*NPC_GetPassengerSeatAnims( CBaseCombatCharacter *pPassenger, PassengerSeatAnimType_t nType );
	virtual CBaseCombatCharacter		*NPC_GetPassengerInSeat( int nRoleID, int nSeatID );

	Vector	GetSavedViewOffset( void ) { return m_savedViewOffset; }

private:

	// Vehicle entering/exiting
	void	ParseNPCRoles( KeyValues *pModelKeyValues );
	void	ParseNPCPassengerSeat( KeyValues *pSetKeyValues, CPassengerSeat *pSeat );
	void	ParseNPCSeatTransition( KeyValues *pTransitionKeyValues, CPassengerSeatTransition *pTransition );

protected:
	
	int		FindRoleIndexByName( string_t strRoleName );
	int		FindSeatIndexByName( int nRoleIndex, string_t strSeatName );
	int		NPC_GetAvailableSeat_Any( CBaseCombatCharacter *pPassenger, int nRoleID );
	int		NPC_GetAvailableSeat_Nearest( CBaseCombatCharacter *pPassenger, int nRoleID );

	CPassengerRole *FindOrCreatePassengerRole( string_t strName, int *nIndex = NULL );

	CUtlVector< CPassengerInfo >	m_PassengerInfo;
	CUtlVector< CPassengerRole >	m_PassengerRoles;	// Not save/restored

	// ----------------------------------------------------------------------------
	void	ReloadScript();	// debug/tuning
public:

	void					UseLegacyExitChecks( bool bState ) { m_bUseLegacyExitChecks = bState; }
	void					RestorePassengerInfo( void );

	virtual CBaseEntity		*GetDriver( void );	// Player Driving
	virtual void			ParseEntryExitAnims( void );
	void					ParseExitAnim( KeyValues *pkvExitList, bool bEscapeExit );
	virtual bool			CheckExitPoint( float yaw, int distance, Vector *pEndPoint );
	virtual int				GetEntryAnimForPoint( const Vector &vecPoint );
	virtual int				GetExitAnimToUse( Vector &vecEyeExitEndpoint, bool &bAllPointsBlocked );
	virtual void			HandleEntryExitFinish( bool bExitAnimOn, bool bResetAnim );

	virtual void			SetVehicle( CBaseEntity *pVehicle );
	IDrivableVehicle 		*GetDrivableVehicle( void );

	// Sound handling
	bool					Initialize( const char *pScriptName );
	virtual void			SoundStart();
	virtual void			SoundStartDisabled();
	virtual void			SoundShutdown( float flFadeTime = 0.0 );
	virtual void			SoundUpdate( vbs_sound_update_t &params );
	virtual void			PlaySound( vehiclesound iSound );
	virtual void			StopSound( vehiclesound iSound );
	virtual void 			RecalculateSoundGear( vbs_sound_update_t &params );
	void					SetVehicleVolume( float flVolume ) { m_flVehicleVolume = clamp( flVolume, 0.0f, 1.0f ); }

	// Rumble
	virtual void			StartEngineRumble();
	virtual void			StopEngineRumble();

public:
	CBaseEntity			*m_pVehicle;
	IDrivableVehicle 	*m_pDrivableVehicle;

	// NPC Driving
	int								m_nNPCButtons;
	int								m_nPrevNPCButtons;
	float							m_flTurnDegrees;

	// Entry / Exit anims
	struct entryanim_t
	{
		int		iHitboxGroup;
		char	szAnimName[128];
	};
	CUtlVector< entryanim_t >		m_EntryAnimations;

	struct exitanim_t
	{
		bool	bUpright;
		bool	bEscapeExit;
		char	szAnimName[128];
		Vector	vecExitPointLocal;		// Point the animation leaves the player at when finished
		QAngle	vecExitAnglesLocal;
	};

	CUtlVector< exitanim_t >		m_ExitAnimations;
	bool							m_bParsedAnimations;
	bool							m_bUseLegacyExitChecks;	// HACK: Choreo vehicles use non-sensical setups to move the player, we need to poll their attachment point positions
	int								m_iCurrentExitAnim;
	Vector							m_vecCurrentExitEndPoint;
	Vector							m_savedViewOffset;
	CHandle<CEntityBlocker>			m_hExitBlocker;				// Entity to prevent other entities blocking the player's exit point during the exit animation

	char							m_chPreviousTextureType;

// sound state
	vehiclesounds_t					m_vehicleSounds;
private:
	float							m_flVehicleVolume;
	int								m_iSoundGear;			// The sound "gear" that we're currently in
	float							m_flSpeedPercentage;

	CSoundPatch						*m_pStateSound;
	CSoundPatch						*m_pStateSoundFade;
	sound_states					m_soundState;
	float							m_soundStateStartTime;
	float							m_lastSpeed;
	
	void	SoundState_OnNewState( sound_states lastState );
	void	SoundState_Update( vbs_sound_update_t &params );
	sound_states SoundState_ChooseState( vbs_sound_update_t &params );
	void	PlaySound( const char *pSound );
	void	StopLoopingSound( float fadeTime = 0.25f );
	void	PlayLoopingSound( const char *pSoundName );
	bool	PlayCrashSound( float speed );
	bool	CheckCrash( vbs_sound_update_t &params );
	const char *StateSoundName( sound_states state );
	void	InitSoundParams( vbs_sound_update_t &params );
	void	CacheEntryExitPoints( void );
	bool	GetLocalAttachmentAtTime( int nQuerySequence, int nAttachmentIndex, float flCyclePoint, Vector *vecOriginOut, QAngle *vecAnglesOut );
	bool	GetLocalAttachmentAtTime( const char *lpszAnimName, int nAttachmentIndex, float flCyclePoint, Vector *vecOriginOut, QAngle *vecAnglesOut );
};

#endif // VEHICLE_BASESERVER_H