summaryrefslogtreecommitdiff
path: root/game/shared/tf/tf_playerclass_shared.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/shared/tf/tf_playerclass_shared.cpp')
-rw-r--r--game/shared/tf/tf_playerclass_shared.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/game/shared/tf/tf_playerclass_shared.cpp b/game/shared/tf/tf_playerclass_shared.cpp
new file mode 100644
index 0000000..4365a20
--- /dev/null
+++ b/game/shared/tf/tf_playerclass_shared.cpp
@@ -0,0 +1,228 @@
+//========= 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;
+}