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.
228 lines
7.0 KiB
228 lines
7.0 KiB
//========= 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; |
|
}
|
|
|