All pastes #509351 Raw Edit

c_baseplayer.cpp

public cpp v1 · immutable
·published 2007-05-25 12:30 UTC
rendered paste body
//====== Copyright  1996-2005, Valve Corporation, All rights reserved. =====////// Purpose: Client-side CBasePlayer.////			- Manages the player's flashlight effect.////===========================================================================//#include "cbase.h"#include "c_baseplayer.h"#include "flashlighteffect.h"#include "weapon_selection.h"#include "history_resource.h"#include "iinput.h"#include "input.h"#include "view.h"#include "iviewrender.h"#include "iclientmode.h"#include "in_buttons.h"#include "engine/IEngineSound.h"#include "c_soundscape.h"#include "usercmd.h"#include "c_playerresource.h"#include "iclientvehicle.h"#include "view_shared.h"#include "C_VguiScreen.h"#include "movevars_shared.h"#include "prediction.h"#include "tier0/vprof.h"#include "filesystem.h"#include "bitbuf.h"#include "KeyValues.h"#include "particles_simple.h"#include "fx_water.h"#include "hltvcamera.h"#include "toolframework/itoolframework.h"#include "toolframework_client.h"#include "view_scene.h"// memdbgon must be the last include file in a .cpp file!!!#include "tier0/memdbgon.h"// Don't alias here#if defined( CBasePlayer )#undef CBasePlayer	#endifint g_nKillCamMode = OBS_MODE_NONE;int g_nKillCamTarget1 = 0;int g_nKillCamTarget2 = 0;int g_nUsedPrediction = 1;extern ConVar mp_forcecamera; // in gamevars_shared.h#define FLASHLIGHT_DISTANCE		1000#define MAX_VGUI_INPUT_MODE_SPEED 30#define MAX_VGUI_INPUT_MODE_SPEED_SQ (MAX_VGUI_INPUT_MODE_SPEED*MAX_VGUI_INPUT_MODE_SPEED)static Vector WALL_MIN(-WALL_OFFSET,-WALL_OFFSET,-WALL_OFFSET);static Vector WALL_MAX(WALL_OFFSET,WALL_OFFSET,WALL_OFFSET);extern ConVar default_fov;#ifndef _XBOXextern ConVar sensitivity;#endifstatic C_BasePlayer *s_pLocalPlayer = NULL;static ConVar	cl_customsounds ( "cl_customsounds", "0", 0, "Enable customized player sound playback" );static ConVar	spec_track		( "spec_track", "0", 0, "Tracks an entity in spec mode" );static ConVar	cl_smooth		( "cl_smooth", "1", 0, "Smooth view/eye origin after prediction errors" );static ConVar	cl_smoothtime	( 	"cl_smoothtime", 	"0.1", 	0, 	"Smooth client's view after prediction error over this many seconds",	true, 0.01,	// min/max is 0.01/2.0	true, 2.0	 );ConVar zoom_sensitivity_ratio( "zoom_sensitivity_ratio", "1.0", 0, "Additional mouse sensitivity scale factor applied when FOV is zoomed in." );void RecvProxy_FOV( const CRecvProxyData *pData, void *pStruct, void *pOut );void RecvProxy_DefaultFOV( const CRecvProxyData *pData, void *pStruct, void *pOut );void RecvProxy_LocalVelocityX( const CRecvProxyData *pData, void *pStruct, void *pOut );void RecvProxy_LocalVelocityY( const CRecvProxyData *pData, void *pStruct, void *pOut );void RecvProxy_LocalVelocityZ( const CRecvProxyData *pData, void *pStruct, void *pOut );void RecvProxy_ObserverTarget( const CRecvProxyData *pData, void *pStruct, void *pOut );// -------------------------------------------------------------------------------- //// RecvTable for CPlayerState.// -------------------------------------------------------------------------------- //	BEGIN_RECV_TABLE_NOBASE(CPlayerState, DT_PlayerState)		RecvPropInt		(RECVINFO(deadflag)),	END_RECV_TABLE()BEGIN_RECV_TABLE_NOBASE( CPlayerLocalData, DT_Local )	RecvPropArray3( RECVINFO_ARRAY(m_chAreaBits), RecvPropInt(RECVINFO(m_chAreaBits[0]))),	RecvPropArray3( RECVINFO_ARRAY(m_chAreaPortalBits), RecvPropInt(RECVINFO(m_chAreaPortalBits[0]))),	RecvPropInt(RECVINFO(m_iHideHUD)),	// View		RecvPropFloat(RECVINFO(m_flFOVRate)),		RecvPropInt		(RECVINFO(m_bDucked)),	RecvPropInt		(RECVINFO(m_bDucking)),	RecvPropInt		(RECVINFO(m_bInDuckJump)),	RecvPropFloat	(RECVINFO(m_flDucktime)),	RecvPropFloat	(RECVINFO(m_flDuckJumpTime)),	RecvPropFloat	(RECVINFO(m_flJumpTime)),	RecvPropFloat	(RECVINFO(m_flFallVelocity)),//	RecvPropInt		(RECVINFO(m_nOldButtons)),	RecvPropVector	(RECVINFO(m_vecPunchAngle)),	RecvPropVector	(RECVINFO(m_vecPunchAngleVel)),	RecvPropInt		(RECVINFO(m_bDrawViewmodel)),	RecvPropInt		(RECVINFO(m_bWearingSuit)),	RecvPropBool	(RECVINFO(m_bPoisoned)),	RecvPropFloat	(RECVINFO(m_flStepSize)),	RecvPropInt		(RECVINFO(m_bAllowAutoMovement)),		// 3d skybox data	RecvPropInt(RECVINFO(m_skybox3d.scale)),	RecvPropVector(RECVINFO(m_skybox3d.origin)),	RecvPropInt(RECVINFO(m_skybox3d.area)),	// 3d skybox fog data	RecvPropInt( RECVINFO( m_skybox3d.fog.enable ) ),	RecvPropInt( RECVINFO( m_skybox3d.fog.blend ) ),	RecvPropVector( RECVINFO( m_skybox3d.fog.dirPrimary ) ),	RecvPropInt( RECVINFO( m_skybox3d.fog.colorPrimary ) ),	RecvPropInt( RECVINFO( m_skybox3d.fog.colorSecondary ) ),	RecvPropFloat( RECVINFO( m_skybox3d.fog.start ) ),	RecvPropFloat( RECVINFO( m_skybox3d.fog.end ) ),	// fog data	RecvPropInt( RECVINFO( m_fog.enable ) ),	RecvPropInt( RECVINFO( m_fog.blend ) ),	RecvPropVector( RECVINFO( m_fog.dirPrimary ) ),	RecvPropInt( RECVINFO( m_fog.colorPrimary ) ),	RecvPropInt( RECVINFO( m_fog.colorSecondary ) ),	RecvPropFloat( RECVINFO( m_fog.start ) ),	RecvPropFloat( RECVINFO( m_fog.end ) ),	RecvPropFloat( RECVINFO( m_fog.farz ) ),	RecvPropInt( RECVINFO( m_fog.colorPrimaryLerpTo ) ),	RecvPropInt( RECVINFO( m_fog.colorSecondaryLerpTo ) ),	RecvPropFloat( RECVINFO( m_fog.startLerpTo ) ),	RecvPropFloat( RECVINFO( m_fog.endLerpTo ) ),	RecvPropFloat( RECVINFO( m_fog.lerptime ) ),	RecvPropFloat( RECVINFO( m_fog.duration ) ),	// audio data	RecvPropVector( RECVINFO( m_audio.localSound[0] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[1] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[2] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[3] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[4] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[5] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[6] ) ),	RecvPropVector( RECVINFO( m_audio.localSound[7] ) ),	RecvPropInt( RECVINFO( m_audio.soundscapeIndex ) ),	RecvPropInt( RECVINFO( m_audio.localBits ) ),	RecvPropEHandle( RECVINFO( m_audio.ent ) ),END_RECV_TABLE()// -------------------------------------------------------------------------------- //// This data only gets sent to clients that ARE this player entity.// -------------------------------------------------------------------------------- //	BEGIN_RECV_TABLE_NOBASE( C_BasePlayer, DT_LocalPlayerExclusive )		RecvPropDataTable	( RECVINFO_DT(m_Local),0, &REFERENCE_RECV_TABLE(DT_Local) ),		RecvPropFloat		( RECVINFO(m_vecViewOffset[0]) ),		RecvPropFloat		( RECVINFO(m_vecViewOffset[1]) ),		RecvPropFloat		( RECVINFO(m_vecViewOffset[2]) ),		RecvPropFloat		( RECVINFO(m_flFriction) ),		RecvPropArray3		( RECVINFO_ARRAY(m_iAmmo), RecvPropInt( RECVINFO(m_iAmmo[0])) ),				RecvPropInt			( RECVINFO(m_fOnTarget) ),		RecvPropInt			( RECVINFO( m_nTickBase ) ),		RecvPropInt			( RECVINFO( m_nNextThinkTick ) ),		RecvPropInt		( RECVINFO( m_iPlayerClass )),		RecvPropEHandle		( RECVINFO( m_hLastWeapon ) ),		RecvPropEHandle		( RECVINFO( m_hGroundEntity ) ), 		RecvPropFloat		( RECVINFO(m_vecVelocity[0]), 0, RecvProxy_LocalVelocityX ), 		RecvPropFloat		( RECVINFO(m_vecVelocity[1]), 0, RecvProxy_LocalVelocityY ), 		RecvPropFloat		( RECVINFO(m_vecVelocity[2]), 0, RecvProxy_LocalVelocityZ ),		RecvPropVector		( RECVINFO( m_vecBaseVelocity ) ),		RecvPropEHandle		( RECVINFO( m_hConstraintEntity)),		RecvPropVector		( RECVINFO( m_vecConstraintCenter) ),		RecvPropFloat		( RECVINFO( m_flConstraintRadius )),		RecvPropFloat		( RECVINFO( m_flConstraintWidth )),		RecvPropFloat		( RECVINFO( m_flConstraintSpeedFactor )),		RecvPropFloat		( RECVINFO( m_flDeathTime )),		RecvPropInt			( RECVINFO( m_nWaterLevel ) ),		RecvPropFloat		( RECVINFO( m_flLaggedMovementValue )),			END_RECV_TABLE()	// -------------------------------------------------------------------------------- //// DT_BasePlayer datatable.// -------------------------------------------------------------------------------- //	IMPLEMENT_CLIENTCLASS_DT(C_BasePlayer, DT_BasePlayer, CBasePlayer)		// We have both the local and nonlocal data in here, but the server proxies		// only send one.		RecvPropDataTable( "localdata", 0, 0, &REFERENCE_RECV_TABLE(DT_LocalPlayerExclusive) ),		RecvPropDataTable(RECVINFO_DT(pl), 0, &REFERENCE_RECV_TABLE(DT_PlayerState), DataTableRecvProxy_StaticDataTable),		RecvPropInt		(RECVINFO(m_iFOV), 0, RecvProxy_FOV),		RecvPropInt		(RECVINFO(m_iDefaultFOV), 0, RecvProxy_DefaultFOV),		RecvPropEHandle( RECVINFO(m_hVehicle) ),		RecvPropEHandle( RECVINFO(m_hUseEntity) ),		RecvPropInt		(RECVINFO(m_iHealth)),		RecvPropInt		(RECVINFO(m_lifeState)),		RecvPropFloat	(RECVINFO(m_flMaxspeed)),		RecvPropInt		(RECVINFO(m_fFlags)),		RecvPropInt		(RECVINFO(m_iObserverMode) ),		RecvPropEHandle	(RECVINFO(m_hObserverTarget), RecvProxy_ObserverTarget ),		RecvPropArray	( RecvPropEHandle( RECVINFO( m_hViewModel[0] ) ), m_hViewModel ),				RecvPropString( RECVINFO(m_szLastPlaceName) ),	END_RECV_TABLE()BEGIN_PREDICTION_DATA_NO_BASE( CPlayerState )	DEFINE_PRED_FIELD(  deadflag, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	// DEFINE_FIELD( netname, string_t ),	// DEFINE_FIELD( fixangle, FIELD_INTEGER ),	// DEFINE_FIELD( anglechange, FIELD_FLOAT ),	// DEFINE_FIELD( v_angle, FIELD_VECTOR ),END_PREDICTION_DATA()	BEGIN_PREDICTION_DATA_NO_BASE( CPlayerLocalData )	// DEFINE_PRED_TYPEDESCRIPTION( m_skybox3d, sky3dparams_t ),	// DEFINE_PRED_TYPEDESCRIPTION( m_fog, fogparams_t ),	// DEFINE_PRED_TYPEDESCRIPTION( m_audio, audioparams_t ),	DEFINE_FIELD( m_nStepside, FIELD_INTEGER ),	DEFINE_PRED_FIELD( m_iHideHUD, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD_TOL( m_vecPunchAngle, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.125f ),	DEFINE_PRED_FIELD_TOL( m_vecPunchAngleVel, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.125f ),	DEFINE_PRED_FIELD( m_bDrawViewmodel, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_bWearingSuit, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_bPoisoned, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_bAllowAutoMovement, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_bDucked, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_bDucking, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_bInDuckJump, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_flDucktime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_flDuckJumpTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_flJumpTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD_TOL( m_flFallVelocity, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, 0.5f ),//	DEFINE_PRED_FIELD( m_nOldButtons, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),	DEFINE_FIELD( m_nOldButtons, FIELD_INTEGER ),	DEFINE_PRED_FIELD( m_flStepSize, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),END_PREDICTION_DATA()	BEGIN_PREDICTION_DATA( C_BasePlayer )	DEFINE_PRED_TYPEDESCRIPTION( m_Local, CPlayerLocalData ),	DEFINE_PRED_TYPEDESCRIPTION( pl, CPlayerState ),	DEFINE_PRED_FIELD( m_iFOV, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_hVehicle, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD_TOL( m_flMaxspeed, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, 0.5f ),	DEFINE_PRED_FIELD( m_iHealth, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_fOnTarget, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_nNextThinkTick, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_lifeState, FIELD_CHARACTER, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_nWaterLevel, FIELD_CHARACTER, FTYPEDESC_INSENDTABLE ),		DEFINE_PRED_FIELD_TOL( m_vecBaseVelocity, FIELD_VECTOR, FTYPEDESC_INSENDTABLE, 0.05 ),	DEFINE_FIELD( m_nButtons, FIELD_INTEGER ),	DEFINE_FIELD( m_flWaterJumpTime, FIELD_FLOAT ),	DEFINE_FIELD( m_nImpulse, FIELD_INTEGER ),	DEFINE_FIELD( m_flStepSoundTime, FIELD_FLOAT ),	DEFINE_FIELD( m_flSwimSoundTime, FIELD_FLOAT ),	DEFINE_FIELD( m_vecLadderNormal, FIELD_VECTOR ),	DEFINE_FIELD( m_flPhysics, FIELD_INTEGER ),	DEFINE_AUTO_ARRAY( m_szAnimExtension, FIELD_CHARACTER ),	DEFINE_FIELD( m_afButtonLast, FIELD_INTEGER ),	DEFINE_FIELD( m_afButtonPressed, FIELD_INTEGER ),	DEFINE_FIELD( m_afButtonReleased, FIELD_INTEGER ),	// DEFINE_FIELD( m_vecOldViewAngles, FIELD_VECTOR ),	// DEFINE_ARRAY( m_iOldAmmo, FIELD_INTEGER,  MAX_AMMO_TYPES ),	//DEFINE_FIELD( m_hOldVehicle, FIELD_EHANDLE ),	// DEFINE_FIELD( m_pModelLight, dlight_t* ),	// DEFINE_FIELD( m_pEnvironmentLight, dlight_t* ),	// DEFINE_FIELD( m_pBrightLight, dlight_t* ),	DEFINE_PRED_FIELD( m_hLastWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_nTickBase, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_FIELD( m_hGroundEntity, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),	DEFINE_PRED_ARRAY( m_hViewModel, FIELD_EHANDLE, MAX_VIEWMODELS, FTYPEDESC_INSENDTABLE ),END_PREDICTION_DATA()LINK_ENTITY_TO_CLASS( player, C_BasePlayer );// -------------------------------------------------------------------------------- //// Functions.// -------------------------------------------------------------------------------- //C_BasePlayer::C_BasePlayer() : m_iv_vecViewOffset( "C_BasePlayer::m_iv_vecViewOffset" ){	AddVar( &m_vecViewOffset, &m_iv_vecViewOffset, LATCH_SIMULATION_VAR );	#ifdef _DEBUG																	m_vecLadderNormal.Init();	m_vecOldViewAngles.Init();#endif	m_pFlashlight = NULL;	m_pCurrentVguiScreen = NULL;	m_pCurrentCommand = NULL;	m_flPredictionErrorTime = -100;	m_StuckLast = 0;	m_bWasFrozen = false;	m_bResampleWaterSurface = true;		ResetObserverMode();	m_vecPredictionError.Init();	m_flPredictionErrorTime = 0;	m_surfaceProps = 0;	m_pSurfaceData = NULL;	m_surfaceFriction = 1.0f;	m_chTextureType = 0;}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------C_BasePlayer::~C_BasePlayer(){	DeactivateVguiScreen( m_pCurrentVguiScreen.Get() );	if ( this == s_pLocalPlayer )	{		s_pLocalPlayer = NULL;	}	if (m_pFlashlight)	{		delete m_pFlashlight;	}}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void C_BasePlayer::Spawn( void ){	// Clear all flags except for FL_FULLEDICT	ClearFlags();	AddFlag( FL_CLIENT );	int effects = GetEffects() & EF_NOSHADOW;	SetEffects( effects );	m_iFOV	= 0;	// init field of view.    SetModel( "models/player.mdl" );	Precache();	SetThink(NULL);	SharedSpawn();}////void C_BasePlayer::GetPlayerClass( void )//{//return m_iPlayerClass;//}void C_BasePlayer::SetPlayerClass( int newcls ){m_iPlayerClass = newcls;}bool C_BasePlayer::IsHLTV() const{	return ( IsLocalPlayer() && engine->IsHLTV() );	}CBaseEntity	*C_BasePlayer::GetObserverTarget() const	// returns players targer or NULL{#ifndef _XBOX	if ( IsHLTV() )	{		return HLTVCamera()->GetPrimaryTarget();	}#endif		if ( GetObserverMode() == OBS_MODE_ROAMING )	{		return NULL;	// no target in roaming mode	}	else	{		return m_hObserverTarget;	}}// Called from Recv Proxy, mainly to reset tone map scalevoid C_BasePlayer::SetObserverTarget( EHANDLE hObserverTarget ){	// If the observer target is changing to an entity that the client doesn't know about yet,	// it can resolve to NULL.  If the client didn't have an observer target before, then	// comparing EHANDLEs directly will see them as equal, since it uses Get(), and compares	// NULL to NULL.  To combat this, we need to check against GetEntryIndex() and	// GetSerialNumber().	if ( hObserverTarget.GetEntryIndex() != m_hObserverTarget.GetEntryIndex() ||		hObserverTarget.GetSerialNumber() != m_hObserverTarget.GetSerialNumber())	{		// Init based on the new handle's entry index and serial number, so that it's Get()		// has a chance to become non-NULL even if it currently resolves to NULL.		m_hObserverTarget.Init( hObserverTarget.GetEntryIndex(), hObserverTarget.GetSerialNumber() );		if ( IsLocalPlayer() )		{			ResetToneMapping(1.0);		}	}}int C_BasePlayer::GetObserverMode() const { #ifndef _XBOX	if ( IsHLTV() )	{		return HLTVCamera()->GetMode();	}#endif	return m_iObserverMode; }bool C_BasePlayer::ViewModel_IsTransparent( void ){	return IsTransparent();}//-----------------------------------------------------------------------------// Used by prediction, sets the view angles for the player//-----------------------------------------------------------------------------void C_BasePlayer::SetLocalViewAngles( const QAngle &viewAngles ){	pl.v_angle = viewAngles;}surfacedata_t* C_BasePlayer::GetGroundSurface(){	//	// Find the name of the material that lies beneath the player.	//	Vector start, end;	VectorCopy( GetAbsOrigin(), start );	VectorCopy( start, end );	// Straight down	end.z -= 64;	// Fill in default values, just in case.		Ray_t ray;	ray.Init( start, end, GetPlayerMins(), GetPlayerMaxs() );	trace_t	trace;	UTIL_TraceRay( ray, MASK_PLAYERSOLID_BRUSHONLY, this, COLLISION_GROUP_PLAYER_MOVEMENT, &trace );	if ( trace.fraction == 1.0f )		return NULL;	// no ground		return physprops->GetSurfaceData( trace.surface.surfaceProps );}//-----------------------------------------------------------------------------// returns the player name//-----------------------------------------------------------------------------const char * C_BasePlayer::GetPlayerName(){	return g_PR ? g_PR->GetPlayerName( entindex() ) : "";}//-----------------------------------------------------------------------------// Is the player dead?//-----------------------------------------------------------------------------bool C_BasePlayer::IsPlayerDead(){	return pl.deadflag == true;}//-----------------------------------------------------------------------------// Purpose://-----------------------------------------------------------------------------void C_BasePlayer::SetVehicleRole( int nRole ){	if ( !IsInAVehicle() )		return;	// HL2 has only a player in a vehicle.	if ( nRole > VEHICLE_ROLE_DRIVER )		return;	char szCmd[64];	Q_snprintf( szCmd, sizeof( szCmd ), "vehicleRole %i\n", nRole );	engine->ServerCmd( szCmd );}//-----------------------------------------------------------------------------// Purpose: Store original ammo data to see what has changed// Input  : bnewentity - //-----------------------------------------------------------------------------void C_BasePlayer::OnPreDataChanged( DataUpdateType_t updateType ){	for (int i = 0; i < MAX_AMMO_TYPES; ++i)	{		m_iOldAmmo[i] = GetAmmoCount(i);	}	BaseClass::OnPreDataChanged( updateType );}//-----------------------------------------------------------------------------// Purpose: // Input  : updateType - //-----------------------------------------------------------------------------void C_BasePlayer::PostDataUpdate( DataUpdateType_t updateType ){	// This has to occur here as opposed to OnDataChanged so that EHandles to the player created	//  on this same frame are not stomped because prediction thinks there	//  isn't a local player yet!!!	if ( updateType == DATA_UPDATE_CREATED )	{		// Make sure s_pLocalPlayer is correct		int iLocalPlayerIndex = engine->GetLocalPlayer();		if ( g_nKillCamMode )			iLocalPlayerIndex = g_nKillCamTarget1;		if ( iLocalPlayerIndex == index )		{			Assert( s_pLocalPlayer == NULL );			s_pLocalPlayer = this;		}	}	if ( IsLocalPlayer() )	{		SetSimulatedEveryTick( true );	}	else	{		SetSimulatedEveryTick( false );		// estimate velocity for non local players		float flTimeDelta = m_flSimulationTime - m_flOldSimulationTime;		if ( flTimeDelta > 0  && !IsEffectActive(EF_NOINTERP) )		{			Vector newVelo = (GetNetworkOrigin() - GetOldOrigin()  ) / flTimeDelta;			SetAbsVelocity( newVelo);		}	}	BaseClass::PostDataUpdate( updateType );	// Only care about this for local player	if ( IsLocalPlayer() )	{		default_fov.SetValue( m_iDefaultFOV );		//Update our FOV, including any zooms going on		int iDefaultFOV = default_fov.GetInt();		int	localFOV	= GetFOV();		int min_fov		= GetMinFOV();		// Don't let it go too low		localFOV = max( min_fov, localFOV );		gHUD.m_flFOVSensitivityAdjust = 1.0f;#ifndef _XBOX		if ( gHUD.m_flMouseSensitivityFactor )		{			gHUD.m_flMouseSensitivity = sensitivity.GetFloat() * gHUD.m_flMouseSensitivityFactor;		}		else#endif		{			// No override, don't use huge sensitivity			if ( localFOV == iDefaultFOV )			{#ifndef _XBOX				// reset to saved sensitivity				gHUD.m_flMouseSensitivity = 0;#endif			}			else			{  				// Set a new sensitivity that is proportional to the change from the FOV default and scaled				//  by a separate compensating factor				gHUD.m_flFOVSensitivityAdjust = 					((float)localFOV / (float)iDefaultFOV) * // linear fov downscale					zoom_sensitivity_ratio.GetFloat(); // sensitivity scale factor#ifndef _XBOX				gHUD.m_flMouseSensitivity = gHUD.m_flFOVSensitivityAdjust * sensitivity.GetFloat(); // regular sensitivity#endif			}		}		if ( updateType == DATA_UPDATE_CREATED )		{			QAngle angles;			engine->GetViewAngles( angles );			SetLocalViewAngles( angles );			m_flOldPlayerZ = GetLocalOrigin().z;		}	}	// If we are updated while paused, allow the player origin to be snapped by the	//  server if we receive a packet from the server	if ( engine->IsPaused() )	{		ResetLatched();	}}void C_BasePlayer::ReceiveMessage( int classID, bf_read &msg ){	if ( classID != GetClientClass()->m_ClassID )	{		// message is for subclass		BaseClass::ReceiveMessage( classID, msg );		return;	}	int messageType = msg.ReadByte();	switch( messageType )	{		case PLAY_PLAYER_JINGLE:			PlayPlayerJingle();			break;	}}void C_BasePlayer::OnRestore(){	BaseClass::OnRestore();	if ( IsLocalPlayer() )	{		// debounce the attack key, for if it was used for restore		input->ClearInputButton( IN_ATTACK | IN_ATTACK2 );		// GetButtonBits() has to be called for the above to take effect		input->GetButtonBits( 0 );	}	// For ammo history icons to current value so they don't flash on level transtions	for ( int i = 0; i < MAX_AMMO_TYPES; i++ )	{		m_iOldAmmo[i] = GetAmmoCount(i);	}}//-----------------------------------------------------------------------------// Purpose: Process incoming data//-----------------------------------------------------------------------------void C_BasePlayer::OnDataChanged( DataUpdateType_t updateType ){#if !defined( NO_ENTITY_PREDICTION )	if ( IsLocalPlayer() )	{		SetPredictionEligible( true );	}#endif	BaseClass::OnDataChanged( updateType );	// Only care about this for local player	if ( IsLocalPlayer() )	{		// Reset engine areabits pointer		render->SetAreaState( m_Local.m_chAreaBits, m_Local.m_chAreaPortalBits );		// Check for Ammo pickups.		for ( int i = 0; i < MAX_AMMO_TYPES; i++ )		{			if ( GetAmmoCount(i) > m_iOldAmmo[i] )			{				// Don't add to ammo pickup if the ammo doesn't do it				const FileWeaponInfo_t *pWeaponData = gWR.GetWeaponFromAmmo(i);				if ( !pWeaponData || !( pWeaponData->iFlags & ITEM_FLAG_NOAMMOPICKUPS ) )				{					// We got more ammo for this ammo index. Add it to the ammo history					CHudHistoryResource *pHudHR = GET_HUDELEMENT( CHudHistoryResource );					if( pHudHR )					{						pHudHR->AddToHistory( HISTSLOT_AMMO, i, abs(GetAmmoCount(i) - m_iOldAmmo[i]) );					}				}			}		}		Soundscape_Update( m_Local.m_audio );	}}//-----------------------------------------------------------------------------// Did we just enter a vehicle this frame?//-----------------------------------------------------------------------------bool C_BasePlayer::JustEnteredVehicle(){	if ( !IsInAVehicle() )		return false;	return ( m_hOldVehicle == m_hVehicle );}//-----------------------------------------------------------------------------// Are we in VGUI input mode?.//-----------------------------------------------------------------------------bool C_BasePlayer::IsInVGuiInputMode() const{	return (m_pCurrentVguiScreen.Get() != NULL);}//-----------------------------------------------------------------------------// Check to see if we're in vgui input mode...//-----------------------------------------------------------------------------void C_BasePlayer::DetermineVguiInputMode( CUserCmd *pCmd ){	// If we're dead, close down and abort!	if ( !IsAlive() )	{		DeactivateVguiScreen( m_pCurrentVguiScreen.Get() );		m_pCurrentVguiScreen.Set( NULL );		return;	}	// If we're in vgui mode *and* we're holding down mouse buttons,	// stay in vgui mode even if we're outside the screen bounds	if (m_pCurrentVguiScreen.Get() && (pCmd->buttons & (IN_ATTACK | IN_ATTACK2)) )	{		SetVGuiScreenButtonState( m_pCurrentVguiScreen.Get(), pCmd->buttons );		// Kill all attack inputs if we're in vgui screen mode		pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);		return;	}	// We're not in vgui input mode if we're moving, or have hit a key	// that will make us move...	// Not in vgui mode if we're moving too quickly	// ROBIN: Disabled movement preventing VGUI screen usage	//if (GetVelocity().LengthSqr() > MAX_VGUI_INPUT_MODE_SPEED_SQ)	if ( 0 )	{		DeactivateVguiScreen( m_pCurrentVguiScreen.Get() );		m_pCurrentVguiScreen.Set( NULL );		return;	}	// Don't enter vgui mode if we've got combat buttons held down	bool bAttacking = false;	if ( ((pCmd->buttons & IN_ATTACK) || (pCmd->buttons & IN_ATTACK2)) && !m_pCurrentVguiScreen.Get() )	{		bAttacking = true;	}	// Not in vgui mode if we're pushing any movement key at all	// Not in vgui mode if we're in a vehicle...	// ROBIN: Disabled movement preventing VGUI screen usage	//if ((pCmd->forwardmove > MAX_VGUI_INPUT_MODE_SPEED) ||	//	(pCmd->sidemove > MAX_VGUI_INPUT_MODE_SPEED) ||	//	(pCmd->upmove > MAX_VGUI_INPUT_MODE_SPEED) ||	//	(pCmd->buttons & IN_JUMP) ||	//	(bAttacking) )	if ( bAttacking || IsInAVehicle() )	{ 		DeactivateVguiScreen( m_pCurrentVguiScreen.Get() );		m_pCurrentVguiScreen.Set( NULL );		return;	}	// Not in vgui mode if there are no nearby screens	C_BaseEntity *pOldScreen = m_pCurrentVguiScreen.Get();	m_pCurrentVguiScreen = FindNearbyVguiScreen( EyePosition(), pCmd->viewangles, GetTeamNumber() );	if (pOldScreen != m_pCurrentVguiScreen)	{		DeactivateVguiScreen( pOldScreen );		ActivateVguiScreen( m_pCurrentVguiScreen.Get() );	}	if (m_pCurrentVguiScreen.Get())	{		SetVGuiScreenButtonState( m_pCurrentVguiScreen.Get(), pCmd->buttons );		// Kill all attack inputs if we're in vgui screen mode		pCmd->buttons &= ~(IN_ATTACK | IN_ATTACK2);	}}//-----------------------------------------------------------------------------// Purpose: Input handling//-----------------------------------------------------------------------------void C_BasePlayer::CreateMove( float flInputSampleTime, CUserCmd *pCmd ){	// Allow the vehicle to clamp the view angles	if ( IsInAVehicle() )	{		IClientVehicle *pVehicle = m_hVehicle.Get()->GetClientVehicle();		if ( pVehicle )		{			pVehicle->UpdateViewAngles( this, pCmd );			engine->SetViewAngles( pCmd->viewangles );		}	}	else 	{#ifndef _XBOX		if ( joy_autosprint.GetBool() )#endif		{			if ( input->KeyState( &in_joyspeed ) != 0.0f )			{				pCmd->buttons |= IN_SPEED;			}		}		CBaseCombatWeapon *pWeapon = GetActiveWeapon();		if ( pWeapon )		{			pWeapon->CreateMove( flInputSampleTime, pCmd, m_vecOldViewAngles );		}	}	// If the frozen flag is set, prevent view movement (server prevents the rest of the movement)	if ( GetFlags() & FL_FROZEN )	{		// Don't stomp the first time we get frozen		if ( m_bWasFrozen )		{			// Stomp the new viewangles with old ones			pCmd->viewangles = m_vecOldViewAngles;			engine->SetViewAngles( pCmd->viewangles );		}		else		{			m_bWasFrozen = true;		}	}	else	{		m_bWasFrozen = false;	}	m_vecOldViewAngles = pCmd->viewangles;		// Check to see if we're in vgui input mode...	DetermineVguiInputMode( pCmd );}//-----------------------------------------------------------------------------// Purpose: Player has changed to a new team//-----------------------------------------------------------------------------void C_BasePlayer::TeamChange( int iNewTeam ){	// Base class does nothing}//-----------------------------------------------------------------------------// Purpose: Creates, destroys, and updates the flashlight effect as needed.//-----------------------------------------------------------------------------void C_BasePlayer::UpdateFlashlight(){	// The dim light is the flashlight.	if ( IsEffectActive( EF_DIMLIGHT ) )	{		if (!m_pFlashlight)		{			// Turned on the headlight; create it.			m_pFlashlight = new CFlashlightEffect(index);			if (!m_pFlashlight)				return;			m_pFlashlight->TurnOn();		}		Vector vecForward, vecRight, vecUp;		EyeVectors( &vecForward, &vecRight, &vecUp );		// Update the light with the new position and direction.				m_pFlashlight->UpdateLight( EyePosition(), vecForward, vecRight, vecUp, FLASHLIGHT_DISTANCE );	}	else if (m_pFlashlight)	{		// Turned off the flashlight; delete it.		delete m_pFlashlight;		m_pFlashlight = NULL;	}}//-----------------------------------------------------------------------------// Purpose: Creates player flashlight if it's ative//-----------------------------------------------------------------------------void C_BasePlayer::Flashlight( void ){	UpdateFlashlight();	// Check for muzzle flash and apply to view model	C_BaseAnimating *ve = this;	if ( GetObserverMode() == OBS_MODE_IN_EYE )	{		ve = dynamic_cast< C_BaseAnimating* >( GetObserverTarget() );	}}//-----------------------------------------------------------------------------// Purpose: Engine is asking whether to add this player to the visible entities list//-----------------------------------------------------------------------------void C_BasePlayer::AddEntity( void ){	// FIXME/UNDONE:  Should the local player say yes to adding itself now 	// and then, when it ges time to render and it shouldn't still do the render with	// STUDIO_EVENTS set so that its attachment points will get updated even if not	// in third person?	// Add in water effects	if ( IsLocalPlayer() )	{		CreateWaterEffects();	}	// If set to invisible, skip. Do this before resetting the entity pointer so it has 	// valid data to decide whether it's visible.	if ( !IsVisible() || !g_pClientMode->ShouldDrawLocalPlayer( this ) )	{		return;	}	// Server says don't interpolate this frame, so set previous info to new info.	if ( IsEffectActive(EF_NOINTERP) || 		Teleported() )	{		ResetLatched();	}	// Add in lighting effects	CreateLightEffects();}extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz );//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void C_BasePlayer::CreateWaterEffects( void ){	// Must be completely submerged to bother	if ( GetWaterLevel() < 3 )	{		m_bResampleWaterSurface = true;		return;	}	// Do special setup if this is our first time back underwater	if ( m_bResampleWaterSurface )	{		// Reset our particle timer		m_tWaterParticleTimer.Init( 32 );				// Find the surface of the water to clip against		m_flWaterSurfaceZ = UTIL_WaterLevel( WorldSpaceCenter(), WorldSpaceCenter().z, WorldSpaceCenter().z + 256 );		m_bResampleWaterSurface = false;	}	// Make sure the emitter is setup	if ( m_pWaterEmitter == NULL )	{		if ( ( m_pWaterEmitter = WaterDebrisEffect::Create( "splish" ) ) == NULL )			return;	}	Vector vecVelocity;	GetVectors( &vecVelocity, NULL, NULL );	Vector offset = WorldSpaceCenter();	m_pWaterEmitter->SetSortOrigin( offset );	PMaterialHandle	hMaterial[2];	hMaterial[0] = ParticleMgr()->GetPMaterial( "effects/fleck_cement1" );	hMaterial[1] = ParticleMgr()->GetPMaterial( "effects/fleck_cement2" );	SimpleParticle	*pParticle;	float curTime = gpGlobals->frametime;	// Add as many particles as we need	while ( m_tWaterParticleTimer.NextEvent( curTime ) )	{		offset = WorldSpaceCenter() + ( vecVelocity * 128.0f ) + RandomVector( -128, 128 );		// Make sure we don't start out of the water!		if ( offset.z > m_flWaterSurfaceZ )		{			offset.z = ( m_flWaterSurfaceZ - 8.0f );		}		pParticle = (SimpleParticle *) m_pWaterEmitter->AddParticle( sizeof(SimpleParticle), hMaterial[random->RandomInt(0,1)], offset );		if (pParticle == NULL)			continue;		pParticle->m_flLifetime	= 0.0f;		pParticle->m_flDieTime	= random->RandomFloat( 2.0f, 4.0f );		pParticle->m_vecVelocity = RandomVector( -2.0f, 2.0f );		//FIXME: We should tint these based on the water's fog value!		float color = random->RandomInt( 32, 128 );		pParticle->m_uchColor[0] = color;		pParticle->m_uchColor[1] = color;		pParticle->m_uchColor[2] = color;		pParticle->m_uchStartSize	= 1;		pParticle->m_uchEndSize		= 1;				pParticle->m_uchStartAlpha	= 255;		pParticle->m_uchEndAlpha	= 0;				pParticle->m_flRoll			= random->RandomInt( 0, 360 );		pParticle->m_flRollDelta	= random->RandomFloat( -0.5f, 0.5f );	}}//-----------------------------------------------------------------------------// Called when not in tactical mode. Allows view to be overriden for things like driving a tank.//-----------------------------------------------------------------------------void C_BasePlayer::OverrideView( CViewSetup *pSetup ){}bool C_BasePlayer::ShouldInterpolate(){	// always interpolate myself	if ( IsLocalPlayer() )		return true;#ifndef _XBOX	// always interpolate entity if followed by HLTV	if ( HLTVCamera()->GetCameraMan() == this )		return true;#endif	return BaseClass::ShouldInterpolate();}bool C_BasePlayer::ShouldDraw(){	return ( !IsLocalPlayer() || C_BasePlayer::ShouldDrawLocalPlayer() || (GetObserverMode() == OBS_MODE_DEATHCAM ) ) &&		   BaseClass::ShouldDraw();}int C_BasePlayer::DrawModel( int flags ){	// if local player is spectating this player in first person mode, don't draw it	C_BasePlayer * player = C_BasePlayer::GetLocalPlayer();	if ( player && player->IsObserver() )	{		if ( player->GetObserverMode() == OBS_MODE_IN_EYE &&			 player->GetObserverTarget() == this )			return 0;	}	return BaseClass::DrawModel( flags );}void C_BasePlayer::CalcChaseCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov){	C_BaseEntity *target = GetObserverTarget();	if ( !target ) 	{		// just copy a save in-map position		VectorCopy( EyePosition(), eyeOrigin );		VectorCopy( EyeAngles(), eyeAngles );		return;	};	// QAngle tmpangles;	Vector forward, viewpoint;	// GetRenderOrigin() returns ragdoll pos if player is ragdolled	Vector origin = target->GetRenderOrigin();	C_BasePlayer *player = ToBasePlayer( target );		if ( player && player->IsAlive() )	{		if( player->GetFlags() & FL_DUCKING )		{			VectorAdd( origin, VEC_DUCK_VIEW, origin );		}		else		{			VectorAdd( origin, VEC_VIEW, origin );		}	}	else	{		// assume it's the players ragdoll		VectorAdd( origin, VEC_DEAD_VIEWHEIGHT, origin );	}	QAngle viewangles;	if ( GetObserverMode() == OBS_MODE_IN_EYE )	{		viewangles = eyeAngles;	}	else if ( IsLocalPlayer() )	{		engine->GetViewAngles( viewangles );	}	else	{		viewangles = EyeAngles();	}	m_flObserverChaseDistance += gpGlobals->frametime*48.0f;	m_flObserverChaseDistance = clamp( m_flObserverChaseDistance, 16, CHASE_CAM_DISTANCE );		AngleVectors( viewangles, &forward );	VectorNormalize( forward );	VectorMA(origin, -m_flObserverChaseDistance, forward, viewpoint );	trace_t trace;	C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace	UTIL_TraceHull( origin, viewpoint, WALL_MIN, WALL_MAX, MASK_SOLID, target, COLLISION_GROUP_NONE, &trace );	C_BaseEntity::PopEnableAbsRecomputations();	if (trace.fraction < 1.0)	{		viewpoint = trace.endpos;		m_flObserverChaseDistance = VectorLength(origin - eyeOrigin);	}		VectorCopy( viewangles, eyeAngles );	VectorCopy( viewpoint, eyeOrigin );	fov = GetFOV();}void C_BasePlayer::CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov){	C_BaseEntity *target = GetObserverTarget();		if ( !target ) 	{		target = this;	}	m_flObserverChaseDistance = 0.0;	eyeOrigin = target->EyePosition();	eyeAngles = target->EyeAngles();		if ( spec_track.GetInt() > 0 )	{		C_BaseEntity *target =  ClientEntityList().GetBaseEntity( spec_track.GetInt() );		if ( target )		{			Vector v = target->GetAbsOrigin(); v.z += 54;			QAngle a; VectorAngles( v - eyeOrigin, a );			NormalizeAngles( a );			eyeAngles = a;			engine->SetViewAngles( a );		}	}	// Apply a smoothing offset to smooth out prediction errors.	Vector vSmoothOffset;	GetPredictionErrorSmoothingVector( vSmoothOffset );	eyeOrigin += vSmoothOffset;	fov = GetFOV();}void C_BasePlayer::CalcInEyeCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov){	C_BaseEntity *target = GetObserverTarget();	if ( !target ) 	{		// just copy a save in-map position		VectorCopy( EyePosition(), eyeOrigin );		VectorCopy( EyeAngles(), eyeAngles );		return;	};	if ( !target->IsAlive() )	{		// if dead, show from 3rd person		CalcChaseCamView( eyeOrigin, eyeAngles, fov );		return;	}	fov = GetFOV();	// TODO use tragets FOV	m_flObserverChaseDistance = 0.0;	eyeAngles = target->EyeAngles();	eyeOrigin = target->GetAbsOrigin();	// Apply punch angle	VectorAdd( eyeAngles, GetPunchAngle(), eyeAngles );	if( engine->IsHLTV() )	{		if ( target->GetFlags() & FL_DUCKING )		{			eyeOrigin += VEC_DUCK_VIEW;		}		else		{			eyeOrigin += VEC_VIEW;		}	}	else	{		Vector offset = m_vecViewOffset;#ifdef HL2MP		offset = target->GetViewOffset();#endif		eyeOrigin += offset; // hack hack	}	engine->SetViewAngles( eyeAngles );}void C_BasePlayer::CalcDeathCamView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov){	CBaseEntity	* pKiller = NULL; 	if ( mp_forcecamera.GetInt() == OBS_ALLOW_ALL )	{		// if mp_forcecamera is off let user see killer or look around		pKiller = GetObserverTarget();		eyeAngles = EyeAngles();	}	float interpolation = ( gpGlobals->curtime - m_flDeathTime ) / DEATH_ANIMATION_TIME;	interpolation = clamp( interpolation, 0.0f, 1.0f );	m_flObserverChaseDistance += gpGlobals->frametime*48.0f;	m_flObserverChaseDistance = clamp( m_flObserverChaseDistance, 16, CHASE_CAM_DISTANCE );	QAngle aForward = eyeAngles;	Vector origin = EyePosition();				IRagdoll *pRagdoll = GetRepresentativeRagdoll();	if ( pRagdoll )	{		origin = pRagdoll->GetRagdollOrigin();		origin.z += VEC_DEAD_VIEWHEIGHT.z; // look over ragdoll, not through	}		if ( pKiller && pKiller->IsPlayer() && (pKiller != this) ) 	{		Vector vKiller = pKiller->EyePosition() - origin;		QAngle aKiller; VectorAngles( vKiller, aKiller );		InterpolateAngles( aForward, aKiller, eyeAngles, interpolation );	};	Vector vForward; AngleVectors( eyeAngles, &vForward );	VectorNormalize( vForward );	VectorMA( origin, -m_flObserverChaseDistance, vForward, eyeOrigin );	trace_t trace; // clip against world	C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace	UTIL_TraceHull( origin, eyeOrigin, WALL_MIN, WALL_MAX, MASK_SOLID, this, COLLISION_GROUP_NONE, &trace );	C_BaseEntity::PopEnableAbsRecomputations();	if (trace.fraction < 1.0)	{		eyeOrigin = trace.endpos;		m_flObserverChaseDistance = VectorLength(origin - eyeOrigin);	}	fov = GetFOV();}//-----------------------------------------------------------------------------// Purpose: Return the weapon to have open the weapon selection on, based upon our currently active weapon//			Base class just uses the weapon that's currently active.//-----------------------------------------------------------------------------C_BaseCombatWeapon *C_BasePlayer::GetActiveWeaponForSelection( void ){	return GetActiveWeapon();}C_BaseAnimating* C_BasePlayer::GetRenderedWeaponModel(){	// Attach to either their weapon model or their view model.	if ( ShouldDrawLocalPlayer() || !IsLocalPlayer() )	{		return GetActiveWeapon();	}	else	{		return GetViewModel();	}}//-----------------------------------------------------------------------------// Purpose: Gets a pointer to the local player, if it exists yet.// Output : C_BasePlayer//-----------------------------------------------------------------------------C_BasePlayer *C_BasePlayer::GetLocalPlayer( void ){	return s_pLocalPlayer;}//-----------------------------------------------------------------------------// Purpose: single place to decide whether the local player should draw//-----------------------------------------------------------------------------bool C_BasePlayer::ShouldDrawLocalPlayer(){	return input->CAM_IsThirdPerson() || ( ToolsEnabled() && ToolFramework_IsThirdPersonCamera() );}//-----------------------------------------------------------------------------// Purpose: // Output : Returns true on success, false on failure.//-----------------------------------------------------------------------------bool C_BasePlayer::IsLocalPlayer( void ) const{	return ( GetLocalPlayer() == this );}int	C_BasePlayer::GetUserID( void ){	player_info_t pi;	if ( !engine->GetPlayerInfo( entindex(), &pi ) )		return -1;	return pi.userID;}// For weapon predictionvoid C_BasePlayer::SetAnimation( PLAYER_ANIM playerAnim ){	// FIXME}void C_BasePlayer::UpdateClientData( void ){	// Update all the items	for ( int i = 0; i < WeaponCount(); i++ )	{		if ( GetWeapon(i) )  // each item updates it's successors			GetWeapon(i)->UpdateClientData( this );	}}// Prediction stuffvoid C_BasePlayer::PreThink( void ){#if !defined( NO_ENTITY_PREDICTION )	ItemPreFrame();	UpdateClientData();	if (m_lifeState >= LIFE_DYING)		return;	//	// If we're not on the ground, we're falling. Update our falling velocity.	//	if ( !( GetFlags() & FL_ONGROUND ) )	{		m_Local.m_flFallVelocity = -GetAbsVelocity().z;	}#endif}void C_BasePlayer::PostThink( void ){#if !defined( NO_ENTITY_PREDICTION )	if ( IsAlive())	{		// do weapon stuff		ItemPostFrame();		if ( GetFlags() & FL_ONGROUND )		{					m_Local.m_flFallVelocity = 0;		}		// Don't allow bogus sequence on player		if ( GetSequence() == -1 )		{			SetSequence( 0 );		}		StudioFrameAdvance();	}	// Even if dead simulate entities	SimulatePlayerSimulatedEntities();#endif}//-----------------------------------------------------------------------------// Purpose: send various tool messages - viewoffset, and base class messages (flex and bones)//-----------------------------------------------------------------------------void C_BasePlayer::GetToolRecordingState( KeyValues *msg ){	if ( !ToolsEnabled() )		return;	VPROF_BUDGET( "C_BasePlayer::GetToolRecordingState", VPROF_BUDGETGROUP_TOOLS );	BaseClass::GetToolRecordingState( msg );	msg->SetInt( "baseplayer", 1 );	msg->SetInt( "localplayer", IsLocalPlayer() ? 1 : 0 );	msg->SetString( "playername", GetPlayerName() );	static CameraRecordingState_t state;	state.m_flFOV = GetFOV();	float flZNear = view->GetZNear();	float flZFar = view->GetZFar();	CalcView( state.m_vecEyePosition, state.m_vecEyeAngles, flZNear, flZFar, state.m_flFOV );	msg->SetPtr( "camera", &state );}//-----------------------------------------------------------------------------// Purpose: Simulate the player for this frame//-----------------------------------------------------------------------------void C_BasePlayer::Simulate(){	//Frame updates	if ( this == C_BasePlayer::GetLocalPlayer() )	{		//Update the flashlight		Flashlight();	}	else	{		// update step sounds for all other players		Vector vel;		EstimateAbsVelocity( vel );		UpdateStepSound( GetGroundSurface(), GetAbsOrigin(), vel );	}	BaseClass::Simulate();}//-----------------------------------------------------------------------------// Purpose: // Output : CBaseViewModel//-----------------------------------------------------------------------------C_BaseViewModel *C_BasePlayer::GetViewModel( int index /*= 0*/ ){	Assert( index >= 0 && index < MAX_VIEWMODELS );	C_BaseViewModel *vm = m_hViewModel[ index ];		if ( GetObserverMode() == OBS_MODE_IN_EYE )	{		C_BasePlayer *target =  ToBasePlayer( GetObserverTarget() );		if ( target && target != this )		{			vm = target->GetViewModel( index );		}	}	return vm;}C_BaseCombatWeapon	*C_BasePlayer::GetActiveWeapon( void ) const{	const C_BasePlayer *fromPlayer = this;	// if localplayer is in InEye spectator mode, return weapon on chased player	if ( (fromPlayer == GetLocalPlayer()) && ( GetObserverMode() == OBS_MODE_IN_EYE) )	{		C_BaseEntity *target =  GetObserverTarget();		if ( target && target->IsPlayer() )		{			fromPlayer = ToBasePlayer( target );		}	}	return fromPlayer->C_BaseCombatCharacter::GetActiveWeapon();}//=========================================================// Autoaim// set crosshair position to point to enemey//=========================================================Vector C_BasePlayer::GetAutoaimVector( float flScale ){	// Never autoaim a predicted weapon (for now)	Vector	forward;	AngleVectors( GetAbsAngles() + m_Local.m_vecPunchAngle, &forward );	return	forward;}void C_BasePlayer::PlayPlayerJingle(){#ifndef _XBOX	// Find player sound for shooter	player_info_t info;	engine->GetPlayerInfo( entindex(), &info );	if ( !cl_customsounds.GetBool() )		return;	// Doesn't have a jingle sound	 if ( !info.customFiles[1] )			return;	char soundhex[ 16 ];	Q_binarytohex( (byte *)&info.customFiles[1], sizeof( info.customFiles[1] ), soundhex, sizeof( soundhex ) );	// See if logo has been downloaded.	char fullsoundname[ 512 ];	Q_snprintf( fullsoundname, sizeof( fullsoundname ), "sound/temp/%s.wav", soundhex );	if ( !filesystem->FileExists( fullsoundname ) )	{		char custname[ 512 ];		Q_snprintf( custname, sizeof( custname ), "downloads/%s.dat", soundhex );		// it may have been downloaded but not copied under materials folder		if ( !filesystem->FileExists( custname ) )			return; // not downloaded yet		// copy from download folder to materials/temp folder		// this is done since material system can access only materials/*.vtf files		if ( !engine->CopyFile( custname, fullsoundname) )			return;	}	Q_snprintf( fullsoundname, sizeof( fullsoundname ), "temp/%s.wav", soundhex );	CLocalPlayerFilter filter;	EmitSound_t ep;	ep.m_nChannel = CHAN_VOICE;	ep.m_pSoundName =  fullsoundname;	ep.m_flVolume = VOL_NORM;	ep.m_SoundLevel = SNDLVL_NORM;	C_BaseEntity::EmitSound( filter, GetSoundSourceIndex(), ep );#endif}// Stuff for predictionvoid C_BasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeat){	// FIXME:  Do something here?}//-----------------------------------------------------------------------------// Purpose: //-----------------------------------------------------------------------------void C_BasePlayer::ResetAutoaim( void ){#if 0	if (m_vecAutoAim.x != 0 || m_vecAutoAim.y != 0)	{		m_vecAutoAim = QAngle( 0, 0, 0 );		engine->CrosshairAngle( edict(), 0, 0 );	}#endif	m_fOnTarget = false;}bool C_BasePlayer::ShouldPredict( void ){#if !defined( NO_ENTITY_PREDICTION )	// Do this before calling into baseclass so prediction data block gets allocated	if ( IsLocalPlayer() )	{		return true;	}#endif	return false;}//-----------------------------------------------------------------------------// Purpose: Special processing for player simulation// NOTE: Don't chain to BaseClass!!!!//-----------------------------------------------------------------------------void C_BasePlayer::PhysicsSimulate( void ){#if !defined( NO_ENTITY_PREDICTION )	VPROF( "C_BasePlayer::PhysicsSimulate" );	// If we've got a moveparent, we must simulate that first.	CBaseEntity *pMoveParent = GetMoveParent();	if (pMoveParent)	{		pMoveParent->PhysicsSimulate();	}	// Make sure not to simulate this guy twice per frame	if (m_nSimulationTick == gpGlobals->tickcount)		return;	m_nSimulationTick = gpGlobals->tickcount;	if ( !IsLocalPlayer() )		return;	C_CommandContext *ctx = GetCommandContext();	Assert( ctx );	Assert( ctx->needsprocessing );	if ( !ctx->needsprocessing )		return;	ctx->needsprocessing = false;	// Handle FL_FROZEN.	if(GetFlags() & FL_FROZEN)	{		ctx->cmd.forwardmove = 0;		ctx->cmd.sidemove = 0;		ctx->cmd.upmove = 0;		ctx->cmd.buttons = 0;		ctx->cmd.impulse = 0;		//VectorCopy ( pl.v_angle, ctx->cmd.viewangles );	}	// Run the next command	prediction->RunCommand( 		this, 		&ctx->cmd, 		MoveHelper() );#endif}const QAngle& C_BasePlayer::GetPunchAngle(){	return m_Local.m_vecPunchAngle.Get();}void C_BasePlayer::SetPunchAngle( const QAngle &angle ){	m_Local.m_vecPunchAngle = angle;}float C_BasePlayer::GetWaterJumpTime() const{	return m_flWaterJumpTime;}void C_BasePlayer::SetWaterJumpTime( float flWaterJumpTime ){	m_flWaterJumpTime = flWaterJumpTime;}float C_BasePlayer::GetSwimSoundTime() const{	return m_flSwimSoundTime;}void C_BasePlayer::SetSwimSoundTime( float flSwimSoundTime ){	m_flSwimSoundTime = flSwimSoundTime;}//-----------------------------------------------------------------------------// Purpose: Return true if this object can be +used by the player//-----------------------------------------------------------------------------bool C_BasePlayer::IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps ){	return false;}//-----------------------------------------------------------------------------// Purpose: // Output : float//-----------------------------------------------------------------------------float C_BasePlayer::GetFOV( void ){	if ( GetObserverMode() == OBS_MODE_IN_EYE )	{		C_BasePlayer *pTargetPlayer = dynamic_cast<C_BasePlayer*>( GetObserverTarget() );		if ( pTargetPlayer )		{			return pTargetPlayer->GetFOV();		}	}	float fFOV = m_iFOV;	// Allow our vehicle to override our FOV if it's currently at the default FOV.	IClientVehicle *pVehicle = GetVehicle();	if ( pVehicle && ( fFOV == 0 ) )	{		pVehicle->GetVehicleFOV( fFOV );	}	if ( fFOV == 0 )	{		fFOV = default_fov.GetInt();	}	//See if we need to lerp the values for local player	if ( IsLocalPlayer() && ( fFOV != m_iFOVStart ) && (m_Local.m_flFOVRate > 0.0f ) )	{		float deltaTime = (float)( gpGlobals->curtime - m_flFOVTime ) / m_Local.m_flFOVRate;		if ( deltaTime >= 1.0f )		{			//If we're past the zoom time, just take the new value and stop lerping			m_iFOVStart = fFOV;		}		else		{			fFOV = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, m_iFOVStart, fFOV );		}	}	return fFOV;}//-----------------------------------------------------------------------------// Purpose: Called when the FOV changes from the server-side// Input  : *pData - //			*pStruct - //			*pOut - //-----------------------------------------------------------------------------void RecvProxy_FOV( const CRecvProxyData *pData, void *pStruct, void *pOut ){	C_BasePlayer *pPlayer = (C_BasePlayer *) pStruct;	//Hold onto the old FOV as our starting point	int iNewFov = pData->m_Value.m_Int;	if ( pPlayer->m_iFOV == iNewFov )		return;	// Get the true current FOV of the player at this point	pPlayer->m_iFOVStart = pPlayer->GetFOV();		//Get our start time for the zoom	pPlayer->m_flFOVTime = gpGlobals->curtime;	pPlayer->m_iFOV = iNewFov;}//-----------------------------------------------------------------------------// Purpose: Called when the default FOV changes from the server-side// Input  : *pData - //			*pStruct - //			*pOut - //-----------------------------------------------------------------------------void RecvProxy_DefaultFOV( const CRecvProxyData *pData, void *pStruct, void *pOut ){	C_BasePlayer *pPlayer = (C_BasePlayer *) pStruct;	//Hold onto the old FOV as our starting point	int iNewFov = pData->m_Value.m_Int;		if ( pPlayer->m_iDefaultFOV != iNewFov )	{		// Don't lerp		pPlayer->m_Local.m_flFOVRate = 0.0f;		pPlayer->m_iDefaultFOV = iNewFov;	}}void RecvProxy_LocalVelocityX( const CRecvProxyData *pData, void *pStruct, void *pOut ){	C_BasePlayer *pPlayer = (C_BasePlayer *) pStruct;	Assert( pPlayer );	float flNewVel_x = pData->m_Value.m_Float;	Vector vecVelocity = pPlayer->GetLocalVelocity();	if( vecVelocity.x != flNewVel_x )	// Should this use an epsilon check?	{		vecVelocity.x = flNewVel_x;		pPlayer->SetLocalVelocity( vecVelocity );	}}void RecvProxy_LocalVelocityY( const CRecvProxyData *pData, void *pStruct, void *pOut ){	C_BasePlayer *pPlayer = (C_BasePlayer *) pStruct;	Assert( pPlayer );	float flNewVel_y = pData->m_Value.m_Float;	Vector vecVelocity = pPlayer->GetLocalVelocity();	if( vecVelocity.y != flNewVel_y )	{		vecVelocity.y = flNewVel_y;		pPlayer->SetLocalVelocity( vecVelocity );	}}void RecvProxy_LocalVelocityZ( const CRecvProxyData *pData, void *pStruct, void *pOut ){	C_BasePlayer *pPlayer = (C_BasePlayer *) pStruct;		Assert( pPlayer );	float flNewVel_z = pData->m_Value.m_Float;	Vector vecVelocity = pPlayer->GetLocalVelocity();	if( vecVelocity.z != flNewVel_z )	{		vecVelocity.z = flNewVel_z;		pPlayer->SetLocalVelocity( vecVelocity );	}}void RecvProxy_ObserverTarget( const CRecvProxyData *pData, void *pStruct, void *pOut ){	C_BasePlayer *pPlayer = (C_BasePlayer *) pStruct;	Assert( pPlayer );	EHANDLE hTarget;	RecvProxy_IntToEHandle( pData, pStruct, &hTarget );	pPlayer->SetObserverTarget( hTarget );}//-----------------------------------------------------------------------------// Purpose: Remove this player from a vehicle//-----------------------------------------------------------------------------void C_BasePlayer::LeaveVehicle( void ){	if ( NULL == m_hVehicle.Get() )		return;// Let server do this for now#if 0	IClientVehicle *pVehicle = GetVehicle();	Assert( pVehicle );	int nRole = pVehicle->GetPassengerRole( this );	Assert( nRole != VEHICLE_ROLE_NONE );	SetParent( NULL );	// Find the first non-blocked exit point:	Vector vNewPos = GetAbsOrigin();	QAngle qAngles = GetAbsAngles();	pVehicle->GetPassengerExitPoint( nRole, &vNewPos, &qAngles );	OnVehicleEnd( vNewPos );	SetAbsOrigin( vNewPos );	SetAbsAngles( qAngles );	m_Local.m_iHideHUD &= ~HIDEHUD_WEAPONSELECTION;	RemoveEffects( EF_NODRAW );	SetMoveType( MOVETYPE_WALK );	SetCollisionGroup( COLLISION_GROUP_PLAYER );	qAngles[ROLL] = 0;	SnapEyeAngles( qAngles );	m_hVehicle = NULL;	pVehicle->SetPassenger(nRole, NULL);	Weapon_Switch( m_hLastWeapon );#endif}float C_BasePlayer::GetMinFOV()	const{	if ( gpGlobals->maxClients == 1 )	{		// Let them do whatever they want, more or less, in single player		return 5;	}	else	{		return 75;	}}float C_BasePlayer::GetFinalPredictedTime() const{	return ( m_nFinalPredictedTick * TICK_INTERVAL );}void C_BasePlayer::NotePredictionError( const Vector &vDelta ){#if !defined( NO_ENTITY_PREDICTION )	Vector vOldDelta;	GetPredictionErrorSmoothingVector( vOldDelta );	// sum all errors within smoothing time	m_vecPredictionError = vDelta + vOldDelta;	// remember when last error happened	m_flPredictionErrorTime = gpGlobals->curtime; 	ResetLatched(); #endif}void C_BasePlayer::GetPredictionErrorSmoothingVector( Vector &vOffset ){#if !defined( NO_ENTITY_PREDICTION )	if ( engine->IsPlayingDemo() || !cl_smooth.GetInt() || !cl_predict.GetBool() )	{		vOffset.Init();		return;	}	float errorAmount = ( gpGlobals->curtime - m_flPredictionErrorTime ) / cl_smoothtime.GetFloat();	if ( errorAmount >= 1.0f )	{		vOffset.Init();		return;	}		errorAmount = 1.0f - errorAmount;	vOffset = m_vecPredictionError * errorAmount;#else	vOffset.Init();#endif}IRagdoll* C_BasePlayer::GetRepresentativeRagdoll() const{	return m_pRagdoll;}