203 lines
6.8 KiB
C++
203 lines
6.8 KiB
C++
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Client's C_BaseCombatCharacter entity
|
|
//
|
|
// $Workfile: $
|
|
// $Date: $
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
// $Log: $
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
#include "cbase.h"
|
|
#include "c_basecombatcharacter.h"
|
|
#include "c_cs_player.h"
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
#if defined( CBaseCombatCharacter )
|
|
#undef CBaseCombatCharacter
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
C_BaseCombatCharacter::C_BaseCombatCharacter()
|
|
{
|
|
for ( int i=0; i < m_iAmmo.Count(); i++ )
|
|
m_iAmmo.Set( i, 0 );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
C_BaseCombatCharacter::~C_BaseCombatCharacter()
|
|
{
|
|
}
|
|
|
|
/*
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Returns the amount of ammunition of the specified type the character's carrying
|
|
//-----------------------------------------------------------------------------
|
|
int C_BaseCombatCharacter::GetAmmoCount( char *szName ) const
|
|
{
|
|
return GetAmmoCount( g_pGameRules->GetAmmoDef()->Index(szName) );
|
|
}
|
|
*/
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Overload our muzzle flash and send it to any actively held weapon
|
|
//-----------------------------------------------------------------------------
|
|
void C_BaseCombatCharacter::DoMuzzleFlash()
|
|
{
|
|
// Our weapon takes our muzzle flash command
|
|
C_BaseCombatWeapon *pWeapon = GetActiveWeapon();
|
|
if ( pWeapon )
|
|
{
|
|
pWeapon->DoMuzzleFlash();
|
|
//NOTENOTE: We do not chain to the base here
|
|
}
|
|
else
|
|
{
|
|
BaseClass::DoMuzzleFlash();
|
|
}
|
|
}
|
|
|
|
void C_BaseCombatCharacter::OnDataChanged( DataUpdateType_t updateType )
|
|
{
|
|
BaseClass::OnDataChanged( updateType );
|
|
|
|
// view weapon model cache monitoring
|
|
// NOTE: expected to be updated ONLY once per frame for the primary player ONLY!
|
|
// the expectation is that there is ONLY one customer that requires view models
|
|
// otherwise the lower level code will thrash as it tries to maintain a single player's view model inventory
|
|
{
|
|
const char *viewWeapons[MAX_WEAPONS];
|
|
int nNumViewWeapons = 0;
|
|
|
|
C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
|
if ( pLocalPlayer == this && !pLocalPlayer->IsObserver() )
|
|
{
|
|
// want to know what this player's weapon inventory is to keep all of these in cache
|
|
for ( int i = 0; i < MAX_WEAPONS; i++ )
|
|
{
|
|
C_BaseCombatWeapon *pWeapon = GetWeapon( i );
|
|
if ( !pWeapon )
|
|
continue;
|
|
|
|
viewWeapons[nNumViewWeapons] = pWeapon->GetViewModel();
|
|
nNumViewWeapons++;
|
|
}
|
|
}
|
|
else if ( pLocalPlayer && pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE && pLocalPlayer->GetObserverTarget() == this )
|
|
{
|
|
// once spectating, PURPOSELY only the active view weapon gets tracked
|
|
// cycling through spectators is the more common pattern and tracking just the active weapon prevents massive cache thrashing
|
|
// otherwise maintaining the observer targets inventories would needlessly thrash the cache as the player rapidly cycles
|
|
C_BaseCombatWeapon *pWeapon = pLocalPlayer->GetActiveWeapon();
|
|
if ( pWeapon )
|
|
{
|
|
viewWeapons[nNumViewWeapons] = pWeapon->GetViewModel();
|
|
nNumViewWeapons++;
|
|
}
|
|
}
|
|
|
|
if ( nNumViewWeapons )
|
|
{
|
|
// view model weapons are subject to a cache policy that needs to be kept accurate for a SINGLE Player
|
|
modelinfo->UpdateViewWeaponModelCache( viewWeapons, nNumViewWeapons );
|
|
}
|
|
}
|
|
|
|
// world weapon model cache monitoring
|
|
// world weapons have a much looser cache policy and just needs to monitor the important set of world weapons
|
|
{
|
|
const char *worldWeapons[MAX_WEAPONS];
|
|
int nNumWorldWeapons = 0;
|
|
|
|
// want to track any world models that are active weapons
|
|
// the world weapons lying on the ground are the ones that become LRU purge candidates
|
|
C_BasePlayer *pPlayer = ToBasePlayer( this );
|
|
if ( pPlayer )
|
|
{
|
|
C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();
|
|
if ( pWeapon )
|
|
{
|
|
worldWeapons[nNumWorldWeapons] = pWeapon->GetWorldModel();
|
|
nNumWorldWeapons++;
|
|
}
|
|
}
|
|
|
|
C_CSPlayer *pCSPlayer = C_CSPlayer::GetLocalCSPlayer();
|
|
if ( pCSPlayer == this )
|
|
{
|
|
int weaponEntIndex = pCSPlayer->GetTargetedWeapon();
|
|
if ( weaponEntIndex > 0 ) //0 is a valid entity index, but will never be used for a weapon
|
|
{
|
|
C_BaseEntity *pEnt = cl_entitylist->GetEnt( weaponEntIndex );
|
|
C_BaseCombatWeapon *pWeapon = dynamic_cast< C_BaseCombatWeapon * >( pEnt );
|
|
if ( pWeapon )
|
|
{
|
|
worldWeapons[nNumWorldWeapons] = pWeapon->GetWorldModel();
|
|
nNumWorldWeapons++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( nNumWorldWeapons )
|
|
{
|
|
modelinfo->TouchWorldWeaponModelCache( worldWeapons, nNumWorldWeapons );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool C_BaseCombatCharacter::HasEverBeenInjured( void ) const
|
|
{
|
|
return ( m_flTimeOfLastInjury != 0.0f );
|
|
}
|
|
|
|
float C_BaseCombatCharacter::GetTimeSinceLastInjury( void ) const
|
|
{
|
|
return gpGlobals->curtime - m_flTimeOfLastInjury;
|
|
}
|
|
|
|
IMPLEMENT_CLIENTCLASS(C_BaseCombatCharacter, DT_BaseCombatCharacter, CBaseCombatCharacter);
|
|
|
|
// Only send active weapon index to local player
|
|
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCLocalPlayerExclusive )
|
|
RecvPropTime( RECVINFO( m_flNextAttack ) ),
|
|
END_RECV_TABLE();
|
|
|
|
BEGIN_RECV_TABLE_NOBASE( C_BaseCombatCharacter, DT_BCCNonLocalPlayerExclusive )
|
|
#if defined( CSTRIKE15 )
|
|
// In CS:GO send active weapon index to all players except local
|
|
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
|
|
#endif
|
|
END_RECV_TABLE();
|
|
|
|
BEGIN_RECV_TABLE(C_BaseCombatCharacter, DT_BaseCombatCharacter)
|
|
RecvPropDataTable( "bcc_localdata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCLocalPlayerExclusive) ),
|
|
RecvPropDataTable( "bcc_nonlocaldata", 0, 0, &REFERENCE_RECV_TABLE(DT_BCCNonLocalPlayerExclusive) ),
|
|
RecvPropInt( RECVINFO( m_LastHitGroup ) ),
|
|
RecvPropEHandle( RECVINFO( m_hActiveWeapon ) ),
|
|
RecvPropTime( RECVINFO( m_flTimeOfLastInjury ) ),
|
|
RecvPropInt( RECVINFO( m_nRelativeDirectionOfLastInjury ) ),
|
|
RecvPropArray3( RECVINFO_ARRAY(m_hMyWeapons), RecvPropEHandle( RECVINFO( m_hMyWeapons[0] ) ) ),
|
|
|
|
#ifdef INVASION_CLIENT_DLL
|
|
RecvPropInt( RECVINFO( m_iPowerups ) ),
|
|
#endif
|
|
|
|
END_RECV_TABLE()
|
|
|
|
|
|
BEGIN_PREDICTION_DATA( C_BaseCombatCharacter )
|
|
|
|
DEFINE_PRED_ARRAY( m_iAmmo, FIELD_INTEGER, MAX_AMMO_TYPES, FTYPEDESC_INSENDTABLE ),
|
|
DEFINE_PRED_FIELD( m_flNextAttack, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
|
|
DEFINE_PRED_FIELD( m_hActiveWeapon, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
|
|
DEFINE_PRED_ARRAY( m_hMyWeapons, FIELD_EHANDLE, MAX_WEAPONS, FTYPEDESC_INSENDTABLE ),
|
|
|
|
END_PREDICTION_DATA()
|