You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1552 lines
53 KiB
1552 lines
53 KiB
//========= 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() { 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 *Weapon_GetLast( 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 ) { 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 |
|
|
|
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 ); |
|
|
|
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 |
|
|
|
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; |
|
|
|
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
|
|
|