|
|
//========= 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(); 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 );
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() const { 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 );
// 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 *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
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 ¶ms );
float GetAutoaimScore( const Vector &eyePosition, const Vector &viewDir, const Vector &vecTarget, CBaseEntity *pTarget, float fScale, CBaseCombatWeapon *pActiveWeapon ); QAngle AutoaimDeflection( Vector &vecSrc, autoaim_params_t ¶ms ); 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 ) OVERRIDE { ChangeTeam( iTeamNum, false, false ); } virtual void ChangeTeam( int iTeamNum, bool bAutoTeam, bool bSilent, bool bAutoBalance = false );
// 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 );
#if defined USES_ECON_ITEMS
// Wearables
virtual void EquipWearable( CEconWearable *pItem ); virtual void RemoveWearable( CEconWearable *pItem ); void PlayWearableAnimsForPlaybackEvent( wearableanimplayback_t iPlayback ); #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 GetLockViewanglesTickNumber() const { return m_iLockViewanglesTickNumber; } QAngle GetLockViewanglesData() const { return m_qangLockViewangles; }
bool IsLerpingFOV( void ) 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 );
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: // How long since this player last interacted with something the game considers an objective/target/goal
float GetTimeSinceLastObjective( void ) const { return ( m_flLastObjectiveTime == -1.f ) ? 999.f : gpGlobals->curtime - m_flLastObjectiveTime; } void SetLastObjectiveTime( float flTime ) { m_flLastObjectiveTime = flTime; }
// 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]; } const CEconWearable *GetWearable( int i ) const { return m_hMyWearables[i]; } int GetNumWearables( void ) const { return m_hMyWearables.Count(); } #endif
private:
Activity m_Activity; float m_flLastObjectiveTime; // Last curtime player touched/killed something the gamemode considers an objective
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; int m_iLockViewanglesTickNumber; QAngle m_qangLockViewangles;
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;
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;
// used to prevent achievement announcement spam
CUtlVector< float > m_flAchievementTimes;
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
|