source-engine/game/server/tf2/tf_player.h

597 lines
17 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef TF_PLAYER_H
#define TF_PLAYER_H
#ifdef _WIN32
#pragma once
#endif
#include "player.h"
#include "tf_shareddefs.h"
#include "tf_playerlocaldata.h"
#include "tf_playerclass.h"
#include "iscorer.h"
#include "tf_playeranimstate.h"
#include "vphysics/player_controller.h"
#define MENU_STRING_BUFFER_SIZE 512
#define MENU_MSG_TEXTCHUNK_SIZE 50
#define MENU_UPDATETIME 2.0
class CVehicleTeleportStation;
class CPlayerClass;
class CThrownGrenade;
class CFlybyPoint;
class CMenu;
class CControlZone;
class CTechnologyTree;
class CTFTeam;
class CWeaponBuilder;
class CWeaponCombatShield;
class COrder;
class CBaseTFCombatWeapon;
class CResourceZone;
class CRagdollShadow;
class CBaseObject;
class CBasePredictedWeapon;
class IVehicle;
enum ResupplyReason_t;
// If disguised player fires weapon, suppress disguise for this long
#define DISGUISE_FIRE_SUPPRESSTIME 4.0f
// If there are enemies within this radius, then
// firing your weapon will cause you to lose your
// disguise for DISGUISE_FIRE_SUPPRESSTIME
#define DISGUISE_SUPPRESSION_RADIUS 1024.0f
// Can only initiate disguise if no enemies within this radius
#define DISGUISE_START_RADIUS 512.0f
// Adrenalin
#define ADRENALIN_DAMAGE_REDUCTION 0.5 // Damage reduction during adrenalin
#define ADRENALIN_SPEED_INCREASE 1.2 // Movement speed increase during adrenalin
#define ADRENALIN_RAMPAGE_EXTEND 5.0 // Time gained from killing an enemy during rampage
// ID
#define MAX_ID_RANGE 2048
// Setup for class specific touch functions.
#define SetClassTouch( _player, a ) _player->SetTouch( CBaseTFPlayer::ClassTouch ); _player->m_pfnClassTouch = static_cast<void (CPlayerClass::*)(CBaseEntity*)>(a)
//=====================================================================
// TF PLAYER
//=====================================================================
class CBaseTFPlayer : public CBasePlayer, public IScorer
{
typedef CBasePlayer BaseClass;
public:
DECLARE_CLASS( CBaseTFPlayer, CBasePlayer );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
DECLARE_PREDICTABLE();
CBaseTFPlayer();
~CBaseTFPlayer();
// For updating hud tech tree
struct tfplayertech_t
{
int m_nAvailable;
int m_nUserCount;
int m_nResourceLevel;
};
// Helper to get a CBaseTFPlayer by its entity index.
static CBaseTFPlayer* Instance( int iEnt )
{
return dynamic_cast< CBaseTFPlayer* >( CBaseEntity::Instance( INDEXENT( iEnt ) ) );
}
bool IsHidden() const;
void SetHidden( bool bHidden );
// Class specific touch functions.
void ClassTouch( CBaseEntity *pTouched );
// This normally wouldn't go in here but we have to access CAllPlayerClasses and that is private.
const char* GetClassModelString( int iClass, int iTeam );
// The player class touch function
void (CPlayerClass ::*m_pfnClassTouch)( CBaseEntity *pOther );
// Override CBaseAnimatingOverlay to zero out m_dweights by default
virtual int AddGesture( Activity activity, bool autokill = true );
// Hacky shield stuff for now
void RemoveShieldOverlays( void );
int RemoveShieldOverlaysExcept( Activity activity, bool addifnotpresent = true );
Activity ShieldTranslateActivity( Activity activity );
void PickShieldAnimation( Activity& activity, int& overlayindex,
bool moving, bool ducked,
Activity overlay, Activity crouch, Activity normal,
bool autokill = true, float blendin = 0.0f, float blendout = 0.0f );
// True if player was moving last time checked (used to switch between shield full body and overlay anims )
bool m_bWasMoving;
virtual void UpdateOnRemove( void );
static CBaseTFPlayer *CreatePlayer( const char *className, edict_t *ed )
{
CBaseTFPlayer::s_PlayerEdict = ed;
return (CBaseTFPlayer*)CreateEntityByName( className );
}
virtual int UpdateTransmitState();
virtual int ShouldTransmit( const CCheckTransmitInfo *pInfo );
// Networking is about to update this player, let it override and specify it's own pvs
virtual void SetupVisibility( CBaseEntity *pViewEntity, unsigned char *pvs, int pvssize );
virtual void Spawn( void );
virtual void InitialSpawn( void );
virtual void ForceRespawn( void );
virtual void UpdateClientData( void );
virtual void ForceClientDllUpdate( void ); // Forces all client .dll specific data to be resent to client.
virtual void Precache( void );
virtual void InitHUD( void );
virtual void SelectItem( const char *pstr, int iSubType = 0 );
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual int ObjectCaps( void );
// Override
virtual bool CanSpeak( void );
void ResetViewOffset( void );
// Input handlers
void InputRespawn( inputdata_t &inputdata );
// Team Handling
CTFTeam *GetTFTeam( void ) { return (CTFTeam*)GetTeam(); };
CTechnologyTree *GetTechTree( void );
virtual void ChangeTeam( int iTeamNum ) OVERRIDE;
void PlacePlayerInTeam( void );
// Class Handling
int PlayerClass( void );
bool IsClass( TFClass iClass );
bool IsSameClass( CBaseTFPlayer* pPlayer ) { Assert(pPlayer); return IsClass( (TFClass)pPlayer->PlayerClass() ); }
void ChangeClass( TFClass iClass );
bool IsClassAvailable( TFClass iClass );
void SetPlayerModel( void );
CPlayerClass *GetPlayerClass();
void ClearPlayerClass( void );
void SetPlayerClass( TFClass iClass );
int ClassCostAdjustment( ResupplyBuyType_t nType );
// Menu Handling
void MenuDisplay( void );
bool MenuInput( int iInput );
void MenuReset( void );
// Standard functions
virtual void ItemPostFrame();
virtual void Jump( void );
void PostThink( void );
void PreThink( void );
void PlayerRespawn( void );
CBaseEntity *EntSelectSpawnPoint( void );
// Death
virtual void DeathSound( const CTakeDamageInfo &info );
virtual void PainSound( const CTakeDamageInfo &info );
virtual void Event_Killed( const CTakeDamageInfo &info );
void TFPlayerDeathThink( void );
virtual void CheatImpulseCommands( int iImpulse );
virtual bool ClientCommand( const CCommand &args );
virtual void SetAnimation( PLAYER_ANIM playerAnim );
// Combat
void RecalculateSpeed( void );
void KilledPlayer( CBaseTFPlayer *pVictim );
int TakeHealth( float flHealth, int bitsDamageType );
// Combat
virtual int OnTakeDamage( const CTakeDamageInfo &info );
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );
void ShowPersonalShieldEffect( const Vector &vOffsetFromEnt, const Vector &vIncomingDirection, float flDamage );
// Objects
void AddObject( CBaseObject *pObject );
void RemoveObject( CBaseObject *pObject );
int CanBuild( int iObjectType );
int GetNumObjects( int iObjectType );
int GetObjectCount( );
CBaseObject *GetObject( int iObjectIndex );
bool IsBuilding( void );
void OwnedObjectDestroyed( CBaseObject *pObject );
void StopPlacement( void );
int StartedBuildingObject( int iObjectType );
void StoppedBuilding( int iObjectType );
void FinishedObject( CBaseObject *pObject );
void SetWeaponBuilder( CWeaponBuilder *pBuilder );
CWeaponBuilder *GetWeaponBuilder( void );
CWeaponCombatShield *GetCombatShield( void );
void OwnedObjectChangeTeam( CBaseObject *pObject, CBaseTFPlayer *pNewOwner );
void RemoveAllObjects( bool bForceAll = false, int iClass = 0, bool bReturnResources = false );
int NumPumpsOnResourceZone( CResourceZone *pZone );
// Deployment
void StartDeploying( void );
void StartUnDeploying( void );
void CheckDeployFinish( void );
void FinishDeploying( void );
void FinishUnDeploying( void );
bool IsDeployed( void );
bool IsDeploying( void );
bool IsUnDeploying( void );
// Movement prevention
bool CantMove( void );
void SetCantMove( bool bCantMove );
bool HasNamedTechnology( const char *name );
void SetPreferredTechnology( CTechnologyTree *pTechnologyTree, int iTechIndex );
int GetPreferredTechnology( void );
tfplayertech_t &AvailableTech( int i ) { return m_rgClientTechAvail[i]; }
// Powerups
virtual void PowerupStart( int iPowerup, float flAmount, CBaseEntity *pAttacker, CDamageModifier *pDamageModifier );
virtual void PowerupEnd( int iPowerup );
virtual float PowerupDuration( int iPowerup, float flTime );
void SetRampage( bool bRampage );
float GetDefaultAnimSpeed( void );
// Knockdown
void KnockDownPlayer( const Vector& sourceDir, float velocity, float duration );
bool IsKnockedDown( void );
// Resources
void AddBankResources( int iAmount );
void RemoveBankResources( int iAmount, bool bSpent = true );
void DonateResources( CBaseTFPlayer *pTarget, int pCount );
int GetBankResources( void );
void SetBankResources( int iAmount );
// Check for a collision....
bool IsHittingShield( const Vector &vecVelocity, float *flDamage );
// Combat prototyping
bool IsBlocking( void ) const { return m_bIsBlocking; }
bool IsParrying( void ) const { return m_bIsParrying; }
void SetBlocking( bool bBlocking ) { m_bIsBlocking = bBlocking; }
void SetParrying( bool bParrying ) { m_bIsParrying = bParrying; }
// Thermal Vision
bool IsUsingThermalVision( void );
void SetUsingThermalVision( bool thermal );
CTFPlayerLocalData *GetLocalData() { return &m_TFLocal; }
// Acts
void CleanupOnActStart( void );
// Resource chunks
bool AddResourceChunks( int iChunks, bool bProcessed );
void RemoveResourceChunks( int iChunks, bool bProcessed );
int GetTotalResourceChunks( void );
int GetResourceChunkCount( bool bProcessed );
void SetGagged( bool gag );
// Control zone
CControlZone* GetCurrentZone( ) { return m_pCurrentZone; }
void SetCurrentZone( CControlZone* pZone ) { m_pCurrentZone = pZone; }
// Camouflage
float GetCamouflageAmount( void ) { return m_flCamouflageAmount; };
bool IsCamouflaged( void );
void SetCamouflaged( int percentage, float changerate );
void ClearCamouflage( void );
float LastAttackTime() const { return m_flLastAttackTime; }
void SetLastAttackTime( float flTime ) { m_flLastAttackTime = flTime; }
bool ResupplyAmmo( float flFraction, ResupplyReason_t reason );
// The last time we were damaged by an enemy.
double LastTimeDamagedByEnemy() const { return m_flLastTimeDamagedByEnemy; }
// Orders
COrder* GetOrder( void ) { return m_hSelectedOrder; }
void SetOrder( COrder *pOrder );
// Count resource zone orders.
int GetNumResourceZoneOrders();
// Reinforcement
bool IsReadyToReinforce( void );
void Reinforce( void );
void ShowTacticalView( bool bTactical );
void SetRespawnStation( CBaseEntity *pStation );
// ID
void SetIDEnt( CBaseEntity *pEntity );
// Health boosts
void TakeHealthBoost( int iHealthBoost, int iTarget, int iDuration );
// Vehicle
bool CanGetInVehicle( void );
CVehicleTeleportStation* GetSelectedMCV() const;
void SetSelectedMCV( CVehicleTeleportStation *pMCV );
// Weapon handling
virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon );
virtual bool Weapon_ShouldSelectItem( CBaseCombatWeapon *pWeapon );
virtual CBaseCombatWeapon *GetLastWeaponBeforeObject( void ) { return m_hLastWeaponBeforeObject; }
// Sapper attaching
bool IsAttachingSapper( void );
float GetSapperAttachmentTime( void );
void StartAttachingSapper( CBaseObject *pObject, CGrenadeObjectSapper *pSapper );
void CleanupAfterAttaching( void );
void StopAttaching( void );
void FinishAttaching( void );
void CheckSapperAttaching( void );
// IScorer
public:
// Return the entity that should receive the score
virtual CBasePlayer *GetScorer( void );
// Return the entity that should get assistance credit
virtual CBasePlayer *GetAssistant( void );
public:
// FIXME: Make these private
// Menu-related goodies
CMenu *m_pCurrentMenu;
char m_MenuStringBuffer[MENU_STRING_BUFFER_SIZE];
int m_MenuSelectionBuffer;
float m_MenuRefreshTime;
float m_MenuUpdateTime;
bool m_bBuffHealthBoost;
// Object sapper placement handling
float m_flSapperAttachmentFinishTime;
float m_flSapperAttachmentStartTime;
CHandle< CGrenadeObjectSapper > m_hSapper;
CHandle< CBaseObject > m_hSappedObject;
private:
// Medic Buffs
void CheckBuffs( void );
void RemoveHealthBoost( void );
// vehicles
void OnVehicleStart();
void OnVehicleEnd( Vector & );
bool IsInTacticalView( void ) const;
// Get rid of resource zone orders.
void KillResourceZoneOrders();
// Knockdowns
void ResetKnockdown( void );
void CheckKnockdown( void );
// Gagging
bool IsGagged( void );
void DropAllResourceChunks( void );
// Thinking
void CheckCamouflage( void );
// Rampage
bool IsInRampage( void );
// Vertification
inline bool HasClass( void ) { return GetPlayerClass() != NULL; }
// Respawn stations
CBaseEntity *GetInitialSpawnPoint( void );
// Go ragdoll, create shadow object, etc.
bool BecomeRagdollOnClient( const Vector &force );
// Remove ragdoll
bool ClearClientRagdoll( bool moveplayertofinalspot );
// Move origin in sync with shadow object if ragdolling
void FollowClientRagdoll( void );
bool CheckRagdollToStand( trace_t &trace );
bool IsClientRagdoll() const { return m_hRagdollShadow.Get() != 0; }
// Deployed?
bool IsDeployed() const { return m_bDeployed; }
void StoreCycle( void );
float RetrieveCycle( void );
bool ShouldMatchCycles( Activity newActivity, Activity currentActivity );
// TF Player Physics Shadow
void InitVCollision( void );
void ApplyDamageForce( const CTakeDamageInfo &info, int nDamageToDo );
// Movement.
Vector m_vecPosDelta;
enum { MOMENTUM_MAXSIZE = 10 };
float m_aMomentum[MOMENTUM_MAXSIZE];
int m_iMomentumHead;
// Spawn spot
CNetworkHandle( CBaseEntity, m_hSpawnPoint );
// This player's TF2 specific data that should only be replicated to
// the player and not to other players.
CNetworkVarEmbedded( CTFPlayerLocalData, m_TFLocal );
IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iMaxHealth ); // Make sure this ent is marked as changed when m_iMaxHealth changes.
CHandle< CWeaponBuilder > m_hWeaponBuilder;
CHandle< CWeaponCombatShield > m_hWeaponCombatShield;
float m_flKnockdownEndTime;
// Weapon used before switching to an object placement
CHandle<CBaseCombatWeapon> m_hLastWeaponBeforeObject;
CNetworkQAngle( m_vecDeployedAngles );
// Tracks when medics are boosting the damage this guy applies.
int m_nMedicDamageBoosts;
CNetworkVar( int, m_TFPlayerFlags ); // Combination of TF_PLAYER_ flags.
bool m_bCantMove;
bool m_bGagged;
bool m_bFirstTeamSpawn; // When true, the player's joined the server but not picked a team for the first time
float m_flLastAttackTime;
// Camouflage
CNetworkVar( float, m_flCamouflageAmount );
// Camouflage state machine
float m_flGoalCamouflageAmount;
float m_flGoalCamouflageChangeRate;
// State information
bool m_bSwitchingView;
// Zone the player's currently in
CControlZone *m_pCurrentZone;
CNetworkVar( int, m_iCurrentZoneState );
// Accuracy
bool m_bSnapAccuracy;
float m_flAccuracy;
float m_flTargetAccuracy;
float m_flLastRicochetNearby;
float m_flNumberOfRicochets;
float m_flLastExplosionNearby;
// Buff states
int m_iHealthBoostTarget;
float m_flHealthBoostDecrement;
float m_flHealthBoostTime;
EHANDLE m_hNextPlayerToUpdateOnRadar;
CNetworkHandle( CBaseEntity, m_hSelectedMCV );
// Orders
CHandle< COrder > m_hSelectedOrder;
// Tech spending vote preference
int m_nPreferredTechnology;
// The last time we were damaged by an enemy.
double m_flLastTimeDamagedByEnemy;
// Menu Handling
float m_MenuDisplayTime;
// Rampage
bool m_bRampage; // Do I get adrenalin extension for killing enemies?
// Handheld shield
CNetworkVar( bool, m_bIsBlocking );
bool m_bIsParrying;
float m_flTimeOfDeath;
EHANDLE m_hLastBoostEntity; // Last entity that gave me a power boost
// Deployment
CNetworkVar( bool, m_bDeployed );
CNetworkVar( bool, m_bDeploying );
CNetworkVar( bool, m_bUnDeploying );
float m_flFinishedDeploying;
CNetworkVar( int, m_iPlayerClass );
CAllPlayerClasses m_PlayerClasses;
// This times how long each class is active.
CFastTimer m_Timer;
tfplayertech_t m_rgClientTechAvail[ MAX_TECHNOLOGIES ];
CHandle< CRagdollShadow > m_hRagdollShadow;
Vector m_vecLastGoodRagdollPos;
// Last reinforcment second counter for player ( so we don't spam the player
// with text every frame )
int m_iLastSecondsToGo;
CPlayerAnimState m_PlayerAnimState;
// Fractional boost amount
float m_flFractionalBoost;
float m_flStoredCycle;
// Are we under attack?
CNetworkVar( bool, m_bUnderAttack );
friend void* SendProxy_RideVehicle( const void *pStruct, const void *pData, CSendProxyRecipients *pRecipients, int objectID );
friend class CTFPlayerMove;
};
inline CBaseTFPlayer *ToBaseTFPlayer( CBaseEntity *pEntity )
{
if ( !pEntity || !pEntity->IsPlayer() )
return NULL;
return dynamic_cast<CBaseTFPlayer *>( pEntity );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CPhysicsPlayerCallback : public IPhysicsPlayerControllerEvent
{
public:
int ShouldMoveTo( IPhysicsObject *pObject, const Vector &position )
{
CBaseTFPlayer *pPlayer = ( CBaseTFPlayer* )pObject->GetGameData();
if ( pPlayer->TouchedPhysics() )
{
return 0;
}
return 1;
}
};
extern CPhysicsPlayerCallback playerCallback;
#endif // TF_PLAYER_H