text: //========= Copyright Valve Corporation, All rights reserved. ============//
  //
  // Purpose: Client-side CBasePlayer.
  //
  //			- Manages the player's flashlight effect.
  //
  //=============================================================================//
  
  #ifndef C_BASEPLAYER_H
  #define C_BASEPLAYER_H
  #ifdef _WIN32
  #pragma once
  #endif
  
  #include "c_playerlocaldata.h"
  #include "c_basecombatcharacter.h"
  #include "PlayerState.h"
  #include "usercmd.h"
  #include "shareddefs.h"
  #include "timedevent.h"
  #include "smartptr.h"
  #include "fx_water.h"
  #include "hintsystem.h"
  #include "SoundEmitterSystem/isoundemittersystembase.h"
  #include "c_env_fog_controller.h"
  #include "igameevents.h"
  #include "GameEventListener.h"
  
  #if defined USES_ECON_ITEMS
  #include "econ_item.h"
  #include "game_item_schema.h"
  #include "econ_item_view.h"
  #endif
  
  class C_BaseCombatWeapon;
  class C_BaseViewModel;
  class C_FuncLadder;
  class CFlashlightEffect;
  class C_EconWearable;
  
  extern int g_nKillCamMode;
  extern int g_nKillCamTarget1;
  extern int g_nKillCamTarget2;
  
  class C_CommandContext
  {
  public:
  	bool			needsprocessing;
  
  	CUserCmd		cmd;
  	int				command_number;
  };
  
  class C_PredictionError
  {
  public:
  	float	time;
  	Vector	error;
  };
  
  #define CHASE_CAM_DISTANCE_MIN	16.0f
  #define CHASE_CAM_DISTANCE_MAX	96.0f
  #define WALL_OFFSET				6.0f
  
  
  bool IsInFreezeCam( void );
  
  //-----------------------------------------------------------------------------
  // Purpose: Base Player class
  //-----------------------------------------------------------------------------
  class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener
  {
  public:
  	DECLARE_CLASS( C_BasePlayer, C_BaseCombatCharacter );
  	DECLARE_CLIENTCLASS();
  	DECLARE_PREDICTABLE();
  	DECLARE_INTERPOLATION();
  
  	C_BasePlayer();
  	virtual			~C_BasePlayer();
  
  	virtual void	Spawn( void );
  	virtual void	SharedSpawn(); // Shared between client and server.
  	virtual bool	GetSteamID( CSteamID *pID );
  
  	// IClientEntity overrides.
  	virtual void	OnPreDataChanged( DataUpdateType_t updateType );
  	virtual void	OnDataChanged( DataUpdateType_t updateType );
  
  	virtual void	PreDataUpdate( DataUpdateType_t updateType );
  	virtual void	PostDataUpdate( DataUpdateType_t updateType );
  	
  	virtual void	ReceiveMessage( int classID, bf_read &msg );
  
  	virtual void	OnRestore();
  
  	virtual void	AddEntity( void );
  
  	virtual void	MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
  
  	virtual void	GetToolRecordingState( KeyValues *msg );
  
  	virtual float GetPlayerMaxSpeed();
  
  	void	SetAnimationExtension( const char *pExtension );
  
  	C_BaseViewModel		*GetViewModel( int viewmodelindex = 0, bool bObserverOK=true );
  	C_BaseCombatWeapon	*GetActiveWeapon( void ) const;
  	const char			*GetTracerType( void );
  
  	// View model prediction setup
  	virtual void		CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
  	virtual void		CalcViewModelView( const Vector& eyeOrigin, const QAngle& eyeAngles);
  	
  
  	// Handle view smoothing when going up stairs
  	void				SmoothViewOnStairs( Vector& eyeOrigin );
  	virtual float		CalcRoll (const QAngle& angles, const Vector& velocity, float rollangle, float rollspeed);
  	void				CalcViewRoll( QAngle& eyeAngles );
  	void				CreateWaterEffects( void );
  
  	virtual void			SetPlayerUnderwater( bool state );
  	void					UpdateUnderwaterState( void );
  	bool					IsPlayerUnderwater( void ) { return m_bPlayerUnderwater; }
  
  	virtual Vector			Weapon_ShootPosition();
  	virtual void			Weapon_DropPrimary( void ) {}
  
  	virtual Vector			GetAutoaimVector( float flScale );
  	void					SetSuitUpdate(const char *name, int fgroup, int iNoRepeat);
  
  	// Input handling
  	virtual bool	CreateMove( float flInputSampleTime, CUserCmd *pCmd );
  	virtual void	AvoidPhysicsProps( CUserCmd *pCmd );
  	
  	virtual void	PlayerUse( void );
  	CBaseEntity		*FindUseEntity( void );
  	virtual bool	IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );
  
  	// Data handlers
  	virtual bool	IsPlayer( void ) const { return true; }
  	virtual int		GetHealth() const { return m_iHealth; }
  
  	int		GetBonusProgress() const { return m_iBonusProgress; }
  	int		GetBonusChallenge() const { return m_iBonusChallenge; }
  
  	// observer mode
  	virtual int			GetObserverMode() const;
  	void				SetObserverMode ( int iNewMode );
  	virtual CBaseEntity	*GetObserverTarget() const;
  	void			SetObserverTarget( EHANDLE hObserverTarget );
  
  	bool			AudioStateIsUnderwater( Vector vecMainViewOrigin );
  
  	bool IsObserver() const;
  	bool IsHLTV() const;
  	bool IsReplay() const;
  	void ResetObserverMode();
  	bool IsBot( void ) const { return false; }
  
  	// Eye position..
  	virtual Vector		 EyePosition();
  	virtual const QAngle &EyeAngles();		// Direction of eyes
  	void				 EyePositionAndVectors( Vector *pPosition, Vector *pForward, Vector *pRight, Vector *pUp );
  	virtual const QAngle &LocalEyeAngles();		// Direction of eyes
  	
  	// This can be overridden to return something other than m_pRagdoll if the mod uses separate 
  	// entities for ragdolls.
  	virtual IRagdoll* GetRepresentativeRagdoll() const;
  
  	// override the initial bone position for ragdolls
  	virtual bool GetRagdollInitBoneArrays( matrix3x4_t *pDeltaBones0, matrix3x4_t *pDeltaBones1, matrix3x4_t *pCurrentBones, float boneDt ) OVERRIDE;
  
  	// Returns eye vectors
  	void			EyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL );
  	void			CacheVehicleView( void );	// Calculate and cache the position of the player in the vehicle
  
  
  	bool			IsSuitEquipped( void ) { return m_Local.m_bWearingSuit; };
  
  	// Team handlers
  	virtual void	TeamChange( int iNewTeam );
  
  	// Flashlight
  	void	Flashlight( void );
  	void	UpdateFlashlight( void );
  
  	// Weapon selection code
  	virtual bool				IsAllowedToSwitchWeapons( void ) { return !IsObserver(); }
  	virtual C_BaseCombatWeapon	*GetActiveWeaponForSelection( void );
  
  	// Returns the view model if this is the local player. If you're in third person or 
  	// this is a remote player, it returns the active weapon
  	// (and its appropriate left/right weapon if this is TF2).
  	virtual C_BaseAnimating*	GetRenderedWeaponModel();
  
  	virtual bool				IsOverridingViewmodel( void ) { return false; };
  	virtual int					DrawOverriddenViewmodel( C_BaseViewModel *pViewmodel, int flags ) { return 0; };
  
  	virtual float				GetDefaultAnimSpeed( void ) { return 1.0; }
  
  	void						SetMaxSpeed( float flMaxSpeed ) { m_flMaxspeed = flMaxSpeed; }
  	float						MaxSpeed() const		{ return m_flMaxspeed; }
  
  	// Should this object cast shadows?
  	virtual ShadowType_t		ShadowCastType() { return SHADOWS_NONE; }
  
  	virtual bool				ShouldReceiveProjectedTextures( int flags )
  	{
  		return false;
  	}
  
  
  	bool						IsLocalPlayer( void ) const;
  
  	// Global/static methods
  	virtual void				ThirdPersonSwitch( bool bThirdperson );
  	static bool					LocalPlayerInFirstPersonView();
  	static bool					ShouldDrawLocalPlayer();
  	static C_BasePlayer			*GetLocalPlayer( void );
  	int							GetUserID( void );
  	virtual bool				CanSetSoundMixer( void );
  	virtual int					GetVisionFilterFlags( bool bWeaponsCheck = false ) { return 0x00; }
  	bool						HasVisionFilterFlags( int nFlags, bool bWeaponsCheck = false ) { return ( GetVisionFilterFlags( bWeaponsCheck ) & nFlags ) == nFlags; }
  	virtual void				CalculateVisionUsingCurrentFlags( void ) {}
  	void						BuildFirstPersonMeathookTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed, const char *pchHeadBoneName );
  
  	// Specific queries about this player.
  	bool						InFirstPersonView();
  	bool						ShouldDrawThisPlayer();
  
  	// Called by the view model if its rendering is being overridden.
  	virtual bool				ViewModel_IsTransparent( void );
  	virtual bool				ViewModel_IsUsingFBTexture( void );
  
  #if !defined( NO_ENTITY_PREDICTION )
  	void						AddToPlayerSimulationList( C_BaseEntity *other );
  	void						SimulatePlayerSimulatedEntities( void );
  	void						RemoveFromPlayerSimulationList( C_BaseEntity *ent );
  	void						ClearPlayerSimulationList( void );
  #endif
  
  	virtual void				PhysicsSimulate( void );
  	virtual unsigned int	PhysicsSolidMaskForEntity( void ) const { return MASK_PLAYERSOLID; }
  
  	// Prediction stuff
  	virtual bool				ShouldPredict( void );
  
  	virtual void				PreThink( void );
  	virtual void				PostThink( void );
  
  	virtual void				ItemPreFrame( void );
  	virtual void				ItemPostFrame( void );
  	virtual void				AbortReload( void );
  
  	virtual void				SelectLastItem(void);
  	virtual void				Weapon_SetLast( C_BaseCombatWeapon *pWeapon );
  	virtual bool				Weapon_ShouldSetLast( C_BaseCombatWeapon *pOldWeapon, C_BaseCombatWeapon *pNewWeapon ) { return true; }
  	virtual bool				Weapon_ShouldSelectItem( C_BaseCombatWeapon *pWeapon );
  	virtual	bool				Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 );		// Switch to given weapon if has ammo (false if failed)
  	virtual C_BaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
  	void						ResetAutoaim( void );
  	virtual void 				SelectItem( const char *pstr, int iSubType = 0 );
  
  	virtual void				UpdateClientData( void );
  
  	virtual float				GetFOV( void );	
  	int							GetDefaultFOV( void ) const;
  	virtual bool				IsZoomed( void )	{ return false; }
  	bool						SetFOV( CBaseEntity *pRequester, int FOV, float zoomRate = 0.0f, int iZoomStart = 0 );
  	void						ClearZoomOwner( void );
  
  	float						GetFOVDistanceAdjustFactor();
  
  	virtual void				ViewPunch( const QAngle &angleOffset );
  	void						ViewPunchReset( float tolerance = 0 );
  
  	void						UpdateButtonState( int nUserCmdButtonMask );
  	int							GetImpulse( void ) const;
  
  	virtual void				Simulate();
  
  	virtual bool				ShouldInterpolate();
  
  	virtual bool				ShouldDraw();
  	virtual int					DrawModel( int flags );
  
  	// Called when not in tactical mode. Allows view to be overriden for things like driving a tank.
  	virtual void				OverrideView( CViewSetup *pSetup );
  
  	// returns the player name
  	const char *				GetPlayerName();
  	virtual const Vector		GetPlayerMins( void ) const; // uses local player
  	virtual const Vector		GetPlayerMaxs( void ) const; // uses local player
  
  	// Is the player dead?
  	bool				IsPlayerDead();
  	bool				IsPoisoned( void ) { return m_Local.m_bPoisoned; }
  
  	C_BaseEntity				*GetUseEntity();
  
  	// Vehicles...
  	IClientVehicle			*GetVehicle();
  
  	bool			IsInAVehicle() const	{ return ( NULL != m_hVehicle.Get() ) ? true : false; }
  	virtual void	SetVehicleRole( int nRole );
  	void					LeaveVehicle( void );
  
  	bool					UsingStandardWeaponsInVehicle( void );
  
  	virtual void			SetAnimation( PLAYER_ANIM playerAnim );
  
  	float					GetTimeBase( void ) const;
  	float					GetFinalPredictedTime() const;
  
  	bool					IsInVGuiInputMode() const;
  	bool					IsInViewModelVGuiInputMode() const;
  
  	C_CommandContext		*GetCommandContext();
  
  	// Get the command number associated with the current usercmd we're running (if in predicted code).
  	int CurrentCommandNumber() const;
  	const CUserCmd *GetCurrentUserCommand() const;
  
  	const QAngle& GetPunchAngle();
  	void SetPunchAngle( const QAngle &angle );
  
  	float					GetWaterJumpTime() const;
  	void					SetWaterJumpTime( float flWaterJumpTime );
  	float					GetSwimSoundTime( void ) const;
  	void					SetSwimSoundTime( float flSwimSoundTime );
  
  	float					GetDeathTime( void ) { return m_flDeathTime; }
  
  	void		SetPreviouslyPredictedOrigin( const Vector &vecAbsOrigin );
  	const Vector &GetPreviouslyPredictedOrigin() const;
  
  	// CS wants to allow small FOVs for zoomed-in AWPs.
  	virtual float GetMinFOV() const;
  
  	virtual void DoMuzzleFlash();
  	virtual void PlayPlayerJingle();
  
  	virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity  );
  	virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
  	virtual surfacedata_t * GetFootstepSurface( const Vector &origin, const char *surfaceName );
  	virtual void GetStepSoundVelocities( float *velwalk, float *velrun );
  	virtual void SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking );
  	virtual const char *GetOverrideStepSound( const char *pszBaseStepSoundName ) { return pszBaseStepSoundName; }
  
  	virtual void OnEmitFootstepSound( const CSoundParameters& params, const Vector& vecOrigin, float fVolume ) {}
  
  	// Called by prediction when it detects a prediction correction.
  	// vDelta is the line from where the client had predicted the player to at the usercmd in question,
  	// to where the server says the client should be at said usercmd.
  	void NotePredictionError( const Vector &vDelta );
  	
  	// Called by the renderer to apply the prediction error smoothing.
  	void GetPredictionErrorSmoothingVector( Vector &vOffset ); 
  
  	bool IsOnLadder( void );
  	virtual void ExitLadder() {}
  	surfacedata_t *GetLadderSurface( const Vector &origin );
  
  	surfacedata_t *GetSurfaceData( void ) { return m_pSurfaceData; }
  
  	void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; }
  
  	// Hints
  	virtual CHintSystem		*Hints( void ) { return NULL; }
  	bool					ShouldShowHints( void ) { return Hints() ? Hints()->ShouldShowHints() : false; }
  	bool 					HintMessage( int hint, bool bForce = false, bool bOnlyIfClear = false ) { return Hints() ? Hints()->HintMessage( hint, bForce, bOnlyIfClear ) : false; }
  	void 					HintMessage( const char *pMessage ) { if (Hints()) Hints()->HintMessage( pMessage ); }
  
  	virtual	IMaterial *GetHeadLabelMaterial( void );
  
  	// Fog
  	fogparams_t				*GetFogParams( void ) { return &m_CurrentFog; }
  	void					FogControllerChanged( bool bSnap );
  	void					UpdateFogController( void );
  	void					UpdateFogBlend( void );
  
  	float					GetFOVTime( void ){ return m_flFOVTime; }
  
  	virtual void			OnAchievementAchieved( int iAchievement ) {}
  	
  	bool					ShouldAnnounceAchievement( void ){ return m_flNextAchievementAnnounceTime < gpGlobals->curtime; }
  	void					SetNextAchievementAnnounceTime( float flTime ){ m_flNextAchievementAnnounceTime = flTime; }
  
  #if defined USES_ECON_ITEMS
  	// Wearables
  	virtual void			UpdateWearables();
  	C_EconWearable			*GetWearable( int i ) { return m_hMyWearables[i]; }
  	int						GetNumWearables( void ) { return m_hMyWearables.Count(); }
  #endif
  
  	bool					HasFiredWeapon( void ) { return m_bFiredWeapon; }
  	void					SetFiredWeapon( bool bFlag ) { m_bFiredWeapon = bFlag; }
  
  	virtual bool			CanUseFirstPersonCommand( void ){ return true; }
  	
  protected:
  	fogparams_t				m_CurrentFog;
  	EHANDLE					m_hOldFogController;
  
  public:
  	int m_StuckLast;
  	
  	// Data for only the local player
  	CNetworkVarEmbedded( CPlayerLocalData, m_Local );
  
  #if defined USES_ECON_ITEMS
  	CNetworkVarEmbedded( CAttributeList, m_AttributeList );
  #endif
  
  	// Data common to all other players, too
  	CPlayerState			pl;
  
  	// Player FOV values
  	int						m_iFOV;				// field of view
  	int						m_iFOVStart;		// starting value of the FOV changing over time (client only)
  	float					m_flFOVTime;		// starting time of the FOV zoom
  	int						m_iDefaultFOV;		// default FOV if no other zooms are occurring
  	EHANDLE					m_hZoomOwner;		// This is a pointer to the entity currently controlling the player's zoom
  												// Only this entity can change the zoom state once it has ownership
  
  	// For weapon prediction
  	bool			m_fOnTarget;		//Is the crosshair on a target?
  	
  	char			m_szAnimExtension[32];
  
  	int				m_afButtonLast;
  	int				m_afButtonPressed;
  	int				m_afButtonReleased;
  
  	int				m_nButtons;
  
  	CUserCmd		*m_pCurrentCommand;
  
  	// Movement constraints
  	EHANDLE			m_hConstraintEntity;
  	Vector			m_vecConstraintCenter;
  	float			m_flConstraintRadius;
  	float			m_flConstraintWidth;
  	float			m_flConstraintSpeedFactor;
  
  protected:
  
  	void				CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  	void				CalcVehicleView(IClientVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles,
  							float& zNear, float& zFar, float& fov );
  	virtual void		CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  	virtual Vector		GetChaseCamViewOffset( CBaseEntity *target );
  	void				CalcChaseCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  	virtual void		CalcInEyeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  
  	virtual float		GetDeathCamInterpolationTime();
  
  	virtual void		CalcDeathCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  	void				CalcRoamingView(Vector& eyeOrigin, QAngle& eyeAngles, float& fov);
  	virtual void		CalcFreezeCamView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  
  	// Check to see if we're in vgui input mode...
  	void DetermineVguiInputMode( CUserCmd *pCmd );
  
  	// Used by prediction, sets the view angles for the player
  	virtual void SetLocalViewAngles( const QAngle &viewAngles );
  	virtual void SetViewAngles( const QAngle& ang );
  
  	// used by client side player footsteps 
  	surfacedata_t* GetGroundSurface();
  
  	virtual void	FireGameEvent( IGameEvent *event );
  
  protected:
  	// Did we just enter a vehicle this frame?
  	bool			JustEnteredVehicle();
  
  // DATA
  	int				m_iObserverMode;	// if in spectator mode != 0
  	EHANDLE			m_hObserverTarget;	// current observer target
  	float			m_flObserverChaseDistance; // last distance to observer traget
  	Vector			m_vecFreezeFrameStart;
  	float			m_flFreezeFrameStartTime;	// Time at which we entered freeze frame observer mode
  	float			m_flFreezeFrameDistance;
  	bool			m_bWasFreezeFraming; 
  	float			m_flDeathTime;		// last time player died
  
  	float			m_flStepSoundTime;
  	bool			m_IsFootprintOnLeft;
  
  private:
  	// Make sure no one calls this...
  	C_BasePlayer& operator=( const C_BasePlayer& src );
  	C_BasePlayer( const C_BasePlayer & ); // not defined, not accessible
  
  	// Vehicle stuff.
  	EHANDLE			m_hVehicle;
  	EHANDLE			m_hOldVehicle;
  	EHANDLE			m_hUseEntity;
  	
  	float			m_flMaxspeed;
  
  	int				m_iBonusProgress;
  	int				m_iBonusChallenge;
  
  	CInterpolatedVar< Vector >	m_iv_vecViewOffset;
  
  	// Not replicated
  	Vector			m_vecWaterJumpVel;
  	float			m_flWaterJumpTime;  // used to be called teleport_time
  	int				m_nImpulse;
  
  	float			m_flSwimSoundTime;
  	Vector			m_vecLadderNormal;
  	
  	QAngle			m_vecOldViewAngles;
  
  	bool			m_bWasFrozen;
  	int				m_flPhysics;
  
  	int				m_nTickBase;
  	int				m_nFinalPredictedTick;
  
  	EHANDLE			m_pCurrentVguiScreen;
  
  	bool			m_bFiredWeapon;
  
  
  	// Player flashlight dynamic light pointers
  	CFlashlightEffect *m_pFlashlight;
  
  	typedef CHandle<C_BaseCombatWeapon> CBaseCombatWeaponHandle;
  	CNetworkVar( CBaseCombatWeaponHandle, m_hLastWeapon );
  
  #if !defined( NO_ENTITY_PREDICTION )
  	CUtlVector< CHandle< C_BaseEntity > > m_SimulatedByThisPlayer;
  #endif
  
  	// players own view models, left & right hand
  	CHandle< C_BaseViewModel >	m_hViewModel[ MAX_VIEWMODELS ];		
  	
  	float					m_flOldPlayerZ;
  	float					m_flOldPlayerViewOffsetZ;
  	
  	Vector	m_vecVehicleViewOrigin;		// Used to store the calculated view of the player while riding in a vehicle
  	QAngle	m_vecVehicleViewAngles;		// Vehicle angles
  	float	m_flVehicleViewFOV;
  	int		m_nVehicleViewSavedFrame;	// Used to mark which frame was the last one the view was calculated for
  
  	// For UI purposes...
  	int				m_iOldAmmo[ MAX_AMMO_TYPES ];
  
  	C_CommandContext		m_CommandContext;
  
  	// For underwater effects
  	float							m_flWaterSurfaceZ;
  	bool							m_bResampleWaterSurface;
  	TimedEvent						m_tWaterParticleTimer;
  	CSmartPtr<WaterDebrisEffect>	m_pWaterEmitter;
  
  	bool							m_bPlayerUnderwater;
  
  	friend class CPrediction;
  
  	// HACK FOR TF2 Prediction
  	friend class CTFGameMovementRecon;
  	friend class CGameMovement;
  	friend class CTFGameMovement;
  	friend class CHL1GameMovement;
  	friend class CCSGameMovement;
  	friend class CHL2GameMovement;
  	friend class CDODGameMovement;
  	friend class CPortalGameMovement;
  #ifdef NEO_DLL
  	friend class CNEOGameMovement;
  #endif
  	
  	// Accessors for gamemovement
  	float GetStepSize( void ) const { return m_Local.m_flStepSize; }
  
  	float m_flNextAvoidanceTime;
  	float m_flAvoidanceRight;
  	float m_flAvoidanceForward;
  	float m_flAvoidanceDotForward;
  	float m_flAvoidanceDotRight;
  
  protected:
  	virtual bool IsDucked( void ) const { return m_Local.m_bDucked; }
  	virtual bool IsDucking( void ) const { return m_Local.m_bDucking; }
  	virtual float GetFallVelocity( void ) { return m_Local.m_flFallVelocity; }
  	bool ForceSetupBonesAtTimeFakeInterpolation( matrix3x4_t *pBonesOut, float curtimeOffset );
  
  	float m_flLaggedMovementValue;
  
  	// These are used to smooth out prediction corrections. They're most useful when colliding with
  	// vphysics objects. The server will be sending constant prediction corrections, and these can help
  	// the errors not be so jerky.
  	Vector m_vecPredictionError;
  	float m_flPredictionErrorTime;
  	
  	Vector m_vecPreviouslyPredictedOrigin; // Used to determine if non-gamemovement game code has teleported, or tweaked the player's origin
  
  	char m_szLastPlaceName[MAX_PLACE_NAME_LENGTH];	// received from the server
  
  	// Texture names and surface data, used by CGameMovement
  	int				m_surfaceProps;
  	surfacedata_t*	m_pSurfaceData;
  	float			m_surfaceFriction;
  	char			m_chTextureType;
  
  	bool			m_bSentFreezeFrame;
  	float			m_flFreezeZOffset;
  
  	float			m_flNextAchievementAnnounceTime;
  
  	int				m_nForceVisionFilterFlags; // Force our vision filter to a specific setting
  	int				m_nLocalPlayerVisionFlags;
  
  #if defined USES_ECON_ITEMS
  	// Wearables
  	CUtlVector<CHandle<C_EconWearable > >	m_hMyWearables;
  #endif
  
  private:
  
  	struct StepSoundCache_t
  	{
  		StepSoundCache_t() : m_usSoundNameIndex( 0 ) {}
  		CSoundParameters	m_SoundParameters;
  		unsigned short		m_usSoundNameIndex;
  	};
  	// One for left and one for right side of step
  	StepSoundCache_t		m_StepSoundCache[ 2 ];
  
  public:
  
  	const char *GetLastKnownPlaceName( void ) const	{ return m_szLastPlaceName; }	// return the last nav place name the player occupied
  
  	float GetLaggedMovementValue( void ){ return m_flLaggedMovementValue;	}
  	bool  ShouldGoSouth( Vector vNPCForward, Vector vNPCRight ); //Such a bad name.
  
  	void SetOldPlayerZ( float flOld ) { m_flOldPlayerZ = flOld;	}
  };
  
  EXTERN_RECV_TABLE(DT_BasePlayer);
  
  //-----------------------------------------------------------------------------
  // Inline methods
  //-----------------------------------------------------------------------------
  inline C_BasePlayer *ToBasePlayer( C_BaseEntity *pEntity )
  {
  	if ( !pEntity || !pEntity->IsPlayer() )
  		return NULL;
  
  #if _DEBUG
  	Assert( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL );
  #endif
  
  	return static_cast<C_BasePlayer *>( pEntity );
  }
  
  inline C_BaseEntity *C_BasePlayer::GetUseEntity() 
  { 
  	return m_hUseEntity;
  }
  
  
  inline IClientVehicle *C_BasePlayer::GetVehicle() 
  { 
  	C_BaseEntity *pVehicleEnt = m_hVehicle.Get();
  	return pVehicleEnt ? pVehicleEnt->GetClientVehicle() : NULL;
  }
  
  inline bool C_BasePlayer::IsObserver() const 
  { 
  	return (GetObserverMode() != OBS_MODE_NONE); 
  }
  
  inline int C_BasePlayer::GetImpulse( void ) const 
  { 
  	return m_nImpulse; 
  }
  
  
  inline C_CommandContext* C_BasePlayer::GetCommandContext()
  {
  	return &m_CommandContext;
  }
  
  inline int CBasePlayer::CurrentCommandNumber() const
  {
  	Assert( m_pCurrentCommand );
  	return m_pCurrentCommand->command_number;
  }
  
  inline const CUserCmd *CBasePlayer::GetCurrentUserCommand() const
  {
  	Assert( m_pCurrentCommand );
  	return m_pCurrentCommand;
  }
  
  #endif // C_BASEPLAYER_H
  