|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
#include "cbase.h"
#include "KeyValues.h"
#include "tf_playerclass_shared.h"
#include "materialsystem/imaterialsystemhardwareconfig.h"
#include "filesystem.h"
#include "tier2/tier2.h"
//=============================================================================
//
// Shared player class data.
//
//=============================================================================
//
// Tables.
//
#define CLASSMODEL_PARITY_BITS 3
#define CLASSMODEL_PARITY_MASK ((1<<CLASSMODEL_PARITY_BITS)-1)
// Client specific.
#ifdef CLIENT_DLL
BEGIN_RECV_TABLE_NOBASE( CTFPlayerClassShared, DT_TFPlayerClassShared ) RecvPropInt( RECVINFO( m_iClass ) ), RecvPropString( RECVINFO( m_iszClassIcon ) ), RecvPropString( RECVINFO( m_iszCustomModel ) ), RecvPropVector( RECVINFO( m_vecCustomModelOffset ) ), RecvPropQAngles( RECVINFO( m_angCustomModelRotation ) ), RecvPropBool( RECVINFO( m_bCustomModelRotates ) ), RecvPropBool( RECVINFO( m_bCustomModelRotationSet ) ), RecvPropBool( RECVINFO( m_bCustomModelVisibleToSelf ) ), RecvPropBool( RECVINFO( m_bUseClassAnimations ) ), RecvPropInt( RECVINFO(m_iClassModelParity) ), END_RECV_TABLE()
// Server specific.
#else
BEGIN_SEND_TABLE_NOBASE( CTFPlayerClassShared, DT_TFPlayerClassShared ) SendPropInt( SENDINFO( m_iClass ), Q_log2( TF_CLASS_COUNT_ALL )+1, SPROP_UNSIGNED ), SendPropStringT( SENDINFO( m_iszClassIcon ) ), SendPropStringT( SENDINFO( m_iszCustomModel ) ), SendPropVector( SENDINFO( m_vecCustomModelOffset ) ), SendPropQAngles( SENDINFO( m_angCustomModelRotation ) ), SendPropBool( SENDINFO( m_bCustomModelRotates ) ), SendPropBool( SENDINFO( m_bCustomModelRotationSet ) ), SendPropBool( SENDINFO( m_bCustomModelVisibleToSelf ) ), SendPropBool( SENDINFO( m_bUseClassAnimations ) ), SendPropInt( SENDINFO(m_iClassModelParity), CLASSMODEL_PARITY_BITS, SPROP_UNSIGNED ), END_SEND_TABLE()
#endif
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CTFPlayerClassShared::CTFPlayerClassShared() { Reset(); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFPlayerClassShared::Reset( void ) { m_iClass.Set( TF_CLASS_UNDEFINED ); #ifdef CLIENT_DLL
m_iszClassIcon[0] = '\0'; m_iszCustomModel[0] = '\0'; #else
m_iszClassIcon.Set( NULL_STRING ); m_iszCustomModel.Set( NULL_STRING ); #endif
m_vecCustomModelOffset = vec3_origin; m_angCustomModelRotation = vec3_angle; m_bCustomModelRotates = true; m_bCustomModelRotationSet = false; m_bCustomModelVisibleToSelf = true; m_bUseClassAnimations = false; m_iClassModelParity = 0; }
#ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFPlayerClassShared::SetCustomModel( const char *pszModelName, bool isUsingClassAnimations ) { if ( pszModelName && pszModelName[0] ) { bool bAllowPrecache = CBaseEntity::IsPrecacheAllowed(); CBaseEntity::SetAllowPrecache( true ); CBaseEntity::PrecacheModel( pszModelName ); CBaseEntity::SetAllowPrecache( bAllowPrecache );
m_iszCustomModel.Set( AllocPooledString( pszModelName ) );
m_bUseClassAnimations = isUsingClassAnimations; } else { m_iszCustomModel.Set( NULL_STRING ); m_vecCustomModelOffset = vec3_origin; m_angCustomModelRotation = vec3_angle; }
m_iClassModelParity = (m_iClassModelParity + 1) & CLASSMODEL_PARITY_MASK; } #endif // #ifndef CLIENT_DLL
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CTFPlayerClassShared::CustomModelHasChanged( void ) { if ( m_iClassModelParity != m_iOldClassModelParity ) { m_iOldClassModelParity = m_iClassModelParity.Get(); return true; } return false; }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
#ifdef STAGING_ONLY
ConVar tf_player_use_female_models( "tf_player_use_female_models", "0", FCVAR_CHEAT | FCVAR_REPLICATED, "For testing. Appends '_female' to the model filename loaded" ); #endif
const char *CTFPlayerClassShared::GetModelName( void ) const { // Does this play have an overridden model?
#ifdef CLIENT_DLL
if ( m_iszCustomModel[0] ) return m_iszCustomModel; #else
if ( m_iszCustomModel.Get() != NULL_STRING ) return ( STRING( m_iszCustomModel.Get() ) ); #endif
#define MAX_MODEL_FILENAME_LENGTH 256
static char modelFilename[ MAX_MODEL_FILENAME_LENGTH ];
Q_strncpy( modelFilename, GetPlayerClassData( m_iClass )->GetModelName(), sizeof( modelFilename ) ); #ifdef STAGING_ONLY
if ( tf_player_use_female_models.GetBool() ) { // find the ".mdl" part
char *ext; for( ext = modelFilename; *ext != '\000'; ++ext ) { if ( *ext == '.' ) { V_strncpy( ext, "_female.mdl", sizeof( modelFilename ) - ( ext - modelFilename ) ); break; } }
// make sure the test model is precached
bool bAllowPrecache = CBaseEntity::IsPrecacheAllowed(); CBaseEntity::SetAllowPrecache( true ); CBaseEntity::PrecacheModel( modelFilename ); CBaseEntity::SetAllowPrecache( bAllowPrecache ); } #endif
return modelFilename; }
//-----------------------------------------------------------------------------
// Purpose: Initialize the player class.
//-----------------------------------------------------------------------------
const char *g_HACK_GunslingerEngineerArmsOverride = "models\\weapons\\c_models\\c_engineer_gunslinger.mdl";
const char *CTFPlayerClassShared::GetHandModelName( int iHandIndex = 0 ) const { return iHandIndex == 0 ? GetPlayerClassData( m_iClass )->m_szHandModelName :g_HACK_GunslingerEngineerArmsOverride; // this is precached in the CTFRobotArm class
} //-----------------------------------------------------------------------------
// Purpose: Initialize the player class.
//-----------------------------------------------------------------------------
bool CTFPlayerClassShared::Init( int iClass ) { Assert ( ( iClass >= TF_FIRST_NORMAL_CLASS ) && ( iClass <= TF_LAST_NORMAL_CLASS ) );
Reset(); m_iClass = iClass;
#ifdef CLIENT_DLL
V_strncpy( m_iszCustomModel, g_aRawPlayerClassNamesShort[ m_iClass ], sizeof( m_iszCustomModel ) ); #else
m_iszClassIcon.Set( AllocPooledString( g_aRawPlayerClassNamesShort[ m_iClass ] ) ); #endif
return true; }
// If needed, put this into playerclass scripts
bool CTFPlayerClassShared::CanBuildObject( int iObjectType ) { bool bFound = false;
TFPlayerClassData_t *pData = GetData();
int i; for ( i=0;i<TF_PLAYER_BLUEPRINT_COUNT;i++ ) { if ( iObjectType == pData->m_aBuildable[i] ) { bFound = true; break; } }
return bFound; }
|