text: //========= Copyright Valve Corporation, All rights reserved. ============//
  //
  // Purpose: 
  //
  //===========================================================================//
  
  #ifndef PLAYER_H
  #define PLAYER_H
  #ifdef _WIN32
  #pragma once
  #endif
  
  #include "basecombatcharacter.h"
  #include "usercmd.h"
  #include "playerlocaldata.h"
  #include "PlayerState.h"
  #include "game/server/iplayerinfo.h"
  #include "hintsystem.h"
  #include "SoundEmitterSystem/isoundemittersystembase.h"
  #include "util_shared.h"
  
  #if defined USES_ECON_ITEMS
  #include "game_item_schema.h"
  #include "econ_item_view.h"
  #endif
  
  // For queuing and processing usercmds
  class CCommandContext
  {
  public:
  	CUtlVector< CUserCmd > cmds;
  
  	int				numcmds;
  	int				totalcmds;
  	int				dropped_packets;
  	bool			paused;
  };
  
  // Info about last 20 or so updates to the
  class CPlayerCmdInfo
  {
  public:
  	CPlayerCmdInfo() : 
  	  m_flTime( 0.0f ), m_nNumCmds( 0 ), m_nDroppedPackets( 0 )
  	{
  	}
  
  	// realtime of sample
  	float		m_flTime;
  	// # of CUserCmds in this update
  	int			m_nNumCmds;
  	// # of dropped packets on the link
  	int			m_nDroppedPackets;
  };
  
  class CPlayerSimInfo
  {
  public:
  	CPlayerSimInfo() : 
  	  m_flTime( 0.0f ), m_nNumCmds( 0 ), m_nTicksCorrected( 0 ), m_flFinalSimulationTime( 0.0f ), m_flGameSimulationTime( 0.0f ), m_flServerFrameTime( 0.0f ), m_vecAbsOrigin( 0, 0, 0 )
  	{
  	}
  
  	// realtime of sample
  	float		m_flTime;
  	// # of CUserCmds in this update
  	int			m_nNumCmds;
  	// If clock needed correction, # of ticks added/removed
  	int			m_nTicksCorrected; // +ve or -ve
  	// player's m_flSimulationTime at end of frame
  	float		m_flFinalSimulationTime;
  	float		m_flGameSimulationTime;
  	// estimate of server perf
  	float		m_flServerFrameTime;  
  	Vector		m_vecAbsOrigin;
  };
  //-----------------------------------------------------------------------------
  // Forward declarations: 
  //-----------------------------------------------------------------------------
  class CBaseCombatWeapon;
  class CBaseViewModel;
  class CTeam;
  class IPhysicsPlayerController;
  class IServerVehicle;
  class CUserCmd;
  class CFuncLadder;
  class CNavArea;
  class CHintSystem;
  class CAI_Expresser;
  
  #if defined USES_ECON_ITEMS
  class CEconWearable;
  #endif // USES_ECON_ITEMS
  
  // for step sounds
  struct surfacedata_t;
  
  // !!!set this bit on guns and stuff that should never respawn.
  #define	SF_NORESPAWN	( 1 << 30 )
  
  //
  // Player PHYSICS FLAGS bits
  //
  enum PlayerPhysFlag_e
  {
  	PFLAG_DIROVERRIDE	= ( 1<<0 ),		// override the player's directional control (trains, physics gun, etc.)
  	PFLAG_DUCKING		= ( 1<<1 ),		// In the process of ducking, but totally squatted yet
  	PFLAG_USING			= ( 1<<2 ),		// Using a continuous entity
  	PFLAG_OBSERVER		= ( 1<<3 ),		// player is locked in stationary cam mode. Spectators can move, observers can't.
  	PFLAG_VPHYSICS_MOTIONCONTROLLER = ( 1<<4 ),	// player is physically attached to a motion controller
  	PFLAG_GAMEPHYSICS_ROTPUSH = (1<<5), // game physics did a rotating push that we may want to override with vphysics
  
  	// If you add another flag here check that you aren't 
  	// overwriting phys flags in the HL2 of TF2 player classes
  };
  
  //
  // generic player
  //
  //-----------------------------------------------------
  //This is Half-Life player entity
  //-----------------------------------------------------
  #define CSUITPLAYLIST	4		// max of 4 suit sentences queued up at any time
  #define	SUIT_REPEAT_OK		0
  
  #define SUIT_NEXT_IN_30SEC	30
  #define SUIT_NEXT_IN_1MIN	60
  #define SUIT_NEXT_IN_5MIN	300
  #define SUIT_NEXT_IN_10MIN	600
  #define SUIT_NEXT_IN_30MIN	1800
  #define SUIT_NEXT_IN_1HOUR	3600
  
  #define CSUITNOREPEAT		32
  
  #define TEAM_NAME_LENGTH	16
  
  // constant items
  #define ITEM_HEALTHKIT		1
  #define ITEM_BATTERY		4
  
  #define AUTOAIM_2DEGREES  0.0348994967025
  #define AUTOAIM_5DEGREES  0.08715574274766
  #define AUTOAIM_8DEGREES  0.1391731009601
  #define AUTOAIM_10DEGREES 0.1736481776669
  #define AUTOAIM_20DEGREES 0.3490658503989
  
  // useful cosines
  #define DOT_1DEGREE   0.9998476951564
  #define DOT_2DEGREE   0.9993908270191
  #define DOT_3DEGREE   0.9986295347546
  #define DOT_4DEGREE   0.9975640502598
  #define DOT_5DEGREE   0.9961946980917
  #define DOT_6DEGREE   0.9945218953683
  #define DOT_7DEGREE   0.9925461516413
  #define DOT_8DEGREE   0.9902680687416
  #define DOT_9DEGREE   0.9876883405951
  #define DOT_10DEGREE  0.9848077530122
  #define DOT_15DEGREE  0.9659258262891
  #define DOT_20DEGREE  0.9396926207859
  #define DOT_25DEGREE  0.9063077870367
  #define DOT_30DEGREE  0.866025403784
  #define DOT_45DEGREE  0.707106781187
  enum
  {
  	VPHYS_WALK = 0,
  	VPHYS_CROUCH,
  	VPHYS_NOCLIP,
  };
  
  
  enum PlayerConnectedState
  {
  	PlayerConnected,
  	PlayerDisconnecting,
  	PlayerDisconnected,
  };
  
  extern bool gInitHUD;
  extern ConVar *sv_cheats;
  
  class CBasePlayer;
  class CPlayerInfo : public IBotController, public IPlayerInfo
  {
  public:
  	CPlayerInfo () { m_pParent = NULL; } 
  	~CPlayerInfo () {}
  	void SetParent( CBasePlayer *parent ) { m_pParent = parent; } 
  
  	// IPlayerInfo interface
  	virtual const char *GetName();
  	virtual int			GetUserID();
  	virtual const char *GetNetworkIDString();
  	virtual int			GetTeamIndex();
  	virtual void		ChangeTeam( int iTeamNum );
  	virtual int			GetFragCount();
  	virtual int			GetDeathCount();
  	virtual bool		IsConnected();
  	virtual int			GetArmorValue();
  
  	virtual bool IsHLTV();
  	virtual bool IsReplay();
  	virtual bool IsPlayer();
  	virtual bool IsFakeClient();
  	virtual bool IsDead();
  	virtual bool IsInAVehicle();
  	virtual bool IsObserver();
  	virtual const Vector GetAbsOrigin();
  	virtual const QAngle GetAbsAngles();
  	virtual const Vector GetPlayerMins();
  	virtual const Vector GetPlayerMaxs();
  	virtual const char *GetWeaponName();
  	virtual const char *GetModelName();
  	virtual const int GetHealth();
  	virtual const int GetMaxHealth();
  
  	// bot specific functions	
  	virtual void SetAbsOrigin( Vector & vec );
  	virtual void SetAbsAngles( QAngle & ang );
  	virtual void RemoveAllItems( bool removeSuit );
  	virtual void SetActiveWeapon( const char *WeaponName );
  	virtual void SetLocalOrigin( const Vector& origin );
  	virtual const Vector GetLocalOrigin( void );
  	virtual void SetLocalAngles( const QAngle& angles );
  	virtual const QAngle GetLocalAngles( void );
  	virtual bool IsEFlagSet( int nEFlagMask );
  
  	virtual void RunPlayerMove( CBotCmd *ucmd );
  	virtual void SetLastUserCommand( const CBotCmd &cmd );
  
  	virtual CBotCmd GetLastUserCommand();
  
  private:
  	CBasePlayer *m_pParent; 
  };
  
  class CBasePlayer : public CBaseCombatCharacter
  {
  public:
  	DECLARE_CLASS( CBasePlayer, CBaseCombatCharacter );
  protected:
  	// HACK FOR BOTS
  	friend class CBotManager;
  	static edict_t *s_PlayerEdict; // must be set before calling constructor
  public:
  	DECLARE_DATADESC();
  	DECLARE_SERVERCLASS();
  	// script description
  	DECLARE_ENT_SCRIPTDESC();
  	
  	CBasePlayer();
  	~CBasePlayer();
  
  	// IPlayerInfo passthrough (because we can't do multiple inheritance)
  	IPlayerInfo *GetPlayerInfo() { return &m_PlayerInfo; }
  	IBotController *GetBotController() { return &m_PlayerInfo; }
  
  	virtual void			SetModel( const char *szModelName );
  	void					SetBodyPitch( float flPitch );
  
  	virtual void			UpdateOnRemove( void );
  
  	static CBasePlayer		*CreatePlayer( const char *className, edict_t *ed );
  
  	virtual void			CreateViewModel( int viewmodelindex = 0 );
  	CBaseViewModel			*GetViewModel( int viewmodelindex = 0, bool bObserverOK = true );
  	void					HideViewModels( void );
  	void					DestroyViewModels( void );
  
  #ifdef MAPBASE
  	virtual void			CreateHandModel( int viewmodelindex = 1, int iOtherVm = 0 );
  #endif
  
  	CPlayerState			*PlayerData( void ) { return &pl; }
  	
  	int						RequiredEdictIndex( void ) { return ENTINDEX(edict()); } 
  
  	void					LockPlayerInPlace( void );
  	void					UnlockPlayer( void );
  
  	virtual void			DrawDebugGeometryOverlays(void);
  	
  	// Networking is about to update this entity, let it override and specify it's own pvs
  	virtual void			SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs, int pvssize );
  	virtual int				UpdateTransmitState();
  	virtual int				ShouldTransmit( const CCheckTransmitInfo *pInfo );
  
  	// Returns true if this player wants pPlayer to be moved back in time when this player runs usercmds.
  	// Saves a lot of overhead on the server if we can cull out entities that don't need to lag compensate
  	// (like team members, entities out of our PVS, etc).
  	virtual bool			WantsLagCompensationOnEntity( const CBasePlayer	*pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
  
  	virtual void			Spawn( void );
  	virtual void			Activate( void );
  	virtual void			SharedSpawn(); // Shared between client and server.
  	virtual void			ForceRespawn( void );
  
  	virtual void			InitialSpawn( void );
  	virtual void			InitHUD( void ) {}
  	virtual void			ShowViewPortPanel( const char * name, bool bShow = true, KeyValues *data = NULL );
  
  	virtual void			PlayerDeathThink( void );
  
  	virtual void			Jump( void );
  	virtual void			Duck( void );
  
  	const char				*GetTracerType( void );
  	void					MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType );
  	void					DoImpactEffect( trace_t &tr, int nDamageType );
  
  #if !defined( NO_ENTITY_PREDICTION )
  	void					AddToPlayerSimulationList( CBaseEntity *other );
  	void					RemoveFromPlayerSimulationList( CBaseEntity *other );
  	void					SimulatePlayerSimulatedEntities( void );
  	void					ClearPlayerSimulationList( void );
  #endif
  
  	// Physics simulation (player executes it's usercmd's here)
  	virtual void			PhysicsSimulate( void );
  
  	// Forces processing of usercmds (e.g., even if game is paused, etc.)
  	void					ForceSimulation();
  
  	virtual unsigned int	PhysicsSolidMaskForEntity( void ) const;
  
  	virtual void			PreThink( void );
  	virtual void			PostThink( void );
  	virtual int				TakeHealth( float flHealth, int bitsDamageType );
  	virtual void			TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
  	bool					ShouldTakeDamageInCommentaryMode( const CTakeDamageInfo &inputInfo );
  	virtual int				OnTakeDamage( const CTakeDamageInfo &info );
  	virtual void			DamageEffect(float flDamage, int fDamageType);
  
  	virtual void			OnDamagedByExplosion( const CTakeDamageInfo &info );
  
  	void					PauseBonusProgress( bool bPause = true );
  	void					SetBonusProgress( int iBonusProgress );
  	void					SetBonusChallenge( int iBonusChallenge );
  
  	int						GetBonusProgress() const { return m_iBonusProgress; }
  	int						GetBonusChallenge() const { return m_iBonusChallenge; }
  
  	virtual Vector			EyePosition( );			// position of eyes
  	const QAngle			&EyeAngles( );
  	void					EyePositionAndVectors( Vector *pPosition, Vector *pForward, Vector *pRight, Vector *pUp );
  	virtual const QAngle	&LocalEyeAngles();		// Direction of eyes
  	void					EyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL );
  	void					CacheVehicleView( void );	// Calculate and cache the position of the player in the vehicle
  
  	// Sets the view angles
  	void					SnapEyeAngles( const QAngle &viewAngles );
  
  	virtual QAngle			BodyAngles();
  	virtual Vector			BodyTarget( const Vector &posSrc, bool bNoisy);
  	virtual bool			ShouldFadeOnDeath( void ) { return FALSE; }
  	
  	virtual const impactdamagetable_t &GetPhysicsImpactDamageTable();
  	virtual int				OnTakeDamage_Alive( const CTakeDamageInfo &info );
  	virtual void			Event_Killed( const CTakeDamageInfo &info );
  	// Notifier that I've killed some other entity. (called from Victim's Event_Killed).
  	virtual void			Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info );
  
  	virtual void			Event_Dying( const CTakeDamageInfo &info );
  
  	bool					IsHLTV( void ) const { return pl.hltv; }
  	bool					IsReplay( void ) const { return pl.replay; }
  	virtual	bool			IsPlayer( void ) const { return true; }			// Spectators return TRUE for this, use IsObserver to separate cases
  	virtual bool			IsNetClient( void ) const { return true; }		// Bots should return FALSE for this, they can't receive NET messages
  																			// Spectators should return TRUE for this
  
  	virtual bool			IsFakeClient( void ) const;
  
  	// Get the client index (entindex-1).
  	int						GetClientIndex()	{ return ENTINDEX( edict() ) - 1; }
  
  	// returns the player name
  	const char *			GetPlayerName() { return m_szNetname; }
  	void					SetPlayerName( const char *name );
  
  	int						GetUserID() { return engine->GetPlayerUserId( edict() ); }
  	const char *			GetNetworkIDString(); 
  	virtual const Vector	GetPlayerMins( void ) const; // uses local player
  	virtual const Vector	GetPlayerMaxs( void ) const; // uses local player
  
  
  	void					VelocityPunch( const Vector &vecForce );
  	void					ViewPunch( const QAngle &angleOffset );
  	void					ViewPunchReset( float tolerance = 0 );
  	void					ShowViewModel( bool bShow );
  	void					ShowCrosshair( bool bShow );
  
  	bool					ScriptIsPlayerNoclipping(void);
  
  #ifdef MAPBASE_VSCRIPT
  	HSCRIPT					VScriptGetExpresser();
  #endif
  
  	// View model prediction setup
  	void					CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov );
  
  	// 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 );
  
  	virtual int				Save( ISave &save );
  	virtual int				Restore( IRestore &restore );
  	virtual bool			ShouldSavePhysics();
  	virtual void			OnRestore( void );
  
  	virtual void			PackDeadPlayerItems( void );
  	virtual void			RemoveAllItems( bool removeSuit );
  	bool					IsDead() const;
  #ifdef CSTRIKE_DLL
  	virtual bool			IsRunning( void ) const	{ return false; } // bot support under cstrike (AR)
  #endif
  
  	bool					HasPhysicsFlag( unsigned int flag ) { return (m_afPhysicsFlags & flag) != 0; }
  
  	// Weapon stuff
  	virtual Vector			Weapon_ShootPosition( );
  	virtual bool			Weapon_CanUse( CBaseCombatWeapon *pWeapon );
  	virtual void			Weapon_Equip( CBaseCombatWeapon *pWeapon );
  	virtual	void			Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget /* = NULL */, const Vector *pVelocity /* = NULL */ );
  	virtual	bool			Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0 );		// Switch to given weapon if has ammo (false if failed)
  	virtual void			Weapon_SetLast( CBaseCombatWeapon *pWeapon );
  	virtual bool			Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) { return true; }
  	virtual bool			Weapon_ShouldSelectItem( CBaseCombatWeapon *pWeapon );
  	void					Weapon_DropSlot( int weaponSlot );
  	CBaseCombatWeapon		*Weapon_GetLast( void ) { return m_hLastWeapon.Get(); }
  #ifdef MAPBASE
  	virtual Activity		Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL );
  #endif
  
  	virtual void			OnMyWeaponFired( CBaseCombatWeapon *weapon );	// call this when this player fires a weapon to allow other systems to react
  	virtual float			GetTimeSinceWeaponFired( void ) const;			// returns the time, in seconds, since this player fired a weapon
  	virtual bool			IsFiringWeapon( void ) const;					// return true if this player is currently firing their weapon
  
  	bool					HasAnyAmmoOfType( int nAmmoIndex );
  
  	// JOHN:  sends custom messages if player HUD data has changed  (eg health, ammo)
  	virtual void			UpdateClientData( void );
  	void					RumbleEffect( unsigned char index, unsigned char rumbleData, unsigned char rumbleFlags );
  	
  	// Player is moved across the transition by other means
  	virtual int				ObjectCaps( void ) { return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
  	virtual void			Precache( void );
  	bool					IsOnLadder( void );
  	virtual void			ExitLadder() {}
  	virtual surfacedata_t	*GetLadderSurface( const Vector &origin );
  
  	virtual void			SetFlashlightEnabled( bool bState ) { };
  	virtual int				FlashlightIsOn( void ) { return false; }
  	virtual void			FlashlightTurnOn( void ) { };
  	virtual void			FlashlightTurnOff( void ) { };
  	virtual bool			IsIlluminatedByFlashlight( CBaseEntity *pEntity, float *flReturnDot ) {return false; }
  	
  	void					UpdatePlayerSound ( void );
  	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 const char	   *GetOverrideStepSound( const char *pszBaseStepSoundName ) { return pszBaseStepSoundName; }
  	virtual void			GetStepSoundVelocities( float *velwalk, float *velrun );
  	virtual void			SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking );
  	virtual void			DeathSound( const CTakeDamageInfo &info );
  	virtual const char*		GetSceneSoundToken( void ) { return ""; }
  
  	virtual void			OnEmitFootstepSound( const CSoundParameters& params, const Vector& vecOrigin, float fVolume ) {}
  
  	Class_T					Classify ( void );
  	virtual void			SetAnimation( PLAYER_ANIM playerAnim );
  	void					SetWeaponAnimType( const char *szExtention );
  
  	// custom player functions
  	virtual void			ImpulseCommands( void );
  	virtual void			CheatImpulseCommands( int iImpulse );
  	virtual bool			ClientCommand( const CCommand &args );
  
  	void					NotifySinglePlayerGameEnding() { m_bSinglePlayerGameEnding = true; }
  	bool					IsSinglePlayerGameEnding() { return m_bSinglePlayerGameEnding == true; }
  
  	bool					HandleVoteCommands( const CCommand &args );
  	
  	// Observer functions
  	virtual bool			StartObserverMode(int mode); // true, if successful
  	virtual void			StopObserverMode( void );	// stop spectator mode
  	virtual bool			ModeWantsSpectatorGUI( int iMode ) { return true; }
  	virtual bool			SetObserverMode(int mode); // sets new observer mode, returns true if successful
  	virtual int				GetObserverMode( void ); // returns observer mode or OBS_NONE
  	virtual bool			SetObserverTarget(CBaseEntity * target);
  	virtual void			ObserverUse( bool bIsPressed ); // observer pressed use
  	virtual CBaseEntity		*GetObserverTarget( void ); // returns players targer or NULL
  	virtual CBaseEntity		*FindNextObserverTarget( bool bReverse ); // returns next/prev player to follow or NULL
  	virtual int				GetNextObserverSearchStartPoint( bool bReverse ); // Where we should start looping the player list in a FindNextObserverTarget call
  	virtual bool			IsValidObserverTarget(CBaseEntity * target); // true, if player is allowed to see this target
  	virtual void			CheckObserverSettings(); // checks, if target still valid (didn't die etc)
  	virtual void			JumptoPosition(const Vector &origin, const QAngle &angles);
  	virtual void			ForceObserverMode(int mode); // sets a temporary mode, force because of invalid targets
  	virtual void			ResetObserverMode(); // resets all observer related settings
  	virtual void			ValidateCurrentObserverTarget( void ); // Checks the current observer target, and moves on if it's not valid anymore
  	virtual void			AttemptToExitFreezeCam( void );
  
  	virtual bool			StartReplayMode( float fDelay, float fDuration, int iEntity );
  	virtual void			StopReplayMode();
  	virtual int				GetDelayTicks();
  	virtual int				GetReplayEntity();
  
  	virtual void			CreateCorpse( void ) { }
  	virtual CBaseEntity		*EntSelectSpawnPoint( void );
  
  	// Vehicles
  	virtual bool			IsInAVehicle( void ) const;
  			bool			CanEnterVehicle( IServerVehicle *pVehicle, int nRole );
  	virtual bool			GetInVehicle( IServerVehicle *pVehicle, int nRole );
  	virtual void			LeaveVehicle( const Vector &vecExitPoint = vec3_origin, const QAngle &vecExitAngles = vec3_angle );
  	int						GetVehicleAnalogControlBias() { return m_iVehicleAnalogBias; }
  	void					SetVehicleAnalogControlBias( int bias ) { m_iVehicleAnalogBias = bias; }
  	
  	// override these for 
  	virtual void			OnVehicleStart() {}
  	virtual void			OnVehicleEnd( Vector &playerDestPosition ) {} 
  	IServerVehicle			*GetVehicle();
  	CBaseEntity				*GetVehicleEntity( void );
  	bool					UsingStandardWeaponsInVehicle( void );
  	
  	void					AddPoints( int score, bool bAllowNegativeScore );
  	void					AddPointsToTeam( int score, bool bAllowNegativeScore );
  	virtual bool			BumpWeapon( CBaseCombatWeapon *pWeapon );
  	bool					RemovePlayerItem( CBaseCombatWeapon *pItem );
  	CBaseEntity				*HasNamedPlayerItem( const char *pszItemName );
  	bool 					HasWeapons( void );// do I have ANY weapons?
  	virtual void			SelectLastItem(void);
  	virtual void 			SelectItem( const char *pstr, int iSubType = 0 );
  	void					ItemPreFrame( void );
  	virtual void			ItemPostFrame( void );
  	virtual CBaseEntity		*GiveNamedItem( const char *szName, int iSubType = 0 );
  	void					EnableControl(bool fControl);
  	virtual void			CheckTrainUpdate( void );
  	void					AbortReload( void );
  
  	void					SendAmmoUpdate(void);
  
  	void					WaterMove( void );
  	float					GetWaterJumpTime() const;
  	void					SetWaterJumpTime( float flWaterJumpTime );
  	float					GetSwimSoundTime( void ) const;
  	void					SetSwimSoundTime( float flSwimSoundTime );
  
  	virtual void			SetPlayerUnderwater( bool state );
  	void					UpdateUnderwaterState( void );
  	bool					IsPlayerUnderwater( void ) { return m_bPlayerUnderwater; }
  
  	virtual bool			CanBreatheUnderwater() const { return false; }
  	virtual void			PlayerUse( void );
  	virtual void			PlayUseDenySound() {}
  
  	virtual CBaseEntity		*FindUseEntity( void );
  	virtual bool			IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );
  	bool					ClearUseEntity();
  	CBaseEntity				*DoubleCheckUseNPC( CBaseEntity *pNPC, const Vector &vecSrc, const Vector &vecDir );
  
  
  	// physics interactions
  	// mass/size limit set to zero for none
  	static bool				CanPickupObject( CBaseEntity *pObject, float massLimit, float sizeLimit );
  	virtual void			PickupObject( CBaseEntity *pObject, bool bLimitMassAndSize = true ) {}
  	virtual void			ForceDropOfCarriedPhysObjects( CBaseEntity *pOnlyIfHoldindThis = NULL ) {}
  	virtual float			GetHeldObjectMass( IPhysicsObject *pHeldObject );
  
  	void					CheckSuitUpdate();
  	void					SetSuitUpdate(const char *name, int fgroup, int iNoRepeat);
  	virtual void			UpdateGeigerCounter( void );
  	void					CheckTimeBasedDamage( void );
  
  	void					ResetAutoaim( void );
  	
  	virtual Vector			GetAutoaimVector( float flScale );
  	virtual Vector			GetAutoaimVector( float flScale, float flMaxDist );
  	virtual void			GetAutoaimVector( autoaim_params_t &params );
  
  	float					GetAutoaimScore( const Vector &eyePosition, const Vector &viewDir, const Vector &vecTarget, CBaseEntity *pTarget, float fScale, CBaseCombatWeapon *pActiveWeapon );
  	QAngle					AutoaimDeflection( Vector &vecSrc, autoaim_params_t &params );
  	virtual bool			ShouldAutoaim( void );
  	void					SetTargetInfo( Vector &vecSrc, float flDist );
  
  	void					SetViewEntity( CBaseEntity *pEntity );
  	CBaseEntity				*GetViewEntity( void ) { return m_hViewEntity; }
  
  	virtual void			ForceClientDllUpdate( void );  // Forces all client .dll specific data to be resent to client.
  
  	void					DeathMessage( CBaseEntity *pKiller );
  
  	virtual void			ProcessUsercmds( CUserCmd *cmds, int numcmds, int totalcmds,
  								int dropped_packets, bool paused );
  	bool					IsUserCmdDataValid( CUserCmd *pCmd );
  
  	void					AvoidPhysicsProps( CUserCmd *pCmd );
  
  	// Run a user command. The default implementation calls ::PlayerRunCommand. In TF, this controls a vehicle if
  	// the player is in one.
  	virtual void			PlayerRunCommand(CUserCmd *ucmd, IMoveHelper *moveHelper);
  	void					RunNullCommand();
  	CUserCmd *				GetCurrentCommand( void )	{ return m_pCurrentCommand; }
  	float					GetTimeSinceLastUserCommand( void ) { return ( !IsConnected() || IsFakeClient() || IsBot() ) ? 0.f : gpGlobals->curtime - m_flLastUserCommandTime; }
  
  	// Team Handling
  	virtual void			ChangeTeam( int iTeamNum ) { ChangeTeam(iTeamNum,false, false); }
  	virtual void			ChangeTeam( int iTeamNum, bool bAutoTeam, bool bSilent );
  
  	// say/sayteam allowed?
  	virtual bool		CanHearAndReadChatFrom( CBasePlayer *pPlayer ) { return true; }
  	virtual bool		CanSpeak( void ) { return true; }
  
  	audioparams_t			&GetAudioParams() { return m_Local.m_audio; }
  
  	virtual void 			ModifyOrAppendPlayerCriteria( AI_CriteriaSet& set );
  
  	const QAngle& GetPunchAngle();
  	void SetPunchAngle( const QAngle &punchAngle );
  
  	virtual void DoMuzzleFlash();
  
  	const char *GetLastKnownPlaceName( void ) const	{ return m_szLastPlaceName; }	// return the last nav place name the player occupied
  
  	virtual void			CheckChatText( char *p, int bufsize ) {}
  
  	virtual void			CreateRagdollEntity( void ) { return; }
  
  	virtual void			HandleAnimEvent( animevent_t *pEvent );
  
  	virtual bool			ShouldAnnounceAchievement( void ){ return true; }
  
  #if defined USES_ECON_ITEMS
  	// Wearables
  	virtual void			EquipWearable( CEconWearable *pItem );
  	virtual void			RemoveWearable( CEconWearable *pItem );
  	void					PlayWearableAnimsForPlaybackEvent( wearableanimplayback_t iPlayback );
  #endif
  
  #ifdef MAPBASE
  	bool					ShouldUseVisibilityCache( CBaseEntity *pEntity );
  #endif
  
  public:
  	// Player Physics Shadow
  	void					SetupVPhysicsShadow( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity, CPhysCollide *pStandModel, const char *pStandHullName, CPhysCollide *pCrouchModel, const char *pCrouchHullName );
  	IPhysicsPlayerController* GetPhysicsController() { return m_pPhysicsController; }
  	virtual void			VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
  	void					VPhysicsUpdate( IPhysicsObject *pPhysics );
  	virtual void			VPhysicsShadowUpdate( IPhysicsObject *pPhysics );
  	virtual bool			IsFollowingPhysics( void ) { return false; }
  	bool					IsRideablePhysics( IPhysicsObject *pPhysics );
  	IPhysicsObject			*GetGroundVPhysics();
  
  	virtual void			Touch( CBaseEntity *pOther );
  	void					SetTouchedPhysics( bool bTouch );
  	bool					TouchedPhysics( void );
  	Vector					GetSmoothedVelocity( void );
  
  	virtual	void			RefreshCollisionBounds( void );
  	virtual void			InitVCollision( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity );
  	virtual void			VPhysicsDestroyObject();
  	void					SetVCollisionState( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity, int collisionState );
  	void					PostThinkVPhysics( void );
  	virtual void			UpdatePhysicsShadowToCurrentPosition();
  	void					UpdatePhysicsShadowToPosition( const Vector &vecAbsOrigin );
  	void					UpdateVPhysicsPosition( const Vector &position, const Vector &velocity, float secondsToArrival );
  
  	// Hint system
  	virtual CHintSystem		*Hints( void ) { return NULL; }
  	bool					ShouldShowHints( void ) { return Hints() ? Hints()->ShouldShowHints() : false; }
  	void					SetShowHints( bool bShowHints ) { if (Hints()) Hints()->SetShowHints( bShowHints ); }
  	bool 					HintMessage( int hint, bool bForce = false ) { return Hints() ? Hints()->HintMessage( hint, bForce ) : false; }
  	void 					HintMessage( const char *pMessage ) { if (Hints()) Hints()->HintMessage( pMessage ); }
  	void					StartHintTimer( int iHintID ) { if (Hints()) Hints()->StartHintTimer( iHintID ); }
  	void					StopHintTimer( int iHintID ) { if (Hints()) Hints()->StopHintTimer( iHintID ); }
  	void					RemoveHintTimer( int iHintID ) { if (Hints()) Hints()->RemoveHintTimer( iHintID ); }
  
  	// Accessor methods
  	int		FragCount() const		{ return m_iFrags; }
  	int		DeathCount() const		{ return m_iDeaths;}
  	bool	IsConnected() const		{ return m_iConnected != PlayerDisconnected; }
  	bool	IsDisconnecting() const	{ return m_iConnected == PlayerDisconnecting; }
  	bool	IsSuitEquipped() const	{ return m_Local.m_bWearingSuit; }
  	int		ArmorValue() const		{ return m_ArmorValue; }
  	bool	HUDNeedsRestart() const { return m_fInitHUD; }
  	float	MaxSpeed() const		{ return m_flMaxspeed; }
  	Activity GetActivity( ) const	{ return m_Activity; }
  	inline void SetActivity( Activity eActivity ) { m_Activity = eActivity; }
  	bool	IsPlayerLockedInPlace() const { return m_iPlayerLocked != 0; }
  	bool	IsObserver() const		{ return (m_afPhysicsFlags & PFLAG_OBSERVER) != 0; }
  	bool	IsOnTarget() const		{ return m_fOnTarget; }
  	float	MuzzleFlashTime() const { return m_flFlashTime; }
  	float	PlayerDrownTime() const	{ return m_AirFinished; }
  
  	int		GetObserverMode() const	{ return m_iObserverMode; }
  	CBaseEntity *GetObserverTarget() const	{ return m_hObserverTarget; }
  
  	// Round gamerules
  	virtual bool	IsReadyToPlay( void ) { return true; }
  	virtual bool	IsReadyToSpawn( void ) { return true; }
  	virtual bool	ShouldGainInstantSpawn( void ) { return false; }
  	virtual void	ResetPerRoundStats( void ) { return; }
  	void			AllowInstantSpawn( void ) { m_bAllowInstantSpawn = true; }
  
  	virtual void	ResetScores( void ) { ResetFragCount(); ResetDeathCount(); }
  	void	ResetFragCount();
  	void	IncrementFragCount( int nCount );
  
  	void	ResetDeathCount();
  	void	IncrementDeathCount( int nCount );
  
  	void	SetArmorValue( int value );
  	void	IncrementArmorValue( int nCount, int nMaxValue = -1 );
  
  	void	SetConnected( PlayerConnectedState iConnected ) { m_iConnected = iConnected; }
  	virtual void EquipSuit( bool bPlayEffects = true );
  	virtual void RemoveSuit( void );
  	void	SetMaxSpeed( float flMaxSpeed ) { m_flMaxspeed = flMaxSpeed; }
  
  	void	NotifyNearbyRadiationSource( float flRange );
  
  	void	SetAnimationExtension( const char *pExtension );
  
  	void	SetAdditionalPVSOrigin( const Vector &vecOrigin );
  	void	SetCameraPVSOrigin( const Vector &vecOrigin );
  	void	SetMuzzleFlashTime( float flTime );
  	void	SetUseEntity( CBaseEntity *pUseEntity );
  	CBaseEntity *GetUseEntity();
  
  	virtual float GetPlayerMaxSpeed();
  
  	// Used to set private physics flags PFLAG_*
  	void	SetPhysicsFlag( int nFlag, bool bSet );
  
  	void	AllowImmediateDecalPainting();
  
  	// Suicide...
  	virtual void CommitSuicide( bool bExplode = false, bool bForce = false );
  	virtual void CommitSuicide( const Vector &vecForce, bool bExplode = false, bool bForce = false );
  
  	// For debugging...
  	void	ForceOrigin( const Vector &vecOrigin );
  
  	// Bot accessors...
  	void	SetTimeBase( float flTimeBase );
  	float	GetTimeBase() const;
  	void	SetLastUserCommand( const CUserCmd &cmd );
  	const CUserCmd *GetLastUserCommand( void );
  	
  	virtual bool IsBot() const;		// IMPORTANT: This returns true for ANY type of bot. If your game uses different, incompatible types of bots check your specific bot type before casting
  	virtual bool IsBotOfType( int botType ) const;	// return true if this player is a bot of the specific type (zero is invalid)
  	virtual int GetBotType( void ) const;			// return a unique int representing the type of bot instance this is
  
  	bool	IsPredictingWeapons( void ) const; 
  	int		CurrentCommandNumber() const;
  	const CUserCmd *GetCurrentUserCommand() const;
  
  	int		GetFOV( void );														// Get the current FOV value
  	int		GetDefaultFOV( void ) const;										// Default FOV if not specified otherwise
  	int		GetFOVForNetworking( void );										// Get the current FOV used for network computations
  	bool	SetFOV( CBaseEntity *pRequester, int FOV, float zoomRate = 0.0f, int iZoomStart = 0 );	// Alters the base FOV of the player (must have a valid requester)
  	void	SetDefaultFOV( int FOV );											// Sets the base FOV if nothing else is affecting it by zooming
  	CBaseEntity *GetFOVOwner( void ) { return m_hZoomOwner; }
  	float	GetFOVDistanceAdjustFactor(); // shared between client and server
  	float	GetFOVDistanceAdjustFactorForNetworking();
  
  	int		GetImpulse( void ) const { return m_nImpulse; }
  
  	// Movement constraints
  	void	ActivateMovementConstraint( CBaseEntity *pEntity, const Vector &vecCenter, float flRadius, float flConstraintWidth, float flSpeedFactor );
  	void	DeactivateMovementConstraint( );
  
  	// talk control
  	void	NotePlayerTalked() { m_fLastPlayerTalkTime = gpGlobals->curtime; }
  	float	LastTimePlayerTalked() { return m_fLastPlayerTalkTime; }
  
  	void	DisableButtons( int nButtons );
  	void	EnableButtons( int nButtons );
  	void	ForceButtons( int nButtons );
  	void	UnforceButtons( int nButtons );
  
  	//---------------------------------
  	// Inputs
  	//---------------------------------
  	void	InputSetHealth( inputdata_t &inputdata );
  	void	InputSetHUDVisibility( inputdata_t &inputdata );
  	void	InputHandleMapEvent( inputdata_t &inputdata );
  #ifdef MAPBASE
  	void	InputSetSuppressAttacks( inputdata_t &inputdata );
  #endif
  
  	surfacedata_t *GetSurfaceData( void ) { return m_pSurfaceData; }
  	void SetLadderNormal( Vector vecLadderNormal ) { m_vecLadderNormal = vecLadderNormal; }
  
  	// Here so that derived classes can use the expresser
  	virtual CAI_Expresser *GetExpresser() { return NULL; };
  
  #if !defined(NO_STEAM)
  	//----------------------------
  	// Steam handling
  	bool		GetSteamID( CSteamID *pID );
  	uint64		GetSteamIDAsUInt64( void );
  #endif
  
  	float GetRemainingMovementTimeForUserCmdProcessing() const { return m_flMovementTimeForUserCmdProcessingRemaining; }
  	float ConsumeMovementTimeForUserCmdProcessing( float flTimeNeeded )
  	{
  		if ( m_flMovementTimeForUserCmdProcessingRemaining <= 0.0f )
  		{
  			return 0.0f;
  		}
  		else if ( flTimeNeeded > m_flMovementTimeForUserCmdProcessingRemaining + FLT_EPSILON )
  		{
  			float flResult = m_flMovementTimeForUserCmdProcessingRemaining;
  			m_flMovementTimeForUserCmdProcessingRemaining = 0.0f;
  			return flResult;
  		}
  		else
  		{
  			m_flMovementTimeForUserCmdProcessingRemaining -= flTimeNeeded;
  			if ( m_flMovementTimeForUserCmdProcessingRemaining < 0.0f )
  				m_flMovementTimeForUserCmdProcessingRemaining = 0.0f;
  			return flTimeNeeded;
  		}
  	}
  
  private:
  	// How much of a movement time buffer can we process from this user?
  	float				m_flMovementTimeForUserCmdProcessingRemaining;
  
  	// For queueing up CUserCmds and running them from PhysicsSimulate
  	int					GetCommandContextCount( void ) const;
  	CCommandContext		*GetCommandContext( int index );
  	CCommandContext		*AllocCommandContext( void );
  	void				RemoveCommandContext( int index );
  	void				RemoveAllCommandContexts( void );
  	CCommandContext		*RemoveAllCommandContextsExceptNewest( void );
  	void				ReplaceContextCommands( CCommandContext *ctx, CUserCmd *pCommands, int nCommands );
  
  	int					DetermineSimulationTicks( void );
  	void				AdjustPlayerTimeBase( int simulation_ticks );
  
  public:
  	
  
  
  	// Used by gamemovement to check if the entity is stuck.
  	int m_StuckLast;
  	
  	// FIXME: Make these protected or private!
  
  	// This player's data that should only be replicated to 
  	//  the player and not to other players.
  	CNetworkVarEmbedded( CPlayerLocalData, m_Local );
  
  #if defined USES_ECON_ITEMS
  	CNetworkVarEmbedded( CAttributeList,	m_AttributeList );
  #endif
  
  	void InitFogController( void );
  	void InputSetFogController( inputdata_t &inputdata );
  
  	// Used by env_soundscape_triggerable to manage when the player is touching multiple
  	// soundscape triggers simultaneously.
  	// The one at the HEAD of the list is always the current soundscape for the player.
  	CUtlVector<EHANDLE> m_hTriggerSoundscapeList;
  
  	// Player data that's sometimes needed by the engine
  	CNetworkVarEmbedded( CPlayerState, pl );
  
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_fFlags );
  
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_vecViewOffset );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_flFriction );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iAmmo );
  	
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_hGroundEntity );
  
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_lifeState );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iHealth );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_vecBaseVelocity );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_nNextThinkTick );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_vecVelocity );
  	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_nWaterLevel );
  	
  	int						m_nButtons;
  	int						m_afButtonPressed;
  	int						m_afButtonReleased;
  	int						m_afButtonLast;
  	int						m_afButtonDisabled;	// A mask of input flags that are cleared automatically
  	int						m_afButtonForced;	// These are forced onto the player's inputs
  
  	CNetworkVar( bool, m_fOnTarget );		//Is the crosshair on a target?
  
  	char					m_szAnimExtension[32];
  
  	int						m_nUpdateRate;		// user snapshot rate cl_updaterate
  	float					m_fLerpTime;		// users cl_interp
  	bool					m_bLagCompensation;	// user wants lag compenstation
  	bool					m_bPredictWeapons; //  user has client side predicted weapons
  	
  	float		GetDeathTime( void ) { return m_flDeathTime; }
  
  	void		ClearZoomOwner( void );
  
  	void		SetPreviouslyPredictedOrigin( const Vector &vecAbsOrigin );
  	const Vector &GetPreviouslyPredictedOrigin() const;
  	float		GetFOVTime( void ){ return m_flFOVTime; }
  
  	void		AdjustDrownDmg( int nAmount );
  
  #if defined USES_ECON_ITEMS
  	CEconWearable			*GetWearable( int i ) { return m_hMyWearables[i]; }
  	int						GetNumWearables( void ) { return m_hMyWearables.Count(); }
  #endif
  
  #ifdef MAPBASE
  	bool					m_bInTriggerFall;
  #endif
  
  private:
  
  	Activity				m_Activity;
  
  protected:
  
  	void					CalcPlayerView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  	void					CalcVehicleView( IServerVehicle *pVehicle, Vector& eyeOrigin, QAngle& eyeAngles, 	
  								float& zNear, float& zFar, float& fov );
  	void					CalcObserverView( Vector& eyeOrigin, QAngle& eyeAngles, float& fov );
  	void					CalcViewModelView( const Vector& eyeOrigin, const QAngle& eyeAngles);
  
  	virtual	void			Internal_HandleMapEvent( inputdata_t &inputdata ){}
  
  	// FIXME: Make these private! (tf_player uses them)
  
  	// Secondary point to derive PVS from when zoomed in with binoculars/sniper rifle.  The PVS is 
  	//  a merge of the standing origin and this additional origin
  	Vector					m_vecAdditionalPVSOrigin; 
  	// Extra PVS origin if we are using a camera object
  	Vector					m_vecCameraPVSOrigin;
  
  	CNetworkHandle( CBaseEntity, m_hUseEntity );			// the player is currently controlling this entity because of +USE latched, NULL if no entity
  
  	int						m_iTrain;				// Train control position
  
  	float					m_iRespawnFrames;	// used in PlayerDeathThink() to make sure players can always respawn
   	unsigned int			m_afPhysicsFlags;	// physics flags - set when 'normal' physics should be revisited or overriden
  	
  	// Vehicles
  	CNetworkHandle( CBaseEntity, m_hVehicle );
  
  	int						m_iVehicleAnalogBias;
  
  	void					UpdateButtonState( int nUserCmdButtonMask );
  
  	bool	m_bPauseBonusProgress;
  	CNetworkVar( int, m_iBonusProgress );
  	CNetworkVar( int, m_iBonusChallenge );
  
  	int						m_lastDamageAmount;		// Last damage taken
  
  	Vector					m_DmgOrigin;
  	float					m_DmgTake;
  	float					m_DmgSave;
  	int						m_bitsDamageType;	// what types of damage has player taken
  	int						m_bitsHUDDamage;	// Damage bits for the current fame. These get sent to the hud via gmsgDamage
  
  	CNetworkVar( float, m_flDeathTime );		// the time at which the player died  (used in PlayerDeathThink())
  	float					m_flDeathAnimTime;	// the time at which the player finished their death anim (used in PlayerDeathThink() and ShouldTransmit())
  
  	CNetworkVar( int, m_iObserverMode );	// if in spectator mode != 0
  	CNetworkVar( int,	m_iFOV );			// field of view
  	CNetworkVar( int,	m_iDefaultFOV );	// default field of view
  	CNetworkVar( int,	m_iFOVStart );		// What our FOV started at
  	CNetworkVar( float,	m_flFOVTime );		// Time our FOV change started
  	
  	int						m_iObserverLastMode; // last used observer mode
  	CNetworkHandle( CBaseEntity, m_hObserverTarget );	// entity handle to m_iObserverTarget
  	bool					m_bForcedObserverMode; // true, player was forced by invalid targets to switch mode
  	
  	CNetworkHandle( CBaseEntity, 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
  
  	float					m_tbdPrev;				// Time-based damage timer
  	int						m_idrowndmg;			// track drowning damage taken
  	int						m_idrownrestored;		// track drowning damage restored
  	int						m_nPoisonDmg;			// track recoverable poison damage taken
  	int						m_nPoisonRestored;		// track poison damage restored
  	// NOTE: bits damage type appears to only be used for time-based damage
  	BYTE					m_rgbTimeBasedDamage[CDMG_TIMEBASED];
  
  	// Player Physics Shadow
  	int						m_vphysicsCollisionState;
  
  	virtual int SpawnArmorValue( void ) const { return 0; }
  
  	float					m_fNextSuicideTime; // the time after which the player can next use the suicide command
  	int						m_iSuicideCustomKillFlags;
  
  	// Replay mode	
  	float					m_fDelay;			// replay delay in seconds
  	float					m_fReplayEnd;		// time to stop replay mode
  	int						m_iReplayEntity;	// follow this entity in replay
  
  private:
  	void HandleFuncTrain();
  
  // DATA
  private:
  	CUtlVector< CCommandContext > m_CommandContext;
  	// Player Physics Shadow
  
  protected: //used to be private, but need access for portal mod (Dave Kircher)
  	IPhysicsPlayerController	*m_pPhysicsController;
  	IPhysicsObject				*m_pShadowStand;
  	IPhysicsObject				*m_pShadowCrouch;
  	Vector						m_oldOrigin;
  	Vector						m_vecSmoothedVelocity;
  	bool						m_touchedPhysObject;
  	bool						m_bPhysicsWasFrozen;
  
  private:
  
  	int						m_iPlayerSound;// the index of the sound list slot reserved for this player
  	int						m_iTargetVolume;// ideal sound volume. 
  	
  	int						m_rgItems[MAX_ITEMS];
  
  	// these are time-sensitive things that we keep track of
  	float					m_flSwimTime;		// how long player has been underwater
  	float					m_flDuckTime;		// how long we've been ducking
  	float					m_flDuckJumpTime;	
  
  	float					m_flSuitUpdate;					// when to play next suit update
  	int						m_rgSuitPlayList[CSUITPLAYLIST];// next sentencenum to play for suit update
  	int						m_iSuitPlayNext;				// next sentence slot for queue storage;
  	int						m_rgiSuitNoRepeat[CSUITNOREPEAT];		// suit sentence no repeat list
  	float					m_rgflSuitNoRepeatTime[CSUITNOREPEAT];	// how long to wait before allowing repeat
  
  	float					m_flgeigerRange;		// range to nearest radiation source
  	float					m_flgeigerDelay;		// delay per update of range msg to client
  	int						m_igeigerRangePrev;
  
  	bool					m_fInitHUD;				// True when deferred HUD restart msg needs to be sent
  	bool					m_fGameHUDInitialized;
  	bool					m_fWeapon;				// Set this to FALSE to force a reset of the current weapon HUD info
  
  	int						m_iUpdateTime;		// stores the number of frame ticks before sending HUD update messages
  	int						m_iClientBattery;	// the Battery currently known by the client.  If this changes, send a new
  
  	// Autoaim data
  	QAngle					m_vecAutoAim;
  	int						m_lastx, m_lasty;	// These are the previous update's crosshair angles, DON"T SAVE/RESTORE
  
  	int						m_iFrags;
  	int						m_iDeaths;
  
  	float					m_flNextDecalTime;// next time this player can spray a decal
  
  	// Team Handling
  	// char					m_szTeamName[TEAM_NAME_LENGTH];
  
  	// Multiplayer handling
  	PlayerConnectedState	m_iConnected;
  
  	// from edict_t
  	// CBasePlayer doesn't send this but CCSPlayer does.
  	CNetworkVarForDerived( int, m_ArmorValue );
  	float					m_AirFinished;
  	float					m_PainFinished;
  
  	// player locking
  	int						m_iPlayerLocked;
  		
  protected:
  	// the player's personal view model
  	typedef CHandle<CBaseViewModel> CBaseViewModelHandle;
  	CNetworkArray( CBaseViewModelHandle, m_hViewModel, MAX_VIEWMODELS );
  
  	// Last received usercmd (in case we drop a lot of packets )
  	CUserCmd				m_LastCmd;
  	CUserCmd				*m_pCurrentCommand;
  
  	float					m_flStepSoundTime;	// time to check for next footstep sound
  
  	bool					m_bAllowInstantSpawn;
  
  #if defined USES_ECON_ITEMS
  	// Wearables
  	CUtlVector<CHandle<CEconWearable > >	m_hMyWearables;
  #endif
  
  private:
  
  // Replicated to all clients
  	CNetworkVar( float, m_flMaxspeed );
  	
  // Not transmitted
  	float					m_flWaterJumpTime;  // used to be called teleport_time
  	Vector					m_vecWaterJumpVel;
  	int						m_nImpulse;
  	float					m_flSwimSoundTime;
  	Vector					m_vecLadderNormal;
  
  	float					m_flFlashTime;
  	int						m_nDrownDmgRate;		// Drowning damage in points per second without air.
  
  	int						m_nNumCrouches;			// Number of times we've crouched (for hinting)
  	bool					m_bDuckToggled;		// If true, the player is crouching via a toggle
  
  public:
  	bool					GetToggledDuckState( void ) { return m_bDuckToggled; }
  	void					ToggleDuck( void );
  	float					GetStickDist( void );
  
  	float					m_flForwardMove;
  	float					m_flSideMove;
  	int						m_nNumCrateHudHints;
  
  #ifdef MAPBASE
  	CNetworkVar( bool, m_bDrawPlayerModelExternally );
  #endif
  
  private:
  
  	// Used in test code to teleport the player to random locations in the map.
  	Vector					m_vForcedOrigin;
  	bool					m_bForceOrigin;	
  
  	// Clients try to run on their own realtime clock, this is this client's clock
  	CNetworkVar( int, m_nTickBase );
  
  	bool					m_bGamePaused;
  	float					m_fLastPlayerTalkTime;
  	
  	CNetworkVar( CBaseCombatWeaponHandle, m_hLastWeapon );
  
  #if !defined( NO_ENTITY_PREDICTION )
  	CUtlVector< CHandle< CBaseEntity > > m_SimulatedByThisPlayer;
  #endif
  
  	float					m_flOldPlayerZ;
  	float					m_flOldPlayerViewOffsetZ;
  
  	bool					m_bPlayerUnderwater;
  
  	EHANDLE					m_hViewEntity;
  
  	// Movement constraints
  	CNetworkHandle( CBaseEntity, m_hConstraintEntity );
  	CNetworkVector( m_vecConstraintCenter );
  	CNetworkVar( float, m_flConstraintRadius );
  	CNetworkVar( float, m_flConstraintWidth );
  	CNetworkVar( float, m_flConstraintSpeedFactor );
  
  	friend class CPlayerMove;
  	friend class CPlayerClass;
  
  	// Player name
  	char					m_szNetname[MAX_PLAYER_NAME_LENGTH];
  
  protected:
  	// 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;
  	
  	// Accessors for gamemovement
  	bool IsDucked( void ) const { return m_Local.m_bDucked; }
  	bool IsDucking( void ) const { return m_Local.m_bDucking; }
  	float GetStepSize( void ) const { return m_Local.m_flStepSize; }
  
  	CNetworkVar( float,  m_flLaggedMovementValue );
  
  	// These are generated while running usercmds, then given to UpdateVPhysicsPosition after running all queued commands.
  	Vector m_vNewVPhysicsPosition;
  	Vector m_vNewVPhysicsVelocity;
  	
  	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;			// FOV of the vehicle driver
  	int		m_nVehicleViewSavedFrame;	// Used to mark which frame was the last one the view was calculated for
  
  	Vector m_vecPreviouslyPredictedOrigin; // Used to determine if non-gamemovement game code has teleported, or tweaked the player's origin
  	int		m_nBodyPitchPoseParam;
  
  	CNetworkString( m_szLastPlaceName, MAX_PLACE_NAME_LENGTH );
  
  	char m_szNetworkIDString[MAX_NETWORKID_LENGTH];
  	CPlayerInfo m_PlayerInfo;
  
  	// Texture names and surface data, used by CGameMovement
  	int				m_surfaceProps;
  	surfacedata_t*	m_pSurfaceData;
  	float			m_surfaceFriction;
  	char			m_chTextureType;
  	char			m_chPreviousTextureType;	// Separate from m_chTextureType. This is cleared if the player's not on the ground.
  
  	bool			m_bSinglePlayerGameEnding;
  
  public:
  
  	float  GetLaggedMovementValue( void ){ return m_flLaggedMovementValue;	}
  	void   SetLaggedMovementValue( float flValue ) { m_flLaggedMovementValue = flValue;	}
  
  	inline bool IsAutoKickDisabled( void ) const;
  	inline void DisableAutoKick( bool disabled );
  
  	void	DumpPerfToRecipient( CBasePlayer *pRecipient, int nMaxRecords );
  	// NVNT returns true if user has a haptic device
  	virtual bool HasHaptics(){return m_bhasHaptics;}
  	// NVNT sets weather a user should receive haptic device messages.
  	virtual void SetHaptics(bool has) { m_bhasHaptics = has;}
  private:
  	// NVNT member variable holding if this user is using a haptic device.
  	bool m_bhasHaptics;
  
  	bool m_autoKickDisabled;
  
  	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 ];
  
  	CUtlLinkedList< CPlayerSimInfo >  m_vecPlayerSimInfo;
  	CUtlLinkedList< CPlayerCmdInfo >  m_vecPlayerCmdInfo;
  
  	IntervalTimer m_weaponFiredTimer;
  
  	// Store the last time we successfully processed a usercommand
  	float			m_flLastUserCommandTime;
  
  public:
  	virtual unsigned int PlayerSolidMask( bool brushOnly = false ) const;	// returns the solid mask for the given player, so bots can have a more-restrictive set
  
  };
  
  typedef CHandle<CBasePlayer> CBasePlayerHandle;
  
  EXTERN_SEND_TABLE(DT_BasePlayer)
  
  
  
  //-----------------------------------------------------------------------------
  // Inline methods
  //-----------------------------------------------------------------------------
  inline bool CBasePlayer::IsBotOfType( int botType ) const
  {
  	// bot type of zero is invalid
  	return ( GetBotType() != 0 ) && ( GetBotType() == botType );
  }
  
  inline int CBasePlayer::GetBotType( void ) const
  {
  	return 0;
  }
  
  inline bool CBasePlayer::IsAutoKickDisabled( void ) const
  {
  	return m_autoKickDisabled;
  }
  
  inline void CBasePlayer::DisableAutoKick( bool disabled )
  {
  	m_autoKickDisabled = disabled;
  }
  
  inline void CBasePlayer::SetAdditionalPVSOrigin( const Vector &vecOrigin ) 
  { 
  	m_vecAdditionalPVSOrigin = vecOrigin; 
  }
  
  inline void CBasePlayer::SetCameraPVSOrigin( const Vector &vecOrigin ) 
  { 
  	m_vecCameraPVSOrigin = vecOrigin; 
  }
  
  inline void CBasePlayer::SetMuzzleFlashTime( float flTime ) 
  { 
  	m_flFlashTime = flTime; 
  }
  
  inline void CBasePlayer::SetUseEntity( CBaseEntity *pUseEntity ) 
  { 
  	m_hUseEntity = pUseEntity; 
  }
  
  inline CBaseEntity *CBasePlayer::GetUseEntity() 
  { 
  	return m_hUseEntity;
  }
  
  // Bot accessors...
  inline void CBasePlayer::SetTimeBase( float flTimeBase ) 
  { 
  	m_nTickBase = TIME_TO_TICKS( flTimeBase ); 
  }
  
  inline void CBasePlayer::SetLastUserCommand( const CUserCmd &cmd ) 
  { 
  	m_LastCmd = cmd; 
  }
  
  inline CUserCmd const *CBasePlayer::GetLastUserCommand( void )
  {
  	return &m_LastCmd;
  }
  
  inline bool CBasePlayer::IsPredictingWeapons( void ) const 
  {
  	return m_bPredictWeapons;
  }
  
  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;
  }
  
  inline IServerVehicle *CBasePlayer::GetVehicle() 
  { 
  	CBaseEntity *pVehicleEnt = m_hVehicle.Get();
  	return pVehicleEnt ? pVehicleEnt->GetServerVehicle() : NULL;
  }
  
  inline CBaseEntity *CBasePlayer::GetVehicleEntity() 
  { 
  	return m_hVehicle.Get();
  }
  
  inline bool CBasePlayer::IsInAVehicle( void ) const 
  { 
  	return ( NULL != m_hVehicle.Get() ) ? true : false; 
  }
  
  inline void CBasePlayer::SetTouchedPhysics( bool bTouch ) 
  { 
  	m_touchedPhysObject = bTouch; 
  }
  
  inline bool CBasePlayer::TouchedPhysics( void )			
  { 
  	return m_touchedPhysObject; 
  }
  
  inline void CBasePlayer::OnMyWeaponFired( CBaseCombatWeapon *weapon )
  {
  	m_weaponFiredTimer.Start();
  }
  
  inline float CBasePlayer::GetTimeSinceWeaponFired( void ) const
  {
  	return m_weaponFiredTimer.GetElapsedTime();
  }
  
  inline bool CBasePlayer::IsFiringWeapon( void ) const
  {
  	return m_weaponFiredTimer.HasStarted() && m_weaponFiredTimer.IsLessThen( 1.0f );
  }
  
  
  
  //-----------------------------------------------------------------------------
  // Converts an entity to a player
  //-----------------------------------------------------------------------------
  inline CBasePlayer *ToBasePlayer( CBaseEntity *pEntity )
  {
  	if ( !pEntity || !pEntity->IsPlayer() )
  		return NULL;
  #if _DEBUG
  	return dynamic_cast<CBasePlayer *>( pEntity );
  #else
  	return static_cast<CBasePlayer *>( pEntity );
  #endif
  }
  
  inline const CBasePlayer *ToBasePlayer( const CBaseEntity *pEntity )
  {
  	if ( !pEntity || !pEntity->IsPlayer() )
  		return NULL;
  #if _DEBUG
  	return dynamic_cast<const CBasePlayer *>( pEntity );
  #else
  	return static_cast<const CBasePlayer *>( pEntity );
  #endif
  }
  
  
  //--------------------------------------------------------------------------------------------------------------
  /**
   * DEPRECATED: Use CollectPlayers() instead.
   * Iterate over all active players in the game, invoking functor on each.
   * If functor returns false, stop iteration and return false.
   */
  template < typename Functor >
  bool ForEachPlayer( Functor &func )
  {
  	for( int i=1; i<=gpGlobals->maxClients; ++i )
  	{
  		CBasePlayer *player = static_cast<CBasePlayer *>( UTIL_PlayerByIndex( i ) );
  
  		if (player == NULL)
  			continue;
  
  		if (FNullEnt( player->edict() ))
  			continue;
  
  		if (!player->IsPlayer())
  			continue;
  
  		if( !player->IsConnected() )
  			continue;
  
  		if (func( player ) == false)
  			return false;
  	}
  
  	return true;
  }
  
  
  //-----------------------------------------------------------------------------------------------
  /**
   * The interface for an iterative player functor
   */
  class IPlayerFunctor
  {
  public:
  	virtual void OnBeginIteration( void )						{ }		// invoked once before iteration begins
  	
  	virtual bool operator() ( CBasePlayer *player ) = 0;
  	
  	virtual void OnEndIteration( bool allElementsIterated )		{ }		// invoked once after iteration is complete whether successful or not
  };
  
  
  //--------------------------------------------------------------------------------------------------------------
  /**
   * DEPRECATED: Use CollectPlayers() instead.
   * Specialization of ForEachPlayer template for IPlayerFunctors
   */
  template <>
  inline bool ForEachPlayer( IPlayerFunctor &func )
  {
  	func.OnBeginIteration();
  	
  	bool isComplete = true;
  	
  	for( int i=1; i<=gpGlobals->maxClients; ++i )
  	{
  		CBasePlayer *player = static_cast<CBasePlayer *>( UTIL_PlayerByIndex( i ) );
  
  		if (player == NULL)
  			continue;
  
  		if (FNullEnt( player->edict() ))
  			continue;
  
  		if (!player->IsPlayer())
  			continue;
  
  		if( !player->IsConnected() )
  			continue;
  
  		if (func( player ) == false)
  		{
  			isComplete = false;
  			break;
  		}
  	}
  	
  	func.OnEndIteration( isComplete );
  
  	return isComplete;
  }
  
  //--------------------------------------------------------------------------------------------------------------
  //
  // Collect all valid, connected players into given vector.
  // Returns number of players collected.
  //
  #define COLLECT_ONLY_LIVING_PLAYERS true
  #define APPEND_PLAYERS true
  template < typename T >
  int CollectPlayers( CUtlVector< T * > *playerVector, int team = TEAM_ANY, bool isAlive = false, bool shouldAppend = false )
  {
  	if ( !shouldAppend )
  	{
  		playerVector->RemoveAll();
  	}
  
  	for( int i=1; i<=gpGlobals->maxClients; ++i )
  	{
  		CBasePlayer *player = UTIL_PlayerByIndex( i );
  
  		if ( player == NULL )
  			continue;
  
  		if ( FNullEnt( player->edict() ) )
  			continue;
  
  		if ( !player->IsPlayer() )
  			continue;
  
  		if ( !player->IsConnected() )
  			continue;
  
  		if ( team != TEAM_ANY && player->GetTeamNumber() != team )
  			continue;
  
  		if ( isAlive && !player->IsAlive() )
  			continue;
  
  		playerVector->AddToTail( assert_cast< T * >( player ) );
  	}
  
  	return playerVector->Count();
  }
  
  template < typename T >
  int CollectHumanPlayers( CUtlVector< T * > *playerVector, int team = TEAM_ANY, bool isAlive = false, bool shouldAppend = false )
  {
  	if ( !shouldAppend )
  	{
  		playerVector->RemoveAll();
  	}
  
  	for( int i=1; i<=gpGlobals->maxClients; ++i )
  	{
  		CBasePlayer *player = UTIL_PlayerByIndex( i );
  
  		if ( player == NULL )
  			continue;
  
  		if ( FNullEnt( player->edict() ) )
  			continue;
  
  		if ( !player->IsPlayer() )
  			continue;
  
  		if ( player->IsBot() )
  			continue;
  
  		if ( !player->IsConnected() )
  			continue;
  
  		if ( team != TEAM_ANY && player->GetTeamNumber() != team )
  			continue;
  
  		if ( isAlive && !player->IsAlive() )
  			continue;
  
  		playerVector->AddToTail( assert_cast< T * >( player ) );
  	}
  
  	return playerVector->Count();
  }
  
  enum
  {
  	VEHICLE_ANALOG_BIAS_NONE = 0,
  	VEHICLE_ANALOG_BIAS_FORWARD,
  	VEHICLE_ANALOG_BIAS_REVERSE,
  };
  
  #endif // PLAYER_H
  