|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
#ifndef TF_PLAYER_H
#define TF_PLAYER_H
#pragma once
#include "basemultiplayerplayer.h"
#include "server_class.h"
#include "tf_achievementdata.h"
#include "tf_playeranimstate.h"
#include "tf_shareddefs.h"
#include "tf_obj.h"
#include "tf_player_shared.h"
#include "tf_playerclass.h"
#include "entity_tfstart.h"
#include "steam/steam_gameserver.h"
#include "ihasattributes.h"
#include "tf_item_inventory.h"
class CTFPlayer; class CTFTeam; class CTFGoal; class CTFGoalItem; class CTFItem; class CTFWeaponBuilder; //class CBaseObject;
class CTFWeaponBase; class CIntroViewpoint; class CTriggerAreaCapture; class CTFWeaponBaseGun; class CCaptureZone; class CTFReviveMarker; class CWaveSpawnPopulator; class CTFTauntProp; class CTFDroppedWeapon;
//=============================================================================
//
// Player State Information
//
class CPlayerStateInfo { public:
int m_nPlayerState; const char *m_pStateName;
// Enter/Leave state.
void ( CTFPlayer::*pfnEnterState )(); void ( CTFPlayer::*pfnLeaveState )();
// Think (called every frame).
void ( CTFPlayer::*pfnThink )(); };
enum EAmmoSource { kAmmoSource_Pickup, // this came from either a box of ammo or a player's dropped weapon
kAmmoSource_Resupply, // resupply cabinet and/or full respawn
kAmmoSource_DispenserOrCart, // the player is standing next to an engineer's dispenser or pushing the cart in a payload game
};
//=============================================================================
//
// TF Player
//
class CTFPlayer : public CBaseMultiplayerPlayer, public IHasAttributes, public IInventoryUpdateListener { public: DECLARE_CLASS( CTFPlayer, CBaseMultiplayerPlayer ); DECLARE_SERVERCLASS(); DECLARE_DATADESC();
CTFPlayer(); ~CTFPlayer();
//=============================================================================
// HPE_BEGIN:
// [msmith] Added a player type so we can distinguish between bots and humans.
//=============================================================================
enum TFPlayerType{ HUMAN_PLAYER, TEMP_BOT, TRAINING_BOT }; //=============================================================================
// HPE_END
//=============================================================================
// Creation/Destruction.
static CTFPlayer *CreatePlayer( const char *className, edict_t *ed ); static CTFPlayer *Instance( int iEnt );
virtual int ShouldTransmit( const CCheckTransmitInfo *pInfo );
virtual void SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs, int pvssize ); virtual void Spawn(); virtual void ForceRespawn(); void ForceRegenerateAndRespawn( void ); virtual CBaseEntity *EntSelectSpawnPoint( void ); virtual void InitialSpawn(); static void PrecacheMvM(); static void PrecacheKart(); private: static void PrecachePlayerModels(); static void PrecacheTFPlayer(); public: virtual void Precache(); virtual bool IsReadyToPlay( void ); virtual bool IsReadyToSpawn( void ); virtual bool ShouldGainInstantSpawn( void ); virtual void ResetScores( void ); virtual void UpdateOnRemove( void ); void CheckInstantLoadoutRespawn( void );
virtual void ResetPerRoundStats( void );
void HandleCommand_JoinTeam( const char *pTeamName ); void HandleCommand_JoinClass( const char *pClassName, bool bAllowSpawn = true ); void HandleCommand_JoinTeam_NoMenus( const char *pTeamName );
void CreateViewModel( int iViewModel = 0 ); CBaseViewModel *GetOffHandViewModel(); void SendOffHandViewModelActivity( Activity activity );
virtual void CheatImpulseCommands( int iImpulse ); virtual void PlayerRunCommand( CUserCmd *ucmd, IMoveHelper *moveHelper );
virtual void CommitSuicide( bool bExplode = false, bool bForce = false );
// Combats
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); virtual int TakeHealth( float flHealth, int bitsDamageType ); virtual void Event_KilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ); virtual void Event_Killed( const CTakeDamageInfo &info ); virtual void PlayerDeathThink( void ); virtual void DetermineAssistForKill( const CTakeDamageInfo &info ); virtual void SetNumberofDominations( int iDominations ) { // Check for some bogus values, which are sneaking in somehow
if ( iDominations < 0 ) { Assert( iDominations >= 0 ); iDominations = 0; } else if ( iDominations >= MAX_PLAYERS ) { Assert( iDominations < MAX_PLAYERS ); iDominations = MAX_PLAYERS-1; } m_iNumberofDominations = iDominations; } virtual int GetNumberofDominations( void ) { return m_iNumberofDominations; } void OnKilledOther_Effects( CBaseEntity *pVictim, const CTakeDamageInfo &info );
virtual int OnTakeDamage( const CTakeDamageInfo &inputInfo ); void AddConnectedPlayers( CUtlVector<CTFPlayer*> &vecPlayers, CTFPlayer *pPlayerToConsider ); virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info ); virtual void DamageEffect(float flDamage, int fDamageType);
void OnDealtDamage( CBaseCombatCharacter *pVictim, const CTakeDamageInfo &info ); // invoked when we deal damage to another victim
int GetDamagePerSecond( void ) const; void ResetDamagePerSecond( void );
virtual bool ShouldCollide( int collisionGroup, int contentsMask ) const; void ApplyPushFromDamage( const CTakeDamageInfo &info, Vector vecDir ); void PlayDamageResistSound( float flStartDamage, float flModifiedDamage ); bool CheckBlockBackstab( CTFPlayer *pTFAttacker );
virtual bool Weapon_CanSwitchTo( CBaseCombatWeapon *pWeapon );
void SetHealthBuffTime( float flTime ) { m_flHealthBuffTime = flTime; }
CTFWeaponBase *GetActiveTFWeapon( void ) const; bool IsActiveTFWeapon( const CSchemaItemDefHandle &weaponHandle ) const; bool IsActiveTFWeapon( CEconItemDefinition *weaponHandle ) const; virtual void RemoveAllWeapons(); virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ) OVERRIDE; // Adds weapon to player
void SaveMe( void );
void FireBullet( CTFWeaponBase *pWpn, const FireBulletsInfo_t &info, bool bDoEffects, int nDamageType, int nCustomDamageType = TF_DMG_CUSTOM_NONE ); void ImpactWaterTrace( trace_t &trace, const Vector &vecStart ); void NoteWeaponFired();
bool HasItem( void ) const; // Currently can have only one item at a time.
void SetItem( CTFItem *pItem ); CTFItem *GetItem( void ) const; void SaveLastWeaponSlot( void ); void SetRememberLastWeapon( bool bRememberLastWeapon ) { m_bRememberLastWeapon = bRememberLastWeapon; } void SetRememberActiveWeapon( bool bRememberActiveWeapon ) { m_bRememberActiveWeapon = bRememberActiveWeapon; }
void Regenerate( bool bRefillHealthAndAmmo = true ); float GetNextRegenTime( void ){ return m_flNextRegenerateTime; } void SetNextRegenTime( float flTime ){ m_flNextRegenerateTime = flTime; }
float GetNextChangeClassTime( void ){ return m_flNextChangeClassTime; } void SetNextChangeClassTime( float flTime ){ m_flNextChangeClassTime = flTime; }
float GetNextChangeTeamTime( void ){ return m_flNextChangeTeamTime; } void SetNextChangeTeamTime( float flTime ){ m_flNextChangeTeamTime = flTime; }
virtual void RemoveAllItems( bool removeSuit );
virtual bool BumpWeapon( CBaseCombatWeapon *pWeapon ); bool DropCurrentWeapon( void ); void DropFlag( bool bSilent = false ); void DropRune( bool bApplyForce = true, int nTeam = TEAM_ANY ); void TFWeaponRemove( int iWeaponID ); bool TFWeaponDrop( CTFWeaponBase *pWeapon, bool bThrowForward );
// Class.
CTFPlayerClass *GetPlayerClass( void ) { return &m_PlayerClass; } const CTFPlayerClass *GetPlayerClass( void ) const { return &m_PlayerClass; } int GetDesiredPlayerClassIndex( void ) { return m_Shared.m_iDesiredPlayerClass; } void SetDesiredPlayerClassIndex( int iClass ) { m_Shared.m_iDesiredPlayerClass = iClass; }
// Team.
void ForceChangeTeam( int iTeamNum, bool bFullTeamSwitch = false ); virtual void ChangeTeam( int iTeamNum, bool bAutoTeam, bool bSilent, bool bAutoBalance = false ) OVERRIDE; virtual void ChangeTeam( int iTeamNum ) OVERRIDE { BaseClass::ChangeTeam( iTeamNum ); }
// mp_fadetoblack
void HandleFadeToBlack( void );
// Flashlight controls for SFM - JasonM
virtual int FlashlightIsOn( void ); virtual void FlashlightTurnOn( void ); virtual void FlashlightTurnOff( void );
// Think.
virtual void PreThink(); virtual void PostThink();
virtual void ItemPostFrame(); virtual void Weapon_FrameUpdate( void ); virtual void Weapon_HandleAnimEvent( animevent_t *pEvent ); virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon );
virtual void GetStepSoundVelocities( float *velwalk, float *velrun ); virtual void SetStepSoundTime( stepsoundtimes_t iStepSoundTime, bool bWalking ); virtual const char *GetOverrideStepSound( const char *pszBaseStepSoundName );
virtual void OnEmitFootstepSound( const CSoundParameters& params, const Vector& vecOrigin, float fVolume );
virtual void ModifyEmitSoundParams( EmitSound_t ¶ms );
// Utility.
void UpdateModel( void ); void UpdateSkin( int iTeam );
int GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound, EAmmoSource eAmmoSource ); virtual int GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound = false ); virtual void RemoveAmmo( int iCount, int iAmmoIndex ); virtual void RemoveAmmo( int iCount, const char *szName ); virtual int GetAmmoCount( int iAmmoIndex ) const; int GetMaxAmmo( int iAmmoIndex, int iClassIndex = -1 ); virtual int GetMaxHealth() const OVERRIDE; int GetMaxHealthForBuffing() const; int GetRuneHealthBonus() const;
//-----------------------------------------------------------------------------------------------------
// Return true if we are a "mini boss" in Mann Vs Machine mode
bool IsMiniBoss( void ) const; void SetIsMiniBoss( bool isMiniBoss ) { m_bIsMiniBoss = isMiniBoss; }
bool CanAttack( int iCanAttackFlags = 0 );
void RemoveMeleeCrit( void );
// This passes the event to the client's and server's CPlayerAnimState.
void DoAnimationEvent( PlayerAnimEvent_t event, int mData = 0 );
virtual void HandleAnimEvent( animevent_t *pEvent ) OVERRIDE;
virtual bool ClientCommand( const CCommand &args ); void ClientHearVox( const char *pSentence ); void DisplayLocalItemStatus( CTFGoal *pGoal );
int BuildObservableEntityList( void ); virtual int GetNextObserverSearchStartPoint( bool bReverse ); // Where we should start looping the player list in a FindNextObserverTarget call
virtual CBaseEntity *FindNextObserverTarget(bool bReverse); virtual bool IsValidObserverTarget(CBaseEntity * target); // true, if player is allowed to see this target
virtual bool SetObserverTarget(CBaseEntity * target); virtual bool ModeWantsSpectatorGUI( int iMode ) { return (iMode != OBS_MODE_FREEZECAM && iMode != OBS_MODE_DEATHCAM); } void FindInitialObserverTarget( void ); CBaseEntity *FindNearestObservableTarget( Vector vecOrigin, float flMaxDist ); virtual void ValidateCurrentObserverTarget( void );
void CheckUncoveringSpies( CTFPlayer *pTouchedPlayer ); void Touch( CBaseEntity *pOther );
virtual void RefreshCollisionBounds( void );
float GetMovementForwardPull( void ) const; bool CanPlayerMove() const; float TeamFortress_CalculateMaxSpeed( bool bIgnoreSpecialAbility = false ) const; void TeamFortress_SetSpeed(); EHANDLE TeamFortress_GetDisguiseTarget( int nTeam, int nClass );
void TeamFortress_ClientDisconnected(); void RemoveAllOwnedEntitiesFromWorld( bool bExplodeBuildings = false ); void RemoveOwnedProjectiles(); int GetNumActivePipebombs( void );
Vector EstimateProjectileImpactPosition( CTFWeaponBaseGun *weapon ); // estimate where a projectile fired from the given weapon will initially hit (it may bounce on from there)
Vector EstimateProjectileImpactPosition( float pitch, float yaw, float initVel ); // estimate where a projectile fired will initially hit (it may bounce on from there)
Vector EstimateStickybombProjectileImpactPosition( float pitch, float yaw, float charge ); // Estimate where a stickybomb projectile will hit, using given pitch, yaw, and weapon charge (0-1)
CTFTeamSpawn *GetSpawnPoint( void ){ return m_pSpawnPoint; } void SetAnimation( PLAYER_ANIM playerAnim );
bool IsPlayerClass( int iClass ) const;
void PlayFlinch( const CTakeDamageInfo &info );
float PlayCritReceivedSound( void ); void PainSound( const CTakeDamageInfo &info ); void DeathSound( const CTakeDamageInfo &info ); virtual const char* GetSceneSoundToken( void ); void StunSound( CTFPlayer* pAttacker, int iStunFlags, int iOldStunFlags=0 );
void SetSeeCrit( bool bAllSeeCrit, bool bMiniCrit, bool bShowDisguisedCrit ) { m_bAllSeeCrit = bAllSeeCrit; m_bMiniCrit = bMiniCrit; m_bShowDisguisedCrit = bShowDisguisedCrit; } void SetAttackBonusEffect( EAttackBonusEffects_t effect ) { m_eBonusAttackEffect = effect; } EAttackBonusEffects_t GetAttackBonusEffect( void ) { return m_eBonusAttackEffect; }
// TF doesn't want the explosion ringing sound
virtual void OnDamagedByExplosion( const CTakeDamageInfo &info ) { return; }
void OnBurnOther( CTFPlayer *pTFPlayerVictim, CTFWeaponBase *pWeapon );
// Buildables
void SetWeaponBuilder( CTFWeaponBuilder *pBuilder ); CTFWeaponBuilder *GetWeaponBuilder( void );
int GetBuildResources( void ); void RemoveBuildResources( int iAmount ); void AddBuildResources( int iAmount );
bool IsBuilding( void ); int CanBuild( int iObjectType, int iObjectMode = 0 );
CBaseObject *GetObject( int index ) const; CBaseObject *GetObjectOfType( int iObjectType, int iObjectMode = 0 ) const; int GetObjectCount( void ) const; int GetNumObjects( int iObjectType, int iObjectMode = 0 ); void RemoveAllObjects( bool bExplodeBuildings = false ); void StopPlacement( void ); int StartedBuildingObject( int iObjectType ); void StoppedBuilding( int iObjectType ); void FinishedObject( CBaseObject *pObject ); void AddObject( CBaseObject *pObject ); void OwnedObjectDestroyed( CBaseObject *pObject ); void RemoveObject( CBaseObject *pObject ); bool PlayerOwnsObject( CBaseObject *pObject ); void DetonateObjectOfType( int iObjectType, int iObjectMode = 0, bool bIgnoreSapperState = false ); void StartBuildingObjectOfType( int iType, int iObjectMode = 0 ); float GetObjectBuildSpeedMultiplier( int iObjectType, bool bIsRedeploy ) const;
void OnSapperPlaced( CBaseEntity *sappedObject ); // invoked when we place a sapper on an enemy building
bool IsPlacingSapper( void ) const; // return true if we are a spy who placed a sapper on a building in the last few moments
void OnSapperStarted( float flStartTime ); void OnSapperFinished( float flStartTime ); bool IsSapping( void ) const; int GetSappingEvent( void) const; void ClearSappingEvent( void ); void ClearSappingTracking( void );
CTFTeam *GetTFTeam( void ); CTFTeam *GetOpposingTFTeam( void );
void TeleportEffect( void ); void RemoveTeleportEffect( void ); bool HasTheFlag( ETFFlagType exceptionTypes[] = NULL, int nNumExceptions = 0 ) const; virtual bool IsAllowedToPickUpFlag( void ) const;
// Death & Ragdolls.
virtual void CreateRagdollEntity( void ); void CreateRagdollEntity( bool bGib, bool bBurning, bool bElectrocuted, bool bOnGround, bool bCloakedCorpse, bool bGoldRagdoll, bool bIceRagdoll, bool bBecomeAsh, int iDamageCustom = 0, bool bCritOnHardHit = false ); void DestroyRagdoll( void ); CNetworkHandle( CBaseEntity, m_hRagdoll ); // networked entity handle
virtual bool ShouldGib( const CTakeDamageInfo &info ) OVERRIDE; bool HasBombinomiconEffectOnDeath( void ); void StopRagdollDeathAnim( void ); void SetGibbedOnLastDeath( bool bGibbed ) { m_bGibbedOnLastDeath = bGibbed; } bool WasGibbedOnLastDeath( void ) { return m_bGibbedOnLastDeath; }
// Feign Death
void SpyDeadRingerDeath( const CTakeDamageInfo& info ); void FeignDeath( const CTakeDamageInfo& info ); void CreateFeignDeathRagdoll( const CTakeDamageInfo& info, bool bGib, bool bBurning, bool bDisguised );
// Dropping Ammo
bool ShouldDropAmmoPack( void ); void DropAmmoPack( const CTakeDamageInfo &info, bool bEmpty, bool bDisguisedWeapon ); void DropExtraAmmo( const CTakeDamageInfo& info, bool bFromDeath = false ); void DropHealthPack( const CTakeDamageInfo &info, bool bEmpty ); void DropCurrencyPack( CurrencyRewards_t nSize = TF_CURRENCY_PACK_SMALL, int nAmount = 0, bool bForceDistribute = false, CBasePlayer* pMoneyMaker = NULL ); // Only pass in an amount when nSize = TF_CURRENCY_PACK_CUSTOM
bool CanDisguise( void ); bool CanDisguise_OnKill( void ); bool CanGoInvisible( bool bAllowWhileCarryingFlag = false ); void RemoveInvisibility( void );
bool CanStartPhase( void );
void RemoveDisguise( void );
bool DoClassSpecialSkill( void ); bool EndClassSpecialSkill( void );
bool CanPickupBuilding( CBaseObject *pPickupObject ); bool TryToPickupBuilding( void );
float GetLastDamageReceivedTime( void ) { return m_flLastDamageTime; } float GetLastEntityDamagedTime( void ) { return m_flLastDamageDoneTime; } void SetLastEntityDamagedTime( float flTime ) { m_flLastDamageDoneTime = flTime; } CBaseEntity *GetLastEntityDamaged( void ) { return m_hLastDamageDoneEntity; } void SetLastEntityDamaged( CBaseEntity *pEnt ) { m_hLastDamageDoneEntity = pEnt; }
void SetClassMenuOpen( bool bIsOpen ); bool IsClassMenuOpen( void );
float GetCritMult( void ) { return m_Shared.GetCritMult(); } void RecordDamageEvent( const CTakeDamageInfo &info, bool bKill, int nVictimPrevHealth ) { m_Shared.RecordDamageEvent(info,bKill,nVictimPrevHealth); }
bool GetHudClassAutoKill( void ){ return m_bHudClassAutoKill; } void SetHudClassAutoKill( bool bAutoKill ){ m_bHudClassAutoKill = bAutoKill; }
bool GetMedigunAutoHeal( void ){ return m_bMedigunAutoHeal; } void SetMedigunAutoHeal( bool bMedigunAutoHeal ){ m_bMedigunAutoHeal = bMedigunAutoHeal; } CBaseEntity *MedicGetHealTarget( void ); float MedicGetChargeLevel( CTFWeaponBase **pRetMedigun = NULL ); bool IsCallingForMedic( void ) const; // return true if this player has called for a Medic in the last few seconds
float GetTimeSinceCalledForMedic( void ) const; void NoteMedicCall( void );
bool ShouldAutoRezoom( void ) { return m_bAutoRezoom; } void SetAutoRezoom( bool bAutoRezoom ) { m_bAutoRezoom = bAutoRezoom; } bool ShouldAutoReload( void ){ return m_bAutoReload; } void SetAutoReload( bool bAutoReload ) { m_bAutoReload = bAutoReload; }
virtual void ModifyOrAppendCriteria( AI_CriteriaSet& criteriaSet );
virtual bool CanHearAndReadChatFrom( CBasePlayer *pPlayer ); virtual bool CanBeAutobalanced();
Vector GetClassEyeHeight( void );
void UpdateExpression( void ); void ClearExpression( void );
virtual IResponseSystem *GetResponseSystem(); virtual bool SpeakConceptIfAllowed( int iConcept, const char *modifiers = NULL, char *pszOutResponseChosen = NULL, size_t bufsize = 0, IRecipientFilter *filter = NULL );
virtual bool CanSpeakVoiceCommand( void ); virtual bool ShouldShowVoiceSubtitleToEnemy( void ); virtual void NoteSpokeVoiceCommand( const char *pszScenePlayed ); void SpeakWeaponFire( int iCustomConcept = MP_CONCEPT_NONE ); void ClearWeaponFireScene( void );
virtual int DrawDebugTextOverlays( void );
float m_flNextVoiceCommandTime; int m_iVoiceSpamCounter;
float m_flNextSpeakWeaponFire;
virtual int CalculateTeamBalanceScore( void );
bool ShouldAnnounceAchievement( void ) OVERRIDE; virtual void OnAchievementEarned( int iAchievement );
void CheckObserverSettings(); // checks, if target still valid (didn't die etc)
CTriggerAreaCapture *GetControlPointStandingOn( void ); CCaptureZone *GetCaptureZoneStandingOn( void ); CCaptureZone *GetClosestCaptureZone( void );
// given a vector of points, return the point we can actually travel to the quickest (requires a nav mesh)
CTeamControlPoint *SelectClosestControlPointByTravelDistance( CUtlVector< CTeamControlPoint * > *pointVector ) const;
bool CanAirDash( void ) const;
virtual bool CanBreatheUnderwater() const OVERRIDE; bool CanGetWet() const;
virtual bool IsDeflectable() { return true; } //=============================================================================
// HPE_BEGIN:
// [msmith] Added a player type so we can distinguish between bots and humans.
//=============================================================================
inline TFPlayerType GetPlayerType(){ return m_playerType; } inline void SetPlayerType( TFPlayerType playerType ){ m_playerType = playerType; } //=============================================================================
// HPE_END
//=============================================================================
virtual void OnNavAreaChanged( CNavArea *enteredArea, CNavArea *leftArea ); // invoked (by UpdateLastKnownArea) when we enter a new nav area (or it is reset to NULL)
bool IsThreatAimingTowardMe( CBaseEntity *threat, float cosTolerance = 0.8f ) const; // return true if the given threat is aiming in our direction
bool IsThreatFiringAtMe( CBaseEntity *threat ) const; // return true if the given threat is aiming in our direction and firing its weapon
bool IsInCombat( void ) const; // return true if we are engaged in active combat
void PlayerUse( void );
void InputIgnitePlayer( inputdata_t &inputdata ); void InputSetCustomModel( inputdata_t &inputdata ); void InputSetCustomModelOffset( inputdata_t &inputdata ); void InputSetCustomModelRotation( inputdata_t &inputdata ); void InputClearCustomModelRotation( inputdata_t &inputdata ); void InputSetCustomModelRotates( inputdata_t &inputdata ); void InputSetCustomModelVisibleToSelf( inputdata_t &inputdata ); void InputSetForcedTauntCam( inputdata_t &inputdata ); void InputExtinguishPlayer( inputdata_t &inputdata ); void InputBleedPlayer( inputdata_t &inputdata ); void InputTriggerLootIslandAchievement( inputdata_t &inputdata ); void InputTriggerLootIslandAchievement2( inputdata_t &inputdata ); void InputRollRareSpell( inputdata_t &inputdata ); void InputRoundSpawn( inputdata_t &inputdata );
bool InAirDueToExplosion( void ) { return (!(GetFlags() & FL_ONGROUND) && (GetWaterLevel() == WL_NotInWater) && (m_iBlastJumpState != 0) ); } bool InAirDueToKnockback( void ) { return (!(GetFlags() & FL_ONGROUND) && (GetWaterLevel() == WL_NotInWater) && ( (m_iBlastJumpState != 0) || m_Shared.InCond( TF_COND_KNOCKED_INTO_AIR ) || m_Shared.InCond( TF_COND_GRAPPLINGHOOK ) || m_Shared.InCond( TF_COND_GRAPPLINGHOOK_SAFEFALL ) ) ); }
bool IsCoaching() const { return m_bIsCoaching; } void SetIsCoaching( bool bIsCoaching );
void SetCoach( CTFPlayer *pCoach ) { m_hCoach = pCoach; } CTFPlayer* GetCoach() const { return m_hCoach; }
void SetStudent( CTFPlayer *pStudent ) { m_hStudent = pStudent; } CTFPlayer* GetStudent() const { return m_hStudent; }
void DoNoiseMaker(); // Halloween event item support.
bool IsWormsGearEquipped( void ) const; bool IsRobotCostumeEquipped( void ) const; bool IsDemowolf( void ) const; bool IsFrankenHeavy( void ) const; bool IsFairyHeavy( void ) const; bool IsZombieCostumeEquipped( void ) const; bool HasWearablesEquipped( const CSchemaItemDefHandle *ppItemDefs, int nWearables ) const;
CEconItemView *GetEquippedItemForLoadoutSlot( int iLoadoutSlot ){ return m_Inventory.GetInventoryItemByItemID( m_EquippedLoadoutItemIndices[iLoadoutSlot] ); } CBaseEntity *GetEntityForLoadoutSlot( int iLoadoutSlot ); //Gets whatever entity is associated with the loadout slot (wearable or weapon)
CTFWearable *GetEquippedWearableForLoadoutSlot( int iLoadoutSlot );
//Base entity overrides
// Functions that intercept Base Calls for Attribute Checking
void ApplyAbsVelocityImpulse ( const Vector &vecImpulse ); bool ApplyPunchImpulseX ( float flImpulse ); void ApplyAirBlastImpulse( const Vector &vecImpulse );
void SetUseBossHealthBar( bool bUseBossHealthBar ) { m_bUseBossHealthBar = bUseBossHealthBar; }
void SetUsingVRHeadset( bool bState ){ m_bUsingVRHeadset = bState; }
static bool m_bTFPlayerNeedsPrecache;
// IHasAttributes
CAttributeManager *GetAttributeManager( void ) { return &m_AttributeManager; } CAttributeContainer *GetAttributeContainer( void ) { return NULL; } CBaseEntity *GetAttributeOwner( void ) { return NULL; } CAttributeList *GetAttributeList( void ) { return &m_AttributeList; } virtual void ReapplyProvision( void ) { return; }
protected: CNetworkVarEmbedded( CAttributeContainerPlayer, m_AttributeManager );
//----------------------------
// INVENTORY MANAGEMENT
public: // IInventoryUpdateListener
virtual void InventoryUpdated( CPlayerInventory *pInventory );
virtual void SOCacheUnsubscribed( const CSteamID & steamIDOwner ) { m_Shared.SetLoadoutUnavailable( true ); }
// Inventory access
CTFPlayerInventory *Inventory( void ) { return &m_Inventory; }
private: CTFPlayerInventory m_Inventory; // Items that have been equipped on this player instance (the inventory loadout may have changed)
itemid_t m_EquippedLoadoutItemIndices[CLASS_LOADOUT_POSITION_COUNT];
public: void UpdateInventory( bool bInit ); void VerifySOCache();
CNetworkVarEmbedded( CTFPlayerShared, m_Shared ); friend class CTFPlayerShared;
int m_flNextTimeCheck; // Next time the player can execute a "timeleft" command
CNetworkVar( bool, m_bSaveMeParity ); CNetworkVar( bool, m_bIsCoaching); CNetworkHandle( CTFPlayer, m_hCoach ); CNetworkHandle( CTFPlayer, m_hStudent ); float m_flLastCoachCommand;
CNetworkVar( bool, m_bIsABot ); CNetworkVar( int, m_nBotSkill );
int StateGet( void ) const;
void SetOffHandWeapon( CTFWeaponBase *pWeapon ); void HolsterOffHandWeapon( void ); CTFWeaponBase* GetOffHandWeapon( void ) { return m_hOffHandWeapon; }
float GetSpawnTime() { return m_flSpawnTime; }
virtual void SelectItem( const char *pstr, int iSubType = 0 ) OVERRIDE; virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0 ) OVERRIDE; virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget , const Vector *pVelocity ) OVERRIDE;
virtual void OnMyWeaponFired( CBaseCombatWeapon *weapon ); // call this when this player fires a weapon to allow other systems to react
bool ItemsMatch( TFPlayerClassData_t *pData, CEconItemView *pCurWeaponItem, CEconItemView *pNewWeaponItem, CTFWeaponBase *pWpnEntity = NULL ); void ManageRegularWeapons( TFPlayerClassData_t *pData ); void ManageRegularWeaponsLegacy( TFPlayerClassData_t *pData ); // Older, pre-inventory method of managing regular weapons
void ManageBuilderWeapons( TFPlayerClassData_t *pData ); virtual CBaseEntity *GiveNamedItem( const char *szName, int iSubType = 0, const CEconItemView *pScriptItem = NULL, bool bForce = false ); void PostInventoryApplication( void ); bool ItemIsAllowed( CEconItemView *pItem ); void RemovePlayerAttributes( bool bSetBonuses ); void ApplySetBonuses( void ); void GetActiveSets( CUtlVector<const CEconItemSetDefinition *> *pItemSets ); void ValidateWeapons( TFPlayerClassData_t *pData, bool bResetWeapons ); void ValidateWearables( TFPlayerClassData_t *pData ); CEconItemView* GetLoadoutItem( int iClass, int iSlot, bool bReportWhitelistFails = false ); void UseActionSlotItemPressed( void ); void UseActionSlotItemReleased( void );
bool IsFireproof( void ) const; bool AddToSpyKnife( float value, bool force );
private: void GetHorriblyHackedRailgunPosition( const Vector& vStart, Vector *out_pvStartPos ); void MaybeDrawRailgunBeam( IRecipientFilter *pFilter, CTFWeaponBase *pWeapon, const Vector& vStartPos, const Vector& vEndPos );
// Taunts
public: bool IsReadyToTauntWithPartner( void ) const { return m_bIsReadyToHighFive; } CTFPlayer * GetTauntPartner( void ) { return m_hHighFivePartner; } float GetTauntYaw( void ) { return m_flTauntYaw; } float GetPrevTauntYaw( void ) { return m_flPrevTauntYaw; } void SetTauntYaw( float flTauntYaw ); CTFPlayer * FindPartnerTauntInitiator( void ); void AcceptTauntWithPartner( CTFPlayer *initiator ); void MimicTauntFromPartner( CTFPlayer *initiator ); bool CanMoveDuringTaunt(); bool ShouldStopTaunting(); bool IsTauntInitiator() const { return m_bIsTauntInitiator; } bool IsTauntForceMovingForward() const { return m_bTauntForceMoveForward; } float GetTauntMoveAcceleration() const { return m_flTauntMoveAccelerationTime; } float GetTauntMoveSpeed() const { return m_flTauntForceMoveForwardSpeed; } float GetTauntTurnAccelerationTime() const { return m_flTauntTurnAccelerationTime; } virtual int GetAllowedTauntPartnerTeam() const; CEconItemView *GetTauntEconItemView() { return m_TauntEconItemView.IsValid() ? &m_TauntEconItemView : NULL; }
int GetTauntConcept( CEconItemDefinition *pItemDef ); bool PlayTauntSceneFromItem( CEconItemView *pEconItemView ); void OnTauntSucceeded( const char* pszSceneName, int iTauntIndex = 0, int iTauntConcept = 0 ); void Taunt( taunts_t iTauntIndex = TAUNT_BASE_WEAPON, int iTauntConcept = 0 ); bool IsTaunting( void ) const { return m_Shared.InCond( TF_COND_TAUNTING ); } void DoTauntAttack( void ); bool IsAllowedToTaunt( void ); bool FindOpenTauntPartnerPosition( CEconItemView *pEconItemView, Vector &position, float *flTolerance ); bool IsAllowedToInitiateTauntWithPartner( CEconItemView *pEconItemView, char *pszErrorMessage = NULL, int cubErrorMessage = 0 ); void CancelTaunt( void ); void StopTaunt( void ); void EndLongTaunt(); float GetTauntRemoveTime( void ) const { return m_flTauntRemoveTime; } bool IsAllowedToRemoveTaunt() const { return m_bAllowedToRemoveTaunt; } void HandleTauntCommand( int iTauntSlot = 0 ); QAngle m_angTauntCamera;
CHandle< CBaseEntity > m_hTauntItem;
void ClearTauntAttack(); float GetTauntAttackTime() const { return m_flTauntAttackTime; }
void SetRPSResult( int iRPSResult ) { m_iTauntRPSResult = iRPSResult; }
void HandleWeaponSlotAfterTaunt();
float GetCurrentTauntMoveSpeed() const { return m_flCurrentTauntMoveSpeed; } void SetCurrentTauntMoveSpeed( float flSpeed ) { m_flCurrentTauntMoveSpeed = flSpeed; }
float GetVehicleReverseTime() const { return m_flVehicleReverseTime; } void SetVehicleReverseTime( float flTime ) { m_flVehicleReverseTime = flTime; }
private: void GetReadyToTauntWithPartner( void ); void CancelTauntWithPartner( void ); void StopTauntSoundLoop(); float PlayTauntOutroScene(); float PlayTauntRemapInputScene(); void ParseSharedTauntDataFromEconItemView( CEconItemView *pEconItemView );
CNetworkVar( bool, m_bAllowMoveDuringTaunt ); CNetworkVar( bool, m_bIsReadyToHighFive ); CNetworkHandle( CTFPlayer, m_hHighFivePartner ); CNetworkVar( int, m_nForceTauntCam ); CNetworkVar( float, m_flTauntYaw ); CNetworkVar( int, m_nActiveTauntSlot ); CNetworkVar( item_definition_index_t, m_iTauntItemDefIndex ); CNetworkVar( float, m_flCurrentTauntMoveSpeed ); CNetworkVar( float, m_flVehicleReverseTime );
bool m_bTauntForceMoveForward; float m_flTauntForceMoveForwardSpeed; float m_flTauntMoveAccelerationTime; float m_flTauntTurnSpeed; float m_flTauntTurnAccelerationTime;
float m_flPrevTauntYaw; EHANDLE m_hTauntScene; CHandle< CTFTauntProp > m_hTauntProp; bool m_bInitTaunt; bool m_bTauntMimic; bool m_bIsTauntInitiator; float m_flTauntSoundTime; CUtlString m_strTauntSoundName; float m_flTauntSoundLoopTime; CUtlString m_strTauntSoundLoopName; CEconItemView m_TauntEconItemView;
enum TauntStage_t { TAUNT_NONE = 0, TAUNT_INTRO, TAUNT_OUTRO } m_TauntStage;
bool m_bAllowedToRemoveTaunt; float m_flTauntStartTime; float m_flTauntRemoveTime; float m_flTauntOutroTime; Vector m_vecTauntStartPosition;
float m_flNextAllowTauntRemapInputTime; float m_flTauntAttackTime; float m_flTauntInhaleTime; taunt_attack_t m_iTauntAttack; int m_iTauntAttackCount; int m_iTauntRPSResult; int m_iPreTauntWeaponSlot; int m_iPreTauntFOV;
float m_flNextReflectZap;
public: virtual int GetSpecialDSP( void );
virtual float PlayScene( const char *pszScene, float flDelay = 0.0f, AI_Response *response = NULL, IRecipientFilter *filter = NULL ); void SetDeathFlags( int iDeathFlags ) { m_iDeathFlags = iDeathFlags; } int GetDeathFlags() { return m_iDeathFlags; } void SetMaxSentryKills( int iMaxSentryKills ) { m_iMaxSentryKills = iMaxSentryKills; } int GetMaxSentryKills() { return m_iMaxSentryKills; }
CNetworkVar( bool, m_iSpawnCounter ); void CheckForIdle( void ); inline bool IsAwayFromKeyboard( void ) { return m_bIsAFK; } void PickWelcomeObserverPoint();
virtual bool ProcessSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event );
void StopRandomExpressions( void ) { m_flNextRandomExpressionTime = -1; } void StartRandomExpressions( void ) { m_flNextRandomExpressionTime = gpGlobals->curtime; }
virtual bool WantsLagCompensationOnEntity( const CBasePlayer *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits ) const;
CTFWeaponBase *Weapon_OwnsThisID( int iWeaponID ) const; CTFWeaponBase *Weapon_GetWeaponByType( int iType );
medigun_charge_types GetChargeEffectBeingProvided( void );
// Achievements
void AwardAchievement( int iAchievement, int iCount = 1 ); void HandleAchievement_Medic_AssistHeavy( CTFPlayer *pPunchVictim ); void HandleAchievement_Pyro_BurnFromBehind( CTFPlayer *pBurner );
void ClearPunchVictims( void ) { m_aPunchVictims.RemoveAll(); } void ClearBurnFromBehindAttackers( void ) { m_aBurnFromBackAttackers.RemoveAll(); }
int RocketJumped( void ) { return m_iBlastJumpState & TF_PLAYER_ROCKET_JUMPED; } int StickyJumped( void ) { return m_iBlastJumpState & TF_PLAYER_STICKY_JUMPED; } void SetBlastJumpState( int iState, bool bPlaySound = false ); void ClearBlastJumpState( void );
int GetPreviousTeam( void ) { return m_iPreviousteam; } bool IsArenaSpectator( void ) { return m_bArenaSpectator; }
float GetTeamJoinTime( void ) { return m_flTeamJoinTime; } void MarkTeamJoinTime( void ) { m_flTeamJoinTime = gpGlobals->curtime; } void PlayerJustPlayed( bool bPlayed ) { m_bJustPlayed = bPlayed; } bool DidPlayerJustPlay( void ) { return m_bJustPlayed; }
bool IsCapturingPoint( void );
bool m_bSuicideExplode;
bool m_bScattergunJump; int m_iOldStunFlags;
bool m_bFlipViewModels; int m_iBlastJumpState; float m_flBlastJumpLandTime; bool m_bTakenBlastDamageSinceLastMovement;
void SetTargetDummy( void ){ m_bIsTargetDummy = true; }
bool ShouldCollideWithSentry( void ){ return m_bCollideWithSentry; } bool IsAnyEnemySentryAbleToAttackMe( void ) const; // return true if any enemy sentry has LOS and is facing me and is in range to attack
int GetHealthBefore( void ) { return m_iHealthBefore; }
int GetAutoTeam( int nPreferedTeam = TF_TEAM_AUTOASSIGN ); bool ShouldForceAutoTeam( void );
float m_flCommentOnCarrying;
int GetTeamChangeCount( void ) { return m_iTeamChanges; } int GetClassChangeCount( void ) { return m_iClassChanges; }
void IncrementKillCountSinceLastDeploy( const CTakeDamageInfo &info );
void ForceItemRemovalOnRespawn( void ) { m_bForceItemRemovalOnRespawn = true; }
// Item Testing
public: void ItemTesting_Start( KeyValues *pKV ); void ItemTesting_UpdateBots( KeyValues *pKV ); CEconItemView *ItemTesting_GetTestItem( int iClass, int iSlot ); void ItemTesting_DeleteItems();
public: struct itemtest_t { KeyValues *pKV; CEconItemView scriptItem; }; CUtlVector<itemtest_t> m_ItemsToTest; bool m_bItemTestingRespawn;
bool IsMissionEnemy( void ){ return m_bIsMissionEnemy; } void MarkAsMissionEnemy( void ){ m_bIsMissionEnemy = true; } bool IsSupportEnemy( void ){ return m_bIsSupportEnemy; } void MarkAsSupportEnemy( void ){ m_bIsSupportEnemy = true; } void MarkAsLimitedSupportEnemy( void ){ m_bIsLimitedSupportEnemy = true; }
// In-game currency
int GetCurrency( void ) const { return m_nCurrency; } void SetCurrency( int nAmount ){ m_nCurrency = nAmount; } void AddCurrency( int nAmount ); void RemoveCurrency( int nAmount );
// Set the amount of money this bot is worth when killed. We re-use m_nCurrency, because bots don't collect currency.
void SetCustomCurrencyWorth( int nAmount ) { m_nCurrency = nAmount; }
// Bounty Mode
int GetExperienceLevel( void ) { return m_nExperienceLevel; } void SetExperienceLevel( int nValue ) { m_nExperienceLevel.Set( MAX( nValue, 1 ) ); } int GetExperiencePoints( void ) { return m_nExperiencePoints; } void SetExperiencePoints( int nValue ) { m_nExperiencePoints = MAX( nValue, 0 ); } void AddExperiencePoints( int nValue, bool bGiveCurrency = false, CTFPlayer *pSource = NULL ); void CalculateExperienceLevel( bool bAnnounce = true ); void RefundExperiencePoints( void );
void RememberUpgrade( int iPlayerClass, CEconItemView *pItem, int iUpgrade, int nCost, bool bDowngrade = false ); // store this upgrade for restoring at a checkpoint
void ForgetFirstUpgradeForItem( CEconItemView *pItem ); // erase the first upgrade stored for this item (for powerup bottles)
void ClearUpgradeHistory( void ); void ReapplyItemUpgrades ( CEconItemView *pItem ); void ReapplyPlayerUpgrades ( void ); void SetWaveSpawnPopulator( CWaveSpawnPopulator *pWave ){ m_pWaveSpawnPopulator = pWave; } CUtlVector< CUpgradeInfo >* GetRefundableUpgrades( void ) { return &m_RefundableUpgrades; } void ResetRefundableUpgrades( void ) { m_RefundableUpgrades.RemoveAll(); } void BeginPurchasableUpgrades( void ); void EndPurchasableUpgrades( void ); bool CanPurchaseUpgrades( void ) const { Assert( m_nCanPurchaseUpgradesCount >= 0 ); return m_nCanPurchaseUpgradesCount > 0; }
void PlayReadySound( void );
void AccumulateSentryGunDamageDealt( float damage ); void ResetAccumulatedSentryGunDamageDealt(); float GetAccumulatedSentryGunDamageDealt();
void IncrementSentryGunKillCount( void ); void ResetAccumulatedSentryGunKillCount(); int GetAccumulatedSentryGunKillCount();
bool PlaySpecificSequence( const char *pSequenceName );
void SetWaterExitTime( float flTime ){ m_flWaterExitTime = flTime; } float GetWaterExitTime( void ){ return m_flWaterExitTime; }
void MerasmusPlayerBombExplode( bool bExcludeMe = true );
void DropDeathCallingCard( CTFPlayer* pTFAttacker, CTFPlayer* pTFVictim );
//---------------------------------
// support entity IO for forcing speech concepts
void InputSpeakResponseConcept( inputdata_t &inputdata );
//---------------------------------
float GetTimeSinceLastThink( void ) const { return ( m_flLastThinkTime >= 0.f ) ? gpGlobals->curtime - m_flLastThinkTime : -1.f; } float GetRespawnTimeOverride( void ) const { return m_flRespawnTimeOverride; } const char *GetRespawnLocationOverride( void ) const { return ( m_strRespawnLocationOverride == NULL_STRING ) ? NULL : m_strRespawnLocationOverride.ToCStr(); } void SetRespawnOverride( float flRespawnTime, string_t respawnLocation ) { m_flRespawnTimeOverride = flRespawnTime; m_strRespawnLocationOverride = respawnLocation; } void ResetIdleCheck( void ) { m_flLastAction = gpGlobals->curtime; }
// Matchmaking
void SetMatchSafeToLeave( bool bMatchSafeToLeave ) { m_bMatchSafeToLeave = bMatchSafeToLeave; }
void SetPrevRoundTeamNum( int nTeamNum ){ m_nPrevRoundTeamNum = nTeamNum; } int GetPrevRoundTeamNum( void ){ return m_nPrevRoundTeamNum; }
protected:
// Creation/Destruction.
virtual void InitClass( void ); void GiveDefaultItems(); bool SelectSpawnSpotByType( const char *pEntClassName, CBaseEntity* &pSpot ); // "info_player_teamspawn"
bool SelectSpawnSpotByName( const char *pEntName, CBaseEntity* &pSpot ); // named info_player_teamspawn, i.e. "my_blue_offense_respawns"
void RemoveNemesisRelationships(); void RemoveAllItems();
// Think.
void TFPlayerThink(); void UpdateTimers( void );
// Regeneration due to being a Medic, or derived from items
void RegenThink(); void RuneRegenThink(); void RegenAmmoInternal( int iAmmo, float flRegen ); void ResetPlayerClass( void );
virtual void Internal_HandleMapEvent( inputdata_t &inputdata ) OVERRIDE;
private: float m_flAccumulatedHealthRegen; // Regeneration can be in small amounts, so we accumulate it and apply when it's > 1
float m_flNextAmmoRegenAt; float m_flLastHealthRegenAt; float m_flAccumulatedRuneHealthRegen; float m_flNextRuneAmmoRegenAt; float m_flLastRuneHealthRegenAt; float m_flAccumulatedAmmoRegens[TF_AMMO_SECONDARY+1]; // Only support regenerating primary & secondary right now
// Bots.
friend void Bot_Think( CTFPlayer *pBot );
// Physics.
void PhysObjectSleep(); void PhysObjectWake();
// Ammo pack.
bool CalculateAmmoPackPositionAndAngles( CTFWeaponBase *pWeapon, Vector &vecOrigin, QAngle &vecAngles ); void AmmoPackCleanUp( void );
// State.
CPlayerStateInfo *StateLookupInfo( int nState ); void StateEnter( int nState ); void StateLeave( void ); void StateTransition( int nState ); void StateEnterWELCOME( void ); void StateThinkWELCOME( void ); void StateEnterPICKINGTEAM( void ); void StateEnterACTIVE( void ); void StateEnterOBSERVER( void ); void StateThinkOBSERVER( void ); void StateEnterDYING( void ); void StateThinkDYING( void );
virtual bool SetObserverMode(int mode); virtual void AttemptToExitFreezeCam( void );
bool PlayGesture( const char *pGestureName );
bool GetResponseSceneFromConcept( int iConcept, char *chSceneBuffer, int numSceneBufferBytes );
public: // Achievement data storage
CAchievementData m_AchievementData; CTFPlayerAnimState *m_PlayerAnimState;
private: // Map introductions
int m_iIntroStep; CHandle<CIntroViewpoint> m_hIntroView; float m_flIntroShowHintAt; float m_flIntroShowEventAt; bool m_bHintShown; bool m_bAbortFreezeCam; bool m_bSeenRoundInfo; bool m_bRegenerating;
// Items.
CNetworkHandle( CTFItem, m_hItem );
// Combat.
CNetworkHandle( CTFWeaponBase, m_hOffHandWeapon );
float m_flHealthBuffTime; int m_iHealthBefore;
float m_flNextRegenerateTime; float m_flNextChangeClassTime; float m_flNextChangeTeamTime; bool m_bAllSeeCrit; bool m_bMiniCrit; bool m_bShowDisguisedCrit; EAttackBonusEffects_t m_eBonusAttackEffect;
int m_iTeamChanges; int m_iClassChanges;
// Ragdolls.
Vector m_vecTotalBulletForce;
// State.
CPlayerStateInfo *m_pStateInfo;
// Spawn Point
CTFTeamSpawn *m_pSpawnPoint;
// Networked.
CNetworkQAngle( m_angEyeAngles ); // Copied from EyeAngles() so we can send it to the client.
CTFPlayerClass m_PlayerClass; int m_iLastWeaponFireUsercmd; // Firing a weapon. Last usercmd we shot a bullet on.
int m_iLastWeaponSlot; // To save last switch between lives
int m_iLastSkin; CNetworkVar( float, m_flLastDamageTime ); float m_flLastDamageDoneTime; CHandle< CBaseEntity > m_hLastDamageDoneEntity; float m_flLastHealedTime; float m_flNextPainSoundTime; int m_LastDamageType; int m_iDeathFlags; // TF_DEATH_* flags with additional death info
int m_iMaxSentryKills; // most kills by a single sentry
int m_iNumberofDominations; // number of active dominations for this player
bool m_bPlayedFreezeCamSound; bool m_bSwitchedClass; bool m_bRememberLastWeapon; bool m_bRememberActiveWeapon; int m_iActiveWeaponTypePriorToDeath;
CHandle< CTFWeaponBuilder > m_hWeaponBuilder;
CUtlVector<EHANDLE> m_aObjects; // List of player objects
bool m_bIsClassMenuOpen;
Vector m_vecLastDeathPosition;
float m_flSpawnTime;
float m_flLastAction; float m_flTimeInSpawn;
CUtlVector<EHANDLE> m_hObservableEntities; CUtlVector<float> m_aBurnOtherTimes; // vector of times this player has burned others
bool m_bHudClassAutoKill;
// Background expressions
string_t m_iszExpressionScene; EHANDLE m_hExpressionSceneEnt; float m_flNextRandomExpressionTime;
bool m_bSpeakingConceptAsDisguisedSpy;
bool m_bMedigunAutoHeal; bool m_bAutoRezoom; // does the player want to re-zoom after each shot for sniper rifles
bool m_bAutoReload;
bool m_bForceItemRemovalOnRespawn;
int m_nPrevRoundTeamNum;
public: // Powerplay cheats
bool SetPowerplayEnabled( bool bOn ); bool PlayerHasPowerplay( void ); void PowerplayThink( void ); CNetworkVar( bool, m_bInPowerPlay );
bool IsGoingFeignDeath( void ) { return m_bGoingFeignDeath; }
void SetDeployingBombState( BombDeployingState_t nDeployingBombState ) { m_nDeployingBombState = nDeployingBombState; } BombDeployingState_t GetDeployingBombState( void ) const { return m_nDeployingBombState; }
void SetPendingMerasmusPlayerBombExplode( void ){ m_bPendingMerasmusPlayerBombExplode = true; }
private: // Achievement data
CUtlVector<EHANDLE> m_aPunchVictims; CUtlVector<EHANDLE> m_aBurnFromBackAttackers; int m_iLeftGroundHealth; // health we were at the last time we left the ground
float m_flTeamJoinTime; bool m_bCreatedRocketJumpParticles; bool m_bJustPlayed; int m_iPreviousteam; bool m_bGibbedOnLastDeath; CUtlMap<int, float> m_Cappers; float m_fMaxHealthTime;
// Feign death.
bool m_bGoingFeignDeath; CHandle<CBaseEntity> m_hFeignRagdoll; // Don't use the normal ragdoll.
Vector m_vecFeignDeathVelocity;
CNetworkVar( bool, m_bArenaSpectator );
bool m_bArenaIsAFK; // used to detect when players are AFK during an Arena-mode round
bool m_bIsAFK;
BombDeployingState_t m_nDeployingBombState;
bool m_bIsMissionEnemy; bool m_bIsSupportEnemy; bool m_bIsLimitedSupportEnemy;
// In-game currency
CNetworkVar( int, m_nCurrency ); CNetworkVar( bool, m_bIsMiniBoss );
// Bounty Mode
CNetworkVar( uint32, m_nExperienceLevel ); CNetworkVar( uint32, m_nExperienceLevelProgress ); // Networked progress bar
uint32 m_nExperiencePoints; // Raw player-only value
// Matchmaking
// is this player bound to the match on penalty of abandon. Sync'd via local-player-only DT
CNetworkVar( bool, m_bMatchSafeToLeave );
CWaveSpawnPopulator *m_pWaveSpawnPopulator; float m_flLastReadySoundTime;
int m_nCanPurchaseUpgradesCount; CUtlVector< CUpgradeInfo > m_RefundableUpgrades;
public: // Marking for death.
CHandle<CTFPlayer> m_pMarkedForDeathTarget;
CountdownTimer m_playerMovementStuckTimer; // for destroying stuck bots in MvM
QAngle m_qPreviousChargeEyeAngle; // Previous EyeAngles to compute deltas for legal mouse movement
private:
//=============================================================================
// HPE_BEGIN:
// [msmith] Added a player type so we can distinguish between bots and humans.
//=============================================================================
TFPlayerType m_playerType; //=============================================================================
// HPE_END
//=============================================================================
bool m_bIsTargetDummy;
bool m_bCollideWithSentry; IntervalTimer m_calledForMedicTimer; CountdownTimer m_placedSapperTimer;
CountdownTimer m_inCombatThrottleTimer;
mutable char m_bIsCalculatingMaximumSpeed;
public:
float GetDesiredHeadScale() const; float GetHeadScaleSpeed() const; float GetDesiredTorsoScale() const; float GetTorsoScaleSpeed() const; float GetDesiredHandScale() const; float GetHandScaleSpeed() const;
bool IsInPurgatory( void ) const; bool HasPurgatoryBuff( void ) const;
void SetBombHeadTimestamp(); float GetTimeSinceWasBombHead() const; float GetKartSpeedBoost( void ); float GetKartHealth( void ) { return m_iKartHealth; } void AddKartDamage( int iDamage ) { m_iKartHealth = Max(0, m_iKartHealth + iDamage); } float GetKartKnockbackMultiplier( float flExtraMultiplier ) const; void ResetKartDamage(); CBaseEntity *GetKartBombHeadTarget() const { return m_hKartBombHeadTarget; } void SetKartBombHeadTarget( CBaseEntity* pEnt ) { m_hKartBombHeadTarget = pEnt; }
void AddHalloweenKartPushEvent( CTFPlayer *pOther, CBaseEntity *pInflictor, CBaseEntity *pWeapon, Vector vForce, int iDamage, int iDamageType = 0 ); QAngle GetAnimRenderAngles( void ) { return m_PlayerAnimState->GetRenderAngles(); }
void CancelEurekaTeleport();
CNetworkVar( int, m_iKartState ); CNetworkVar( float, m_flKartNextAvailableBoost ); float m_flHHHKartAttackTime;
// Wrenchmotron teleport
bool m_bIsTeleportingUsingEurekaEffect;
private: void UpdateHalloween( void );
Vector m_vHalloweenKartPush; float m_flHalloweenKartPushEventTime; bool m_bCheckKartCollision; EHANDLE m_hKartBombHeadTarget; float m_flNextBonusDucksVOAllowedTime;
CNetworkVar( int, m_iKartHealth );
float m_flGhostLastHitByKartTime;
bool m_bIsInPurgatory; // for 2011 Halloween event
CountdownTimer m_purgatoryBuffTimer; CountdownTimer m_purgatoryPainMultiplierTimer; int m_purgatoryPainMultiplier; CNetworkVar( float, m_flHeadScale ); CNetworkVar( float, m_flTorsoScale ); CNetworkVar( float, m_flHandScale );
//CountdownTimer m_fireproofTimer; // if active, we're fireproof
// Wrenchmotron teleport
CountdownTimer m_teleportHomeFlashTimer; eEurekaTeleportTargets m_eEurekaTeleportTarget;
float m_accumulatedSentryGunDamageDealt; // for Sentry Buster missions in MvM
int m_accumulatedSentryGunKillCount; // for Sentry Buster missions in MvM
static const int DPS_Period = 90; // The duration of the sliding window for calculating DPS, in seconds
int *m_damageRateArray; // One array element per second, for accumulating damage done during that time
int m_lastDamageRateIndex; int m_peakDamagePerSecond;
CNetworkVar( uint16, m_nActiveWpnClip ); uint16 m_nActiveWpnClipPrev; float m_flNextClipSendTime;
float m_flWaterExitTime; bool m_bPendingMerasmusPlayerBombExplode; float m_fLastBombHeadTimestamp;
bool m_bIsSapping; int m_iSappingEvent; float m_flSapStartTime; float m_flLastThinkTime; float m_flRespawnTimeOverride; string_t m_strRespawnLocationOverride;
CountdownTimer m_booTimer;
CNetworkVar( bool, m_bUseBossHealthBar );
CNetworkVar( bool, m_bUsingVRHeadset );
CNetworkVar( bool, m_bForcedSkin ); CNetworkVar( int, m_nForcedSkin );
private: CHandle< CTFReviveMarker > m_hReviveMarker; public: CTFReviveMarker *GetReviveMarker( void ) { return m_hReviveMarker; }
// Send ForcePlayerViewAngles user message. Handled in __MsgFunc_ForcePlayerViewAngles in
// clientmode_tf.cpp. Sets Local and Abs angles, along with TauntYaw and VehicleMovingAngles.
void ForcePlayerViewAngles( const QAngle& qTeleportAngles );
CBaseEntity *GetGrapplingHookTarget() const { return m_hGrapplingHookTarget; } void SetGrapplingHookTarget( CBaseEntity *pTarget, bool bShouldBleed = false );
bool IsUsingActionSlot() const { return m_bUsingActionSlot; }
void SetSecondaryLastWeapon( CBaseCombatWeapon *pSecondaryLastWeapon ) { m_hSecondaryLastWeapon = pSecondaryLastWeapon; } CBaseCombatWeapon* GetSecondaryLastWeapon() const { return m_hSecondaryLastWeapon; }
bool CanBeForcedToLaugh( void );
void CreateDisguiseWeaponList( CTFPlayer *pDisguiseTarget ); void ClearDisguiseWeaponList();
bool CanPickupDroppedWeapon( const CTFDroppedWeapon *pWeapon ); CTFDroppedWeapon* GetDroppedWeaponInRange();
bool HasCampaignMedal( int iMedal ); void SetCampaignMedalActive( int iMedal ){ m_iCampaignMedals |= iMedal; }
void InspectButtonPressed(); void InspectButtonReleased(); bool IsInspecting() const;
void SetNextScorePointForPD( float flTime ){ m_flNextScorePointForPD = flTime; } bool CanScorePointForPD( void ) const;
void AddCustomAttribute( const char *pszAttributeName, float flVal, float flDuration = -1.f ); void RemoveCustomAttribute( const char *pszAttributeName );
int GetSkinOverride() const { return m_iPlayerSkinOverride; }
bool ShouldGetBonusPointsForExtinguishEvent( int userID );
void SetLastAutobalanceTime( float flTime ) { m_flLastAutobalanceTime = flTime; } float GetLastAutobalanceTime() { return m_flLastAutobalanceTime; }
private: bool PickupWeaponFromOther( CTFDroppedWeapon *pDroppedWeapon ); bool TryToPickupDroppedWeapon(); float m_flSendPickupWeaponMessageTime;
void ModifyDamageInfo( CTakeDamageInfo *pInfo, const CBaseEntity *pTarget );
CNetworkHandle( CBaseEntity, m_hGrapplingHookTarget ); float m_flLastSeenHookTarget; int m_nHookAttachedPlayers;
CNetworkHandle( CBaseCombatWeapon, m_hSecondaryLastWeapon ); CNetworkVar( bool, m_bUsingActionSlot );
CNetworkVar( float, m_flInspectTime );
CUtlVector< CHandle< CTFWeaponBase > > m_hDisguiseWeaponList; // copy disguise target weapons to this list
CNetworkVar( int, m_iCampaignMedals );
float m_flNextScorePointForPD;
float m_flLastRuneChargeUpdate; float m_flLastDamageResistSoundTime;
void UpdateCustomAttributes(); void RemoveAllCustomAttributes(); CUtlMap< CUtlString, float > m_mapCustomAttributes;
CNetworkVar( int, m_iPlayerSkinOverride );
CUtlMap<int, float> m_PlayersExtinguished; // userID and most recent time they were extinguished for bonus points
float m_flLastAutobalanceTime; // begin passtime
public: bool SayAskForBall(); bool m_bPasstimeBallSlippery; // end passtime
virtual bool ShouldForceTransmitsForTeam( int iTeam ) OVERRIDE;
virtual bool IsTruceValidForEnt( void ) const OVERRIDE; };
//-----------------------------------------------------------------------------
// Purpose: Utility function to convert an entity into a tf player.
// Input: pEntity - the entity to convert into a player
//-----------------------------------------------------------------------------
inline CTFPlayer *ToTFPlayer( CBaseEntity *pEntity ) { if ( !pEntity || !pEntity->IsPlayer() ) return NULL;
Assert( dynamic_cast<CTFPlayer*>( pEntity ) != 0 ); return static_cast< CTFPlayer* >( pEntity ); }
inline bool CTFPlayer::IsFireproof( void ) const { return m_Shared.InCond( TF_COND_FIRE_IMMUNE ); }
inline bool CTFPlayer::HasPurgatoryBuff( void ) const { return m_purgatoryBuffTimer.HasStarted() && !m_purgatoryBuffTimer.IsElapsed(); }
inline void CTFPlayer::OnSapperPlaced( CBaseEntity *sappedObject ) { m_placedSapperTimer.Start( 3.0f ); } inline void CTFPlayer::OnSapperStarted( float flStartTime ) { if (m_iSappingEvent == TF_SAPEVENT_NONE && m_flSapStartTime == 0.00 ) { m_flSapStartTime = flStartTime; m_bIsSapping = true; m_iSappingEvent = TF_SAPEVENT_PLACED; } } inline void CTFPlayer::OnSapperFinished( float flStartTime ) { if (m_iSappingEvent == TF_SAPEVENT_NONE && flStartTime == m_flSapStartTime ) { m_bIsSapping = false; m_flSapStartTime = 0.00; m_iSappingEvent = TF_SAPEVENT_DONE; } } inline bool CTFPlayer::IsSapping( void ) const { return m_bIsSapping; }
inline int CTFPlayer::GetSappingEvent( void ) const { return m_iSappingEvent; }
inline void CTFPlayer::ClearSappingEvent( void ) { m_iSappingEvent = TF_SAPEVENT_NONE; }
inline void CTFPlayer::ClearSappingTracking( void ) { ClearSappingEvent(); m_bIsSapping = false; m_flSapStartTime = 0.00; }
inline bool CTFPlayer::IsPlacingSapper( void ) const { return !m_placedSapperTimer.IsElapsed(); }
inline int CTFPlayer::StateGet( void ) const { return m_Shared.m_nPlayerState; }
inline bool CTFPlayer::IsInCombat( void ) const { // the simplest condition is whether we've been firing our weapon very recently
return GetTimeSinceWeaponFired() < 2.0f; }
inline bool CTFPlayer::IsCallingForMedic( void ) const { return m_calledForMedicTimer.HasStarted() && m_calledForMedicTimer.IsLessThen( 5.0f ); }
inline float CTFPlayer::GetTimeSinceCalledForMedic() const { return m_calledForMedicTimer.GetElapsedTime(); }
inline void CTFPlayer::NoteMedicCall( void ) { m_calledForMedicTimer.Start(); }
inline bool CTFPlayer::IsInPurgatory( void ) const { return m_Shared.InCond( TF_COND_PURGATORY ); }
inline void CTFPlayer::AccumulateSentryGunDamageDealt( float damage ) { m_accumulatedSentryGunDamageDealt += damage; }
inline void CTFPlayer::ResetAccumulatedSentryGunDamageDealt() { m_accumulatedSentryGunDamageDealt = 0.0f; }
inline float CTFPlayer::GetAccumulatedSentryGunDamageDealt() { return m_accumulatedSentryGunDamageDealt; }
inline void CTFPlayer::IncrementSentryGunKillCount( void ) { ++m_accumulatedSentryGunKillCount; }
inline void CTFPlayer::ResetAccumulatedSentryGunKillCount() { m_accumulatedSentryGunKillCount = 0; }
inline int CTFPlayer::GetAccumulatedSentryGunKillCount() { return m_accumulatedSentryGunKillCount; }
inline int CTFPlayer::GetDamagePerSecond( void ) const { return m_peakDamagePerSecond; }
inline void CTFPlayer::ResetDamagePerSecond( void ) { for( int i=0; i<DPS_Period; ++i ) { m_damageRateArray[i] = 0; }
m_lastDamageRateIndex = -1; m_peakDamagePerSecond = 0; }
//=============================================================================
//
// CObserverPoint
//
class CObserverPoint : public CPointEntity { DECLARE_CLASS( CObserverPoint, CPointEntity ); public: DECLARE_DATADESC();
CObserverPoint();
virtual void Activate( void ); bool CanUseObserverPoint( CTFPlayer *pPlayer ); virtual int UpdateTransmitState(); void InputEnable( inputdata_t &inputdata ); void InputDisable( inputdata_t &inputdata );
bool IsDefaultWelcome( void ) { return m_bDefaultWelcome; } bool IsMatchSummary( void ) { return m_bMatchSummary; }
void SetDisabled( bool bDisabled ){ m_bDisabled = bDisabled; }
public: bool m_bDisabled; bool m_bDefaultWelcome; EHANDLE m_hAssociatedTeamEntity; string_t m_iszAssociateTeamEntityName; float m_flFOV; bool m_bMatchSummary; };
#endif // TF_PLAYER_H
|