Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.

1117 lines
37 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Player for HL1.
//
// $NoKeywords: $
//=============================================================================//
#ifndef CS_PLAYER_H
#define CS_PLAYER_H
#pragma once
#include "basemultiplayerplayer.h"
#include "server_class.h"
#include "cs_playeranimstate.h"
#include "cs_shareddefs.h"
#include "cs_autobuy.h"
#include "utldict.h"
class CWeaponCSBase;
class CMenu;
class CHintMessageQueue;
class CNavArea;
#include "cs_weapon_parse.h"
void UTIL_AwardMoneyToTeam( int iAmount, int iTeam, CBaseEntity *pIgnore );
#define MENU_STRING_BUFFER_SIZE 1024
#define MENU_MSG_TEXTCHUNK_SIZE 50
enum
{
MIN_NAME_CHANGE_INTERVAL = 10, // minimum number of seconds between name changes
NAME_CHANGE_HISTORY_SIZE = 5, // number of times a player can change names in NAME_CHANGE_HISTORY_INTERVAL
NAME_CHANGE_HISTORY_INTERVAL = 600, // no more than NAME_CHANGE_HISTORY_SIZE name changes can be made in this many seconds
};
extern ConVar bot_mimic;
// Function table for each player state.
class CCSPlayerStateInfo
{
public:
CSPlayerState m_iPlayerState;
const char *m_pStateName;
void (CCSPlayer::*pfnEnterState)(); // Init and deinit the state.
void (CCSPlayer::*pfnLeaveState)();
void (CCSPlayer::*pfnPreThink)(); // Do a PreThink() in this state.
};
//=======================================
//Record of either damage taken or given.
//Contains the player name that we hurt or that hurt us,
//and the total damage
//=======================================
class CDamageRecord
{
public:
CDamageRecord( const char *name, int iDamage, int iCounter )
{
Q_strncpy( m_szPlayerName, name, sizeof(m_szPlayerName) );
m_iDamage = iDamage;
m_iNumHits = 1;
m_iLastBulletUpdate = iCounter;
}
void AddDamage( int iDamage, int iCounter )
{
m_iDamage += iDamage;
if ( m_iLastBulletUpdate != iCounter )
m_iNumHits++;
m_iLastBulletUpdate = iCounter;
}
char *GetPlayerName( void ) { return m_szPlayerName; }
int GetDamage( void ) { return m_iDamage; }
int GetNumHits( void ) { return m_iNumHits; }
private:
char m_szPlayerName[MAX_PLAYER_NAME_LENGTH];
int m_iDamage; //how much damage was done
int m_iNumHits; //how many hits
int m_iLastBulletUpdate; // update counter
};
// Message display history (CCSPlayer::m_iDisplayHistoryBits)
// These bits are set when hint messages are displayed, and cleared at
// different times, according to the DHM_xxx bitmasks that follow
#define DHF_ROUND_STARTED ( 1 << 1 )
#define DHF_HOSTAGE_SEEN_FAR ( 1 << 2 )
#define DHF_HOSTAGE_SEEN_NEAR ( 1 << 3 )
#define DHF_HOSTAGE_USED ( 1 << 4 )
#define DHF_HOSTAGE_INJURED ( 1 << 5 )
#define DHF_HOSTAGE_KILLED ( 1 << 6 )
#define DHF_FRIEND_SEEN ( 1 << 7 )
#define DHF_ENEMY_SEEN ( 1 << 8 )
#define DHF_FRIEND_INJURED ( 1 << 9 )
#define DHF_FRIEND_KILLED ( 1 << 10 )
#define DHF_ENEMY_KILLED ( 1 << 11 )
#define DHF_BOMB_RETRIEVED ( 1 << 12 )
#define DHF_AMMO_EXHAUSTED ( 1 << 15 )
#define DHF_IN_TARGET_ZONE ( 1 << 16 )
#define DHF_IN_RESCUE_ZONE ( 1 << 17 )
#define DHF_IN_ESCAPE_ZONE ( 1 << 18 ) // unimplemented
#define DHF_IN_VIPSAFETY_ZONE ( 1 << 19 ) // unimplemented
#define DHF_NIGHTVISION ( 1 << 20 )
#define DHF_HOSTAGE_CTMOVE ( 1 << 21 )
#define DHF_SPEC_DUCK ( 1 << 22 )
// DHF_xxx bits to clear when the round restarts
#define DHM_ROUND_CLEAR ( \
DHF_ROUND_STARTED | \
DHF_HOSTAGE_KILLED | \
DHF_FRIEND_KILLED | \
DHF_BOMB_RETRIEVED )
// DHF_xxx bits to clear when the player is restored
#define DHM_CONNECT_CLEAR ( \
DHF_HOSTAGE_SEEN_FAR | \
DHF_HOSTAGE_SEEN_NEAR | \
DHF_HOSTAGE_USED | \
DHF_HOSTAGE_INJURED | \
DHF_FRIEND_SEEN | \
DHF_ENEMY_SEEN | \
DHF_FRIEND_INJURED | \
DHF_ENEMY_KILLED | \
DHF_AMMO_EXHAUSTED | \
DHF_IN_TARGET_ZONE | \
DHF_IN_RESCUE_ZONE | \
DHF_IN_ESCAPE_ZONE | \
DHF_IN_VIPSAFETY_ZONE | \
DHF_HOSTAGE_CTMOVE | \
DHF_SPEC_DUCK )
// radio messages (these must be kept in sync with actual radio) -------------------------------------
enum RadioType
{
RADIO_INVALID = 0,
RADIO_START_1, ///< radio messages between this and RADIO_START_2 and part of Radio1()
RADIO_COVER_ME,
RADIO_YOU_TAKE_THE_POINT,
RADIO_HOLD_THIS_POSITION,
RADIO_REGROUP_TEAM,
RADIO_FOLLOW_ME,
RADIO_TAKING_FIRE,
RADIO_START_2, ///< radio messages between this and RADIO_START_3 are part of Radio2()
RADIO_GO_GO_GO,
RADIO_TEAM_FALL_BACK,
RADIO_STICK_TOGETHER_TEAM,
RADIO_GET_IN_POSITION_AND_WAIT,
RADIO_STORM_THE_FRONT,
RADIO_REPORT_IN_TEAM,
RADIO_START_3, ///< radio messages above this are part of Radio3()
RADIO_AFFIRMATIVE,
RADIO_ENEMY_SPOTTED,
RADIO_NEED_BACKUP,
RADIO_SECTOR_CLEAR,
RADIO_IN_POSITION,
RADIO_REPORTING_IN,
RADIO_GET_OUT_OF_THERE,
RADIO_NEGATIVE,
RADIO_ENEMY_DOWN,
RADIO_END,
RADIO_NUM_EVENTS
};
extern const char *RadioEventName[ RADIO_NUM_EVENTS+1 ];
/**
* Convert name to RadioType
*/
extern RadioType NameToRadioEvent( const char *name );
enum BuyResult_e
{
BUY_BOUGHT,
BUY_ALREADY_HAVE,
BUY_CANT_AFFORD,
BUY_PLAYER_CANT_BUY, // not in the buy zone, is the VIP, is past the timelimit, etc
BUY_NOT_ALLOWED, // weapon is restricted by VIP mode, team, etc
BUY_INVALID_ITEM,
};
//=============================================================================
// HPE_BEGIN:
//=============================================================================
// [tj] The phases for the "Goose Chase" achievement
enum GooseChaseAchievementStep
{
GC_NONE,
GC_SHOT_DURING_DEFUSE,
GC_STOPPED_AFTER_GETTING_SHOT
};
// [tj] The phases for the "Defuse Defense" achievement
enum DefuseDefenseAchivementStep
{
DD_NONE,
DD_STARTED_DEFUSE,
DD_KILLED_TERRORIST
};
//=============================================================================
// HPE_END
//=============================================================================
//=============================================================================
// >> CounterStrike player
//=============================================================================
class CCSPlayer : public CBaseMultiplayerPlayer, public ICSPlayerAnimStateHelpers
{
public:
DECLARE_CLASS( CCSPlayer, CBaseMultiplayerPlayer );
DECLARE_SERVERCLASS();
DECLARE_PREDICTABLE();
DECLARE_DATADESC();
CCSPlayer();
~CCSPlayer();
static CCSPlayer *CreatePlayer( const char *className, edict_t *ed );
static CCSPlayer* Instance( int iEnt );
virtual void Precache();
virtual void Spawn();
virtual void InitialSpawn( void );
virtual void CheatImpulseCommands( int iImpulse );
virtual void PlayerRunCommand( CUserCmd *ucmd, IMoveHelper *moveHelper );
virtual void PostThink();
virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo );
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
virtual void Event_Killed( const CTakeDamageInfo &info );
//=============================================================================
// HPE_BEGIN:
// [tj] We have a custom implementation so we can check for achievements.
//=============================================================================
virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info );
//=============================================================================
// HPE_END
//=============================================================================
virtual void TraceAttack( const CTakeDamageInfo &inputInfo, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
virtual CBaseEntity *GiveNamedItem( const char *pszName, int iSubType = 0 );
virtual bool IsBeingGivenItem() const { return m_bIsBeingGivenItem; }
virtual CBaseEntity *FindUseEntity( void );
virtual bool IsUseableEntity( CBaseEntity *pEntity, unsigned int requiredCaps );
virtual void CreateViewModel( int viewmodelindex = 0 );
virtual void ShowViewPortPanel( const char * name, bool bShow = true, KeyValues *data = NULL );
// This passes the event to the client's and server's CPlayerAnimState.
void DoAnimationEvent( PlayerAnimEvent_t event, int nData = 0 );
// from CBasePlayer
virtual void SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs, int pvssize );
virtual int GetNextObserverSearchStartPoint( bool bReverse );
// In shared code.
public:
// ICSPlayerAnimState overrides.
virtual CWeaponCSBase* CSAnim_GetActiveWeapon();
virtual bool CSAnim_CanMove();
virtual float GetPlayerMaxSpeed();
void FireBullet(
Vector vecSrc,
const QAngle &shootAngles,
float flDistance,
int iPenetration,
int iBulletType,
int iDamage,
float flRangeModifier,
CBaseEntity *pevAttacker,
bool bDoEffects,
float xSpread, float ySpread );
void KickBack(
float up_base,
float lateral_base,
float up_modifier,
float lateral_modifier,
float up_max,
float lateral_max,
int direction_change );
void GetBulletTypeParameters(
int iBulletType,
float &fPenetrationPower,
float &flPenetrationDistance );
// Returns true if the player is allowed to move.
bool CanMove() const;
void OnJump( float fImpulse );
void OnLand( float fVelocity );
bool HasC4() const; // Is this player carrying a C4 bomb?
bool IsVIP() const;
int GetClass( void ) const;
void MakeVIP( bool isVIP );
virtual void SetAnimation( PLAYER_ANIM playerAnim );
ICSPlayerAnimState *GetPlayerAnimState() { return m_PlayerAnimState; }
virtual bool StartReplayMode( float fDelay, float fDuration, int iEntity );
virtual void StopReplayMode();
virtual void PlayUseDenySound();
public:
// Simulates a single frame of movement for a player
void RunPlayerMove( const QAngle& viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, float frametime );
virtual void HandleAnimEvent( animevent_t *pEvent );
virtual void UpdateStepSound( surfacedata_t *psurface, const Vector &vecOrigin, const Vector &vecVelocity );
virtual void PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force );
// from cbasecombatcharacter
void InitVCollision( const Vector &vecAbsOrigin, const Vector &vecAbsVelocity );
void VPhysicsShadowUpdate( IPhysicsObject *pPhysics );
bool HasShield() const;
bool IsShieldDrawn() const;
void GiveShield( void );
void RemoveShield( void );
bool IsProtectedByShield( void ) const; // returns true if player has a shield and is currently hidden behind it
bool HasPrimaryWeapon( void );
bool HasSecondaryWeapon( void );
bool IsReloading( void ) const; // returns true if current weapon is reloading
void GiveDefaultItems();
void RemoveAllItems( bool removeSuit ); //overridden to remove the defuser
// Reset account, get rid of shield, etc..
void Reset();
void RoundRespawn( void );
void ObserverRoundRespawn( void );
void CheckTKPunishment( void );
// Add money to this player's account.
void AddAccount( int amount, bool bTrackChange=true, bool bItemBought=false, const char *pItemName = NULL );
void HintMessage( const char *pMessage, bool bDisplayIfDead, bool bOverrideClientSettings = false ); // Displays a hint message to the player
CHintMessageQueue *m_pHintMessageQueue;
unsigned int m_iDisplayHistoryBits;
bool m_bShowHints;
float m_flLastAttackedTeammate;
float m_flNextMouseoverUpdate;
void UpdateMouseoverHints();
// mark this player as not receiving money at the start of the next round.
void MarkAsNotReceivingMoneyNextRound();
bool DoesPlayerGetRoundStartMoney(); // self-explanitory :)
void DropC4(); // Get rid of the C4 bomb.
bool HasDefuser(); // Is this player carrying a bomb defuser?
void GiveDefuser(bool bPickedUp = false); // give the player a defuser
void RemoveDefuser(); // remove defuser from the player and remove the model attachment
//=============================================================================
// HPE_BEGIN:
// [dwenger] Added for fun-fact support
//=============================================================================
bool PickedUpDefuser() { return m_bPickedUpDefuser; }
void SetDefusedWithPickedUpKit(bool bDefusedWithPickedUpKit) { m_bDefusedWithPickedUpKit = bDefusedWithPickedUpKit; }
bool GetDefusedWithPickedUpKit() { return m_bDefusedWithPickedUpKit; }
//=============================================================================
// HPE_END
//=============================================================================
//=============================================================================
// HPE_BEGIN
// [sbodenbender] Need a different test for player blindness for the achievements
//=============================================================================
bool IsBlindForAchievement(); // more stringent than IsBlind; more accurately represents when the player can see again
//=============================================================================
// HPE_END
//=============================================================================
bool IsBlind( void ) const; // return true if this player is blind (from a flashbang)
virtual void Blind( float holdTime, float fadeTime, float startingAlpha = 255 ); // player blinded by a flashbang
float m_blindUntilTime;
float m_blindStartTime;
void Deafen( float flDistance ); //make the player deaf / apply dsp preset to muffle sound
void ApplyDeafnessEffect(); // apply the deafness effect for a nearby explosion.
bool IsAutoFollowAllowed( void ) const; // return true if this player will allow bots to auto follow
void InhibitAutoFollow( float duration ); // prevent bots from auto-following for given duration
void AllowAutoFollow( void ); // allow bots to auto-follow immediately
float m_allowAutoFollowTime; // bots can auto-follow after this time
// Have this guy speak a message into his radio.
void Radio( const char *szRadioSound, const char *szRadioText = NULL );
void ConstructRadioFilter( CRecipientFilter& filter );
void EmitPrivateSound( const char *soundName ); ///< emit given sound that only we can hear
CWeaponCSBase* GetActiveCSWeapon() const;
void PreThink();
// This is the think function for the player when they first join the server and have to select a team
void JoiningThink();
virtual bool ClientCommand( const CCommand &args );
bool HandleCommand_JoinClass( int iClass );
bool HandleCommand_JoinTeam( int iTeam );
BuyResult_e HandleCommand_Buy( const char *item );
BuyResult_e HandleCommand_Buy_Internal( const char * item );
void HandleMenu_Radio1( int slot );
void HandleMenu_Radio2( int slot );
void HandleMenu_Radio3( int slot );
float m_flRadioTime;
int m_iRadioMessages;
int iRadioMenu;
void ListPlayers();
bool m_bIgnoreRadio;
// Returns one of the CS_CLASS_ enums.
int PlayerClass() const;
void MoveToNextIntroCamera();
// Used to be GETINTOGAME state.
void GetIntoGame();
CBaseEntity* EntSelectSpawnPoint();
void SetProgressBarTime( int barTime );
virtual void PlayerDeathThink();
void Weapon_Equip( CBaseCombatWeapon *pWeapon );
virtual bool BumpWeapon( CBaseCombatWeapon *pWeapon );
virtual bool Weapon_CanUse( CBaseCombatWeapon *pWeapon );
void ClearFlashbangScreenFade ( void );
bool ShouldDoLargeFlinch( int nHitGroup, CBaseEntity *pAttacker );
void ResetStamina( void );
bool IsArmored( int nHitGroup );
void Pain( bool HasArmour );
void DeathSound( const CTakeDamageInfo &info );
bool Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon );
void ChangeTeam( int iTeamNum );
void SwitchTeam( int iTeamNum ); // Changes teams without penalty - used for auto team balancing
void ModifyOrAppendPlayerCriteria( AI_CriteriaSet& set );
virtual void OnDamagedByExplosion( const CTakeDamageInfo &info );
// Called whenever this player fires a shot.
void NoteWeaponFired();
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
// ------------------------------------------------------------------------------------------------ //
// Player state management.
// ------------------------------------------------------------------------------------------------ //
public:
void State_Transition( CSPlayerState newState ); // Cleanup the previous state and enter a new state.
CSPlayerState State_Get() const; // Get the current state.
private:
void State_Enter( CSPlayerState newState ); // Initialize the new state.
void State_Leave(); // Cleanup the previous state.
void State_PreThink(); // Update the current state.
// Find the state info for the specified state.
static CCSPlayerStateInfo* State_LookupInfo( CSPlayerState state );
// This tells us which state the player is currently in (joining, observer, dying, etc).
// Each state has a well-defined set of parameters that go with it (ie: observer is movetype_noclip, nonsolid,
// invisible, etc).
CNetworkVar( CSPlayerState, m_iPlayerState );
CCSPlayerStateInfo *m_pCurStateInfo; // This can be NULL if no state info is defined for m_iPlayerState.
// tells us whether or not this player gets money at the start of the next round.
bool m_receivesMoneyNextRound;
// Specific state handler functions.
void State_Enter_WELCOME();
void State_PreThink_WELCOME();
void State_Enter_PICKINGTEAM();
void State_Enter_PICKINGCLASS();
void State_Enter_ACTIVE();
void State_PreThink_ACTIVE();
void State_Enter_OBSERVER_MODE();
void State_PreThink_OBSERVER_MODE();
void State_Enter_DEATH_WAIT_FOR_KEY();
void State_PreThink_DEATH_WAIT_FOR_KEY();
void State_Enter_DEATH_ANIM();
void State_PreThink_DEATH_ANIM();
int FlashlightIsOn( void );
void FlashlightTurnOn( void );
void FlashlightTurnOff( void );
void UpdateAddonBits();
void UpdateRadar();
public:
void SetDeathPose( const int &iDeathPose ) { m_iDeathPose = iDeathPose; }
void SetDeathPoseFrame( const int &iDeathPoseFrame ) { m_iDeathFrame = iDeathPoseFrame; }
void SelectDeathPose( const CTakeDamageInfo &info );
private:
int m_iDeathPose;
int m_iDeathFrame;
//=============================================================================
// HPE_BEGIN:
// [menglish] Freeze cam function and variable declarations
//=============================================================================
bool m_bAbortFreezeCam;
protected:
void AttemptToExitFreezeCam( void );
//=============================================================================
// HPE_END
//=============================================================================
public:
// Predicted variables.
CNetworkVar( bool, m_bResumeZoom );
CNetworkVar( int , m_iLastZoom ); // after firing a shot, set the FOV to 90, and after showing the animation, bring the FOV back to last zoom level.
CNetworkVar( bool, m_bIsDefusing ); // tracks whether this player is currently defusing a bomb
int m_LastHitGroup; // the last body region that took damage
//=============================================================================
// HPE_BEGIN:
// [menglish] Adding two variables, keeping track of damage to the player
//=============================================================================
int m_LastHitBox; // the last body hitbox that took damage
Vector m_vLastHitLocationObjectSpace; //position where last hit occured in space of the bone associated with the hitbox
EHANDLE m_hDroppedEquipment[DROPPED_COUNT];
// [tj] overriding the base suicides to trash CS specific stuff
virtual void CommitSuicide( bool bExplode = false, bool bForce = false );
virtual void CommitSuicide( const Vector &vecForce, bool bExplode = false, bool bForce = false );
void WieldingKnifeAndKilledByGun( bool bState ) { m_bWieldingKnifeAndKilledByGun = bState; }
bool WasWieldingKnifeAndKilledByGun() { return m_bWieldingKnifeAndKilledByGun; }
// [dwenger] adding tracking for weapon used fun fact
void PlayerUsedFirearm( CBaseCombatWeapon* pBaseWeapon );
int GetNumFirearmsUsed() { return m_WeaponTypesUsed.Count(); }
//=============================================================================
// HPE_END
//=============================================================================
CNetworkVar( bool, m_bHasHelmet ); // Does the player have helmet armor
bool m_bEscaped; // Has this terrorist escaped yet?
// Other variables.
bool m_bIsVIP; // Are we the VIP?
int m_iNumSpawns; // Number of times player has spawned this round
int m_iOldTeam; // Keep what team they were last on so we can allow joining spec and switching back to their real team
bool m_bTeamChanged; // Just allow one team change per round
CNetworkVar( int, m_iAccount ); // How much cash this player has.
int m_iShouldHaveCash;
bool m_bJustKilledTeammate;
bool m_bPunishedForTK;
int m_iTeamKills;
float m_flLastMovement;
int m_iNextTimeCheck; // Next time the player can execute a "timeleft" command
float m_flNameChangeHistory[NAME_CHANGE_HISTORY_SIZE]; // index 0 = most recent change
bool CanChangeName( void ); // Checks if the player can change his name
void ChangeName( const char *pszNewName );
void SetClanTag( const char *pTag );
const char *GetClanTag( void ) const;
CNetworkVar( bool, m_bHasDefuser ); // Does this player have a defuser kit?
CNetworkVar( bool, m_bHasNightVision ); // Does this player have night vision?
CNetworkVar( bool, m_bNightVisionOn ); // Is the NightVision turned on ?
//=============================================================================
// HPE_BEGIN:
// [dwenger] Added for fun-fact support
//=============================================================================
//CNetworkVar( bool, m_bPickedUpDefuser ); // Did player pick up the defuser kit as opposed to buying it?
//CNetworkVar( bool, m_bDefusedWithPickedUpKit); // Did player defuse the bomb with a picked-up defuse kit?
//=============================================================================
// HPE_END
//=============================================================================
float m_flLastRadarUpdateTime;
// last known navigation area of player - NULL if unknown
CNavArea *m_lastNavArea;
// Backup copy of the menu text so the player can change this and the menu knows when to update.
char m_MenuStringBuffer[MENU_STRING_BUFFER_SIZE];
// When the player joins, it cycles their view between trigger_camera entities.
// This is the current camera, and the time that we'll switch to the next one.
EHANDLE m_pIntroCamera;
float m_fIntroCamTime;
// Set to true each frame while in a bomb zone.
// Reset after prediction (in PostThink).
CNetworkVar( bool, m_bInBombZone );
CNetworkVar( bool, m_bInBuyZone );
int m_iBombSiteIndex;
bool IsInBuyZone();
bool CanPlayerBuy( bool display );
CNetworkVar( bool, m_bInHostageRescueZone );
void RescueZoneTouch( inputdata_t &inputdata );
CNetworkVar( float, m_flStamina );
CNetworkVar( int, m_iDirection ); // The current lateral kicking direction; 1 = right, 0 = left
CNetworkVar( int, m_iShotsFired ); // number of shots fired recently
// Make sure to register changes for armor.
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_ArmorValue );
CNetworkVar( float, m_flVelocityModifier );
int m_iHostagesKilled;
void SetShieldDrawnState( bool bState );
void DropShield( void );
char m_szNewName [MAX_PLAYER_NAME_LENGTH]; // not empty if player requested a namechange
char m_szClanTag[MAX_CLAN_TAG_LENGTH];
Vector m_vecTotalBulletForce; //Accumulator for bullet force in a single frame
CNetworkVar( float, m_flFlashDuration );
CNetworkVar( float, m_flFlashMaxAlpha );
CNetworkVar( float, m_flProgressBarStartTime );
CNetworkVar( int, m_iProgressBarDuration );
CNetworkVar( int, m_iThrowGrenadeCounter ); // used to trigger grenade throw animations.
// Tracks our ragdoll entity.
CNetworkHandle( CBaseEntity, m_hRagdoll ); // networked entity handle
// Bots and hostages auto-duck during jumps
bool m_duckUntilOnGround;
Vector m_lastStandingPos; // used by the gamemovement code for finding ladders
void SurpressLadderChecks( const Vector& pos, const Vector& normal );
bool CanGrabLadder( const Vector& pos, const Vector& normal );
CNetworkVar( bool, m_bDetected );
private:
CountdownTimer m_ladderSurpressionTimer;
Vector m_lastLadderNormal;
Vector m_lastLadderPos;
protected:
void CreateRagdollEntity();
bool IsHittingShield( const Vector &vecDirection, trace_t *ptr );
void PhysObjectSleep();
void PhysObjectWake();
bool RunMimicCommand( CUserCmd& cmd );
bool SelectSpawnSpot( const char *pEntClassName, CBaseEntity* &pSpot );
void SetModelFromClass( void );
CNetworkVar( int, m_iClass ); // One of the CS_CLASS_ enums.
bool CSWeaponDrop( CBaseCombatWeapon *pWeapon, bool bDropShield = true, bool bThrow = false );
bool DropRifle( bool fromDeath = false );
bool DropPistol( bool fromDeath = false );
//=============================================================================
// HPE_BEGIN:
// [tj] Added a parameter so we know if it was death that caused the drop
// [menglish] New parameter to always know if this is from death and not just an enemy death
//=============================================================================
void DropWeapons( bool fromDeath, bool friendlyFire );
//=============================================================================
// HPE_END
//=============================================================================
virtual int SpawnArmorValue( void ) const { return ArmorValue(); }
BuyResult_e AttemptToBuyAmmo( int iAmmoType );
BuyResult_e AttemptToBuyAmmoSingle( int iAmmoType );
BuyResult_e AttemptToBuyVest( void );
BuyResult_e AttemptToBuyAssaultSuit( void );
BuyResult_e AttemptToBuyDefuser( void );
BuyResult_e AttemptToBuyNightVision( void );
BuyResult_e AttemptToBuyShield( void );
BuyResult_e BuyAmmo( int nSlot, bool bBlinkMoney );
BuyResult_e BuyGunAmmo( CBaseCombatWeapon *pWeapon, bool bBlinkMoney );
void PushawayThink();
private:
ICSPlayerAnimState *m_PlayerAnimState;
// Aiming heuristics code
float m_flIdleTime; //Amount of time we've been motionless
float m_flMoveTime; //Amount of time we've been in motion
float m_flLastDamageTime; //Last time we took damage
float m_flTargetFindTime;
int m_lastDamageHealth; // Last damage given to our health
int m_lastDamageArmor; // Last damage given to our armor
//=============================================================================
// HPE_BEGIN:
// [dwenger] Added for fun-fact support
//=============================================================================
bool m_bPickedUpDefuser; // Did player pick up the defuser kit as opposed to buying it?
bool m_bDefusedWithPickedUpKit; // Did player defuse the bomb with a picked-up defuse kit?
//=============================================================================
// HPE_END
//=============================================================================
// Last usercmd we shot a bullet on.
int m_iLastWeaponFireUsercmd;
// Copyed from EyeAngles() so we can send it to the client.
CNetworkQAngle( m_angEyeAngles );
bool m_bVCollisionInitted;
// AutoBuy functions.
public:
void AutoBuy(); // this should take into account what the player can afford and should buy the best equipment for them.
bool IsInAutoBuy( void ) { return m_bIsInAutoBuy; }
bool IsInReBuy( void ) { return m_bIsInRebuy; }
private:
bool ShouldExecuteAutoBuyCommand(const AutoBuyInfoStruct *commandInfo, bool boughtPrimary, bool boughtSecondary);
void PostAutoBuyCommandProcessing(const AutoBuyInfoStruct *commandInfo, bool &boughtPrimary, bool &boughtSecondary);
void ParseAutoBuyString(const char *string, bool &boughtPrimary, bool &boughtSecondary);
AutoBuyInfoStruct *GetAutoBuyCommandInfo(const char *command);
void PrioritizeAutoBuyString(char *autobuyString, const char *priorityString); // reorders the tokens in autobuyString based on the order of tokens in the priorityString.
BuyResult_e CombineBuyResults( BuyResult_e prevResult, BuyResult_e newResult );
bool m_bIsInAutoBuy;
bool m_bAutoReload;
//ReBuy functions
public:
void Rebuy();
private:
void BuildRebuyStruct();
BuyResult_e RebuyPrimaryWeapon();
BuyResult_e RebuyPrimaryAmmo();
BuyResult_e RebuySecondaryWeapon();
BuyResult_e RebuySecondaryAmmo();
BuyResult_e RebuyHEGrenade();
BuyResult_e RebuyFlashbang();
BuyResult_e RebuySmokeGrenade();
BuyResult_e RebuyDefuser();
BuyResult_e RebuyNightVision();
BuyResult_e RebuyArmor();
bool m_bIsInRebuy;
RebuyStruct m_rebuyStruct;
bool m_bUsingDefaultPistol;
bool m_bIsBeingGivenItem;
#ifdef CS_SHIELD_ENABLED
CNetworkVar( bool, m_bHasShield );
CNetworkVar( bool, m_bShieldDrawn );
#endif
// This is a combination of the ADDON_ flags in cs_shareddefs.h.
CNetworkVar( int, m_iAddonBits );
// Clients don't know about holstered weapons, so we need to tell them the weapon type here
CNetworkVar( int, m_iPrimaryAddon );
CNetworkVar( int, m_iSecondaryAddon );
//Damage record functions
public:
static void StartNewBulletGroup(); // global function
void RecordDamageTaken( const char *szDamageDealer, int iDamageTaken );
void RecordDamageGiven( const char *szDamageTaker, int iDamageGiven );
void ResetDamageCounters(); //Reset all lists
void OutputDamageTaken( void );
void OutputDamageGiven( void );
void StockPlayerAmmo( CBaseCombatWeapon *pNewWeapon = NULL );
CUtlLinkedList< CDamageRecord *, int >& GetDamageGivenList() {return m_DamageGivenList;}
CUtlLinkedList< CDamageRecord *, int >& GetDamageTakenList() {return m_DamageTakenList;}
private:
//A list of damage given
CUtlLinkedList< CDamageRecord *, int > m_DamageGivenList;
//A list of damage taken
CUtlLinkedList< CDamageRecord *, int > m_DamageTakenList;
protected:
float m_applyDeafnessTime;
int m_currentDeafnessFilter;
bool m_isVIP;
// Command rate limiting.
private:
bool ShouldRunRateLimitedCommand( const CCommand &args );
// This lets us rate limit the commands the players can execute so they don't overflow things like reliable buffers.
CUtlDict<float,int> m_RateLimitLastCommandTimes;
CNetworkVar(int, m_cycleLatch); // Every so often, we are going to transmit our cycle to the client to correct divergence caused by PVS changes
CountdownTimer m_cycleLatchTimer;
//=============================================================================
// HPE_BEGIN:
// [menglish, tj] Achievement-based addition to CS player class.
//=============================================================================
public:
void ResetRoundBasedAchievementVariables();
void OnRoundEnd(int winningTeam, int reason);
void OnPreResetRound();
int GetNumEnemyDamagers();
int GetNumEnemiesDamaged();
CBaseEntity* GetNearestSurfaceBelow(float maxTrace);
// Returns the % of the enemies this player killed in the round
int GetPercentageOfEnemyTeamKilled();
//List of times of recent kills to check for sprees
CUtlVector<float> m_killTimes;
//List of all players killed this round
CUtlVector<CHandle<CCSPlayer> > m_enemyPlayersKilledThisRound;
//List of weapons we have used to kill players with this round
CUtlVector<int> m_killWeapons;
int m_NumEnemiesKilledThisRound;
int m_NumEnemiesAtRoundStart;
int m_KillingSpreeStartTime;
float m_firstKillBlindStartTime; //This is the start time of the blind effect during which we got our most recent kill.
int m_killsWhileBlind;
bool m_bIsRescuing; // tracks whether this player is currently rescuing a hostage
bool m_bInjuredAHostage; // tracks whether this player injured a hostage
int m_iNumFollowers; // Number of hostages following this player
bool m_bSurvivedHeadshotDueToHelmet;
void IncrementNumFollowers() { m_iNumFollowers++; }
void DecrementNumFollowers() { m_iNumFollowers--; if (m_iNumFollowers < 0) m_iNumFollowers = 0; }
int GetNumFollowers() { return m_iNumFollowers; }
void SetIsRescuing(bool in_bRescuing) { m_bIsRescuing = in_bRescuing; }
bool IsRescuing() { return m_bIsRescuing; }
void SetInjuredAHostage(bool in_bInjured) { m_bInjuredAHostage = in_bInjured; }
bool InjuredAHostage() { return m_bInjuredAHostage; }
float GetBombPickuptime() { return m_bombPickupTime; }
void SetBombPickupTime(float time) { m_bombPickupTime = time; }
CCSPlayer* GetLastFlashbangAttacker() { return m_lastFlashBangAttacker; }
void SetLastFlashbangAttacker(CCSPlayer* attacker) { m_lastFlashBangAttacker = attacker; }
static CSWeaponID GetWeaponIdCausingDamange( const CTakeDamageInfo &info );
static void ProcessPlayerDeathAchievements( CCSPlayer *pAttacker, CCSPlayer *pVictim, const CTakeDamageInfo &info );
void OnCanceledDefuse();
void OnStartedDefuse();
GooseChaseAchievementStep m_gooseChaseStep;
DefuseDefenseAchivementStep m_defuseDefenseStep;
CHandle<CCSPlayer> m_pGooseChaseDistractingPlayer;
int m_lastRoundResult; //save the reason for the last round ending.
bool m_bMadeFootstepNoise;
float m_bombPickupTime;
bool m_bMadePurchseThisRound;
int m_roundsWonWithoutPurchase;
bool m_bKilledDefuser;
bool m_bKilledRescuer;
int m_maxGrenadeKills;
int m_grenadeDamageTakenThisRound;
bool GetKilledDefuser() { return m_bKilledDefuser; }
bool GetKilledRescuer() { return m_bKilledRescuer; }
int GetMaxGrenadeKills() { return m_maxGrenadeKills; }
void CheckMaxGrenadeKills(int grenadeKills);
CHandle<CCSPlayer> m_lastFlashBangAttacker;
void SetPlayerDominated( CCSPlayer *pPlayer, bool bDominated );
void SetPlayerDominatingMe( CCSPlayer *pPlayer, bool bDominated );
bool IsPlayerDominated( int iPlayerIndex );
bool IsPlayerDominatingMe( int iPlayerIndex );
bool m_wasNotKilledNaturally; //Set if the player is dead from a kill command or late login
bool WasNotKilledNaturally() { return m_wasNotKilledNaturally; }
//=============================================================================
// [menglish] MVP functions
//=============================================================================
void SetNumMVPs( int iNumMVP );
void IncrementNumMVPs( CSMvpReason_t mvpReason );
int GetNumMVPs();
//=============================================================================
// HPE_END
//=============================================================================
void RemoveNemesisRelationships();
void SetDeathFlags( int iDeathFlags ) { m_iDeathFlags = iDeathFlags; }
int GetDeathFlags() { return m_iDeathFlags; }
private:
CNetworkArray( bool, m_bPlayerDominated, MAX_PLAYERS+1 ); // array of state per other player whether player is dominating other players
CNetworkArray( bool, m_bPlayerDominatingMe, MAX_PLAYERS+1 ); // array of state per other player whether other players are dominating this player
//=============================================================================
// HPE_BEGIN:
//=============================================================================
// [menglish] number of rounds this player has caused to be won for their team
int m_iMVPs;
// [dwenger] adding tracking for fun fact
bool m_bWieldingKnifeAndKilledByGun;
// [dwenger] adding tracking for which weapons this player has used in a round
CUtlVector<CSWeaponID> m_WeaponTypesUsed;
//=============================================================================
// HPE_END
//=============================================================================
int m_iDeathFlags; // Flags holding revenge and domination info about a death
//=============================================================================
// HPE_END
//=============================================================================
};
inline CSPlayerState CCSPlayer::State_Get() const
{
return m_iPlayerState;
}
inline CCSPlayer *ToCSPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
return dynamic_cast<CCSPlayer*>( pEntity );
}
inline bool CCSPlayer::IsReloading( void ) const
{
CBaseCombatWeapon *gun = GetActiveWeapon();
if (gun == NULL)
return false;
return gun->m_bInReload;
}
inline bool CCSPlayer::IsProtectedByShield( void ) const
{
return HasShield() && IsShieldDrawn();
}
inline bool CCSPlayer::IsBlind( void ) const
{
return gpGlobals->curtime < m_blindUntilTime;
}
//=============================================================================
// HPE_BEGIN
// [sbodenbender] Need a different test for player blindness for the achievements
//=============================================================================
inline bool CCSPlayer::IsBlindForAchievement()
{
return (m_blindStartTime + m_flFlashDuration) > gpGlobals->curtime;
}
//=============================================================================
// HPE_END
//=============================================================================
inline bool CCSPlayer::IsAutoFollowAllowed( void ) const
{
return (gpGlobals->curtime > m_allowAutoFollowTime);
}
inline void CCSPlayer::InhibitAutoFollow( float duration )
{
m_allowAutoFollowTime = gpGlobals->curtime + duration;
}
inline void CCSPlayer::AllowAutoFollow( void )
{
m_allowAutoFollowTime = 0.0f;
}
inline int CCSPlayer::GetClass( void ) const
{
return m_iClass;
}
inline const char *CCSPlayer::GetClanTag( void ) const
{
return m_szClanTag;
}
#endif //CS_PLAYER_H