Counter Strike : Global Offensive Source Code
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.

779 lines
28 KiB

  1. //========= Copyright (c), Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "cstrike15_item_schema.h"
  9. #include "game_item_schema.h"
  10. #include "schemainitutils.h"
  11. #include "shareddefs.h"
  12. #include "cs_shareddefs.h"
  13. #include "mathlib/lightdesc.h"
  14. #ifndef GC_DLL
  15. #include "econ_item_system.h"
  16. #endif // !GC_DLL
  17. const char CCStrike15ItemSchema::k_rchCommunitySupportPassItemDefName[] = "Community Season One Spring 2013";
  18. //--------------------------------------------------------------------------------------------------
  19. // Purpose: Constructor.
  20. //--------------------------------------------------------------------------------------------------
  21. CCStrike15ItemDefinition::CCStrike15ItemDefinition()
  22. {
  23. m_bIsSupplyCrate = false;
  24. }
  25. //-----------------------------------------------------------------------------
  26. // Purpose:
  27. //-----------------------------------------------------------------------------
  28. bool CCStrike15ItemDefinition::BInitFromKV( KeyValues *pKVItem, CEconItemSchema &schemaa, CUtlVector<CUtlString> *pVecErrors )
  29. {
  30. CEconItemDefinition::BInitFromKV( pKVItem, schemaa, pVecErrors );
  31. CCStrike15ItemSchema *pSchema = ItemSystem()->GetItemSchema();
  32. // Get the default loadout slot
  33. const char *pchSubPosition = GetRawDefinition()->GetString( "item_sub_position", NULL );
  34. m_iDefaultLoadoutSlot = ( pchSubPosition ? StringFieldToInt( pchSubPosition, pSchema->GetLoadoutStringsSubPositions() ) : -1 );
  35. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  36. {
  37. m_iLoadoutSlots[i] = LOADOUT_POSITION_INVALID;
  38. }
  39. if ( m_iDefaultLoadoutSlot == LOADOUT_POSITION_CLOTHING_HANDS && !IsBaseItem() )
  40. {
  41. SCHEMA_INIT_CHECK( GetWorldDisplayModel(), CFmtStr( "Glove model %s (def idx %d) is missing world model key.", GetDefinitionName(), GetDefinitionIndex() ) );
  42. }
  43. // record if this item shares a loadout position with another type of item (m4, cz/p250)
  44. m_bItemSharesEquipSlot = GetRawDefinition()->GetBool( "item_shares_equip_slot" );
  45. const char *pchItemClass = GetItemClass();
  46. SCHEMA_INIT_CHECK( pchItemClass, CFmtStr( "Item \"%s\" is missing schema item class!", pKVItem->GetName() ) );
  47. m_bIsSupplyCrate = ( pchItemClass && !V_strcmp( pchItemClass, "supply_crate" ) );
  48. // Class usability--use our copy of kv item
  49. KeyValues *pClasses = GetRawDefinition()->FindKey( "used_by_classes" );
  50. if ( pClasses )
  51. {
  52. m_vbClassUsability.ClearAll();
  53. KeyValues *pKVClass = pClasses->GetFirstSubKey();
  54. while ( pKVClass )
  55. {
  56. int iTeam = StringFieldToInt( pKVClass->GetName(), pSchema->GetClassUsabilityStrings() );
  57. if ( iTeam > -1 )
  58. {
  59. m_vbClassUsability.Set(iTeam);
  60. m_iLoadoutSlots[iTeam] = m_iDefaultLoadoutSlot;
  61. // If the value is "1", the class uses this item in the default loadout slot.
  62. const char *pszValue = pKVClass->GetString();
  63. if ( pszValue[0] != '1' )
  64. {
  65. int iSlot = StringFieldToInt( pszValue, pSchema->GetLoadoutStrings() );
  66. Assert( iSlot != -1 );
  67. if ( iSlot != -1 )
  68. {
  69. m_iLoadoutSlots[iTeam] = iSlot;
  70. }
  71. }
  72. }
  73. pKVClass = pKVClass->GetNextKey();
  74. }
  75. // add "all_class" if applicable
  76. if ( CanBeUsedByAllTeams() )
  77. {
  78. KeyValues *pKVAllClassKey = new KeyValues( "all_class", "all_class", "1" );
  79. pClasses->AddSubKey( pKVAllClassKey );
  80. }
  81. }
  82. // Verify that no items are set up to be equipped in a wearable slot for some classes and a
  83. // non-wearable slot other times. "Is this in a wearable slot?" is used to determine whether
  84. // or not content can be allowed to stream, so we don't allow an item to overlap.
  85. bool bHasAnyWearableSlots = false,
  86. bHasAnyNonwearableSlots = false;
  87. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  88. {
  89. if ( m_iLoadoutSlots[i] != LOADOUT_POSITION_INVALID )
  90. {
  91. const bool bThisIsWearableSlot = IsWearableSlot( m_iLoadoutSlots[i] );
  92. (bThisIsWearableSlot ? bHasAnyWearableSlots : bHasAnyNonwearableSlots) = true;
  93. }
  94. }
  95. SCHEMA_INIT_CHECK(
  96. !(bHasAnyWearableSlots && bHasAnyNonwearableSlots),
  97. CFmtStr( "Item definition %i \"%s\" used in both wearable and not wearable slots!", GetDefinitionIndex(), GetItemBaseName() ) );
  98. // "anim_slot"
  99. m_iAnimationSlot = -1;
  100. const char *pszAnimSlot = GetRawDefinition()->GetString("anim_slot");
  101. if ( pszAnimSlot && pszAnimSlot[0] )
  102. {
  103. if ( Q_stricmp(pszAnimSlot, "FORCE_NOT_USED") == 0 )
  104. {
  105. m_iAnimationSlot = -2;
  106. }
  107. else
  108. {
  109. m_iAnimationSlot = StringFieldToInt( pszAnimSlot, pSchema->GetWeaponTypeSubstrings() );
  110. }
  111. }
  112. // Initialize player display model.
  113. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  114. {
  115. m_pszPlayerDisplayModel[i] = NULL;
  116. }
  117. // "model_player_per_class"
  118. KeyValues *pPerClassModels = GetRawDefinition()->FindKey( "model_player_per_class" );
  119. for ( int i = 1; i < LOADOUT_COUNT; i++ )
  120. {
  121. if ( pPerClassModels )
  122. {
  123. m_pszPlayerDisplayModel[i] = pPerClassModels->GetString( pSchema->GetClassUsabilityStrings()[i], NULL );
  124. if ( m_pszPlayerDisplayModel[0] == NULL )
  125. {
  126. m_pszPlayerDisplayModel[0] = m_pszPlayerDisplayModel[i];
  127. }
  128. }
  129. }
  130. // Stomp duplicate properties.
  131. if ( !m_pszPlayerDisplayModel[0] )
  132. {
  133. m_pszPlayerDisplayModel[0] = GetBasePlayerDisplayModel();
  134. }
  135. // parse Paint Data
  136. KeyValues *pPaintData = GetRawDefinition()->FindKey( "paint_data" );
  137. if ( pPaintData )
  138. {
  139. KeyValues *pPaintableMaterialKeys = pPaintData->GetFirstSubKey();
  140. while ( pPaintableMaterialKeys )
  141. {
  142. const char *pName = pPaintableMaterialKeys->GetString( "Name" );
  143. if ( pName[0] != 0 )
  144. {
  145. WeaponPaintableMaterial_t *pPaintableMaterial = &m_PaintData[ m_PaintData.AddToTail() ];
  146. V_strncpy( pPaintableMaterial->m_szName, pName, sizeof( pPaintableMaterial->m_szName ) );
  147. const char *pOriginalMaterialName = pPaintableMaterialKeys->GetString( "OrigMat", "" );
  148. V_strncpy( pPaintableMaterial->m_szOriginalMaterialName, pOriginalMaterialName, sizeof( pPaintableMaterial->m_szOriginalMaterialName ) );
  149. const char *pFolderName = pPaintableMaterialKeys->GetString( "FolderName", pPaintableMaterial->m_szName ); // defaults to same as the name
  150. V_strncpy( pPaintableMaterial->m_szFolderName, pFolderName, sizeof( pPaintableMaterial->m_szFolderName ) );
  151. pPaintableMaterial->m_nViewModelSize = pPaintableMaterialKeys->GetInt( "ViewmodelDim", 1024 );
  152. pPaintableMaterial->m_nWorldModelSize = pPaintableMaterialKeys->GetInt( "WorldDim", 512 );
  153. pPaintableMaterial->m_flWeaponLength = pPaintableMaterialKeys->GetFloat( "WeaponLength", 36.0f );
  154. pPaintableMaterial->m_flUVScale = pPaintableMaterialKeys->GetFloat( "UVScale", 1.0f );
  155. pPaintableMaterial->m_bBaseTextureOverride = pPaintableMaterialKeys->GetBool( "BaseTextureOverride" );
  156. pPaintableMaterial->m_bMirrorPattern = pPaintableMaterialKeys->GetBool( "MirrorPattern", false );
  157. }
  158. else
  159. {
  160. DevMsg( "Error Parsing PaintData in %s! \n", GetDefinitionName() );
  161. }
  162. pPaintableMaterialKeys = pPaintableMaterialKeys->GetNextKey();
  163. }
  164. }
  165. // parse inventory image data
  166. KeyValues *pInventoryImageData = GetRawDefinition()->FindKey( "inventory_image_data" );
  167. if ( pInventoryImageData )
  168. {
  169. m_pInventoryImageData = new InventoryImageData_t;
  170. m_pInventoryImageData->m_pCameraAngles = NULL;
  171. m_pInventoryImageData->m_pCameraOffset = NULL;
  172. m_pInventoryImageData->m_cameraFOV = -1.0f;
  173. for ( int i = 0; i < MATERIAL_MAX_LIGHT_COUNT; i++ )
  174. {
  175. m_pInventoryImageData->m_pLightDesc[ i ] = NULL;
  176. }
  177. m_pInventoryImageData->m_bOverrideDefaultLight = pInventoryImageData->GetBool( "override_default_light", false );
  178. const char *pCameraAngles = pInventoryImageData->GetString( "camera_angles" );
  179. if ( pCameraAngles[0] != 0 )
  180. {
  181. float flX = 0.0f, flY = 0.0f, flZ = 0.0f;
  182. sscanf( pCameraAngles, "%f %f %f", &flX, &flY, &flZ );
  183. m_pInventoryImageData->m_pCameraAngles = new QAngle( flX, flY, flZ );
  184. }
  185. const char *pCameraOffset = pInventoryImageData->GetString( "camera_offset" );
  186. if ( pCameraOffset[0] != 0 )
  187. {
  188. float flX = 0.0f, flY = 0.0f, flZ = 0.0f;
  189. sscanf( pCameraOffset, "%f %f %f", &flX, &flY, &flZ );
  190. m_pInventoryImageData->m_pCameraOffset = new Vector( flX, flY, flZ );
  191. }
  192. m_pInventoryImageData->m_cameraFOV = pInventoryImageData->GetFloat( "camera_fov", -1.0f );
  193. int nNumLightDescs = 0;
  194. KeyValues *pLightKeys = pInventoryImageData->GetFirstTrueSubKey();
  195. while ( pLightKeys )
  196. {
  197. if ( nNumLightDescs >= ( MATERIAL_MAX_LIGHT_COUNT - ( ( m_pInventoryImageData->m_bOverrideDefaultLight ) ? 0 : 1 ) ) )
  198. {
  199. DevMsg( "Too many lights defined in inventory_image_data in %s. Only using first %d. \n", GetDefinitionName(), MATERIAL_MAX_LIGHT_COUNT );
  200. break;
  201. }
  202. const char *pLightType = pLightKeys->GetName();
  203. if ( pLightType[0] != 0 )
  204. {
  205. LightType_t lightType = MATERIAL_LIGHT_DISABLE;
  206. if ( V_strnicmp( pLightType, "point_light", 11 ) == 0 )
  207. {
  208. lightType = MATERIAL_LIGHT_POINT;
  209. }
  210. else if ( V_strnicmp( pLightType, "directional_light", 17 ) == 0 )
  211. {
  212. lightType = MATERIAL_LIGHT_DIRECTIONAL;
  213. }
  214. else if ( V_strnicmp( pLightType, "spot_light", 10 ) == 0 )
  215. {
  216. lightType = MATERIAL_LIGHT_SPOT;
  217. }
  218. else
  219. {
  220. DevMsg( "Error Parsing inventory_image_data in %s! Unknown light type %s. \n", GetDefinitionName(), pLightType );
  221. }
  222. if ( lightType != MATERIAL_LIGHT_DISABLE )
  223. {
  224. Vector lightPosOrDir( 0, 0, 0 );
  225. Vector lightColor( 0, 0, 0 );
  226. const char *pLightPosOrDir = pLightKeys->GetString( ( lightType == MATERIAL_LIGHT_DIRECTIONAL ) ? "direction" : "position" );
  227. if ( pLightPosOrDir[0] != 0 )
  228. {
  229. sscanf( pLightPosOrDir, "%f %f %f", &(lightPosOrDir.x), &(lightPosOrDir.y), &(lightPosOrDir.z) );
  230. }
  231. const char *pLightColor = pLightKeys->GetString( "color" );
  232. if ( pLightColor[0] != 0 )
  233. {
  234. sscanf( pLightColor, "%f %f %f", &(lightColor.x), &(lightColor.y), &(lightColor.z) );
  235. }
  236. Vector lightLookAt( 0, 0, 0 );
  237. float lightInnerCone = 1.0f;
  238. float lightOuterCone = 10.0f;
  239. if ( lightType == MATERIAL_LIGHT_SPOT )
  240. {
  241. const char *pLightLookAt = pLightKeys->GetString( "lookat" );
  242. if ( pLightLookAt[0] != 0 )
  243. {
  244. sscanf( pLightLookAt, "%f %f %f", &(lightLookAt.x), &(lightLookAt.y), &(lightLookAt.z) );
  245. }
  246. lightInnerCone = pLightKeys->GetFloat( "inner_cone", 1.0f );
  247. lightOuterCone = pLightKeys->GetFloat( "outer_cone", 8.0f );
  248. }
  249. m_pInventoryImageData->m_pLightDesc[ nNumLightDescs ] = new LightDesc_t;
  250. switch ( lightType )
  251. {
  252. case MATERIAL_LIGHT_DIRECTIONAL:
  253. m_pInventoryImageData->m_pLightDesc[ nNumLightDescs ]->InitDirectional( lightPosOrDir, lightColor );
  254. break;
  255. case MATERIAL_LIGHT_POINT:
  256. m_pInventoryImageData->m_pLightDesc[ nNumLightDescs ]->InitPoint( lightPosOrDir, lightColor );
  257. break;
  258. case MATERIAL_LIGHT_SPOT:
  259. m_pInventoryImageData->m_pLightDesc[ nNumLightDescs ]->InitSpot( lightPosOrDir, lightColor, lightLookAt, lightInnerCone, lightOuterCone );
  260. break;
  261. }
  262. nNumLightDescs++;
  263. }
  264. }
  265. pLightKeys = pLightKeys->GetNextTrueSubKey();
  266. }
  267. }
  268. return SCHEMA_INIT_SUCCESS();
  269. }
  270. #ifndef GC_DLL
  271. //-----------------------------------------------------------------------------
  272. // Purpose:
  273. //-----------------------------------------------------------------------------
  274. bool CCStrike15ItemDefinition::BInitFromTestItemKVs( int iNewDefIndex, KeyValues *pKVItem, CEconItemSchema &schemaa )
  275. {
  276. if ( !CEconItemDefinition::BInitFromTestItemKVs( iNewDefIndex, pKVItem, schemaa ) )
  277. return false;
  278. // Use the tester's class usage choices, even when testing existing items
  279. m_vbClassUsability.ClearAll();
  280. int iTeamUsage = pKVItem->GetInt( "class_usage", 0 );
  281. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  282. {
  283. if ( iTeamUsage & (1 << i) || (iTeamUsage & 1) )
  284. {
  285. m_vbClassUsability.Set(i);
  286. m_iLoadoutSlots[i] = m_iDefaultLoadoutSlot;
  287. }
  288. }
  289. // Stomp duplicate properties.
  290. m_pszPlayerDisplayModel[0] = GetBasePlayerDisplayModel();
  291. return true;
  292. }
  293. #endif // !GC_DLL
  294. //-----------------------------------------------------------------------------
  295. // Purpose:
  296. //-----------------------------------------------------------------------------
  297. void CCStrike15ItemDefinition::CopyPolymorphic( const CEconItemDefinition *pSourceDef )
  298. {
  299. Assert( dynamic_cast<const CCStrike15ItemDefinition *>( pSourceDef ) != NULL );
  300. *this = *(const CCStrike15ItemDefinition *)pSourceDef;
  301. }
  302. #ifndef GC_DLL
  303. //-----------------------------------------------------------------------------
  304. // Purpose:
  305. //-----------------------------------------------------------------------------
  306. void CCStrike15ItemDefinition::GeneratePrecacheModelStrings( bool bDynamicLoad, CUtlVector<const char *> *out_pVecModelStrings )
  307. {
  308. Assert( out_pVecModelStrings );
  309. // Is this definition supposed to use dynamic-loaded content or precache it?
  310. if ( !bDynamicLoad || !IsContentStreamable() )
  311. {
  312. // Parent class base meshes, if relevant.
  313. CEconItemDefinition::GeneratePrecacheModelStrings( bDynamicLoad, out_pVecModelStrings );
  314. // Per-class models.
  315. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  316. {
  317. const char *pszModel = GetPlayerDisplayModel(i);
  318. if ( pszModel && pszModel[0] )
  319. {
  320. out_pVecModelStrings->AddToTail( pszModel );
  321. }
  322. }
  323. const char *pszModel = GetWorldDisplayModel();
  324. if ( pszModel && pszModel[0] )
  325. {
  326. out_pVecModelStrings->AddToTail( pszModel );
  327. }
  328. }
  329. }
  330. #endif // !GC_DLL
  331. //-----------------------------------------------------------------------------
  332. // Purpose: Return the load-out slot that this item must be placed into
  333. //-----------------------------------------------------------------------------
  334. int CCStrike15ItemDefinition::GetLoadoutSlot( int iTeam ) const
  335. {
  336. if ( iTeam <= 0 || iTeam >= LOADOUT_COUNT )
  337. return m_iDefaultLoadoutSlot;
  338. return m_iLoadoutSlots[iTeam];
  339. }
  340. #ifndef GC_DLL
  341. //-----------------------------------------------------------------------------
  342. // Purpose: Returns true if this item is in a wearable slot, or is acting as a wearable
  343. //-----------------------------------------------------------------------------
  344. bool CCStrike15ItemDefinition::IsAWearable( int iSlot ) const
  345. {
  346. if ( IsWearableSlot( iSlot ) )
  347. return true;
  348. if ( IsActingAsAWearable() )
  349. return true;
  350. return false;
  351. }
  352. //-----------------------------------------------------------------------------
  353. // Purpose: Returns true if the content for this item view should be streamed. If false,
  354. // it should be preloaded.
  355. //-----------------------------------------------------------------------------
  356. #define ITEM_ENABLE_ITEM_CONTENT_STREAMING true
  357. //ConVar item_enable_content_streaming( "item_enable_content_streaming", "1", FCVAR_ARCHIVE | FCVAR_DEVELOPMENTONLY );
  358. bool CCStrike15ItemDefinition::IsContentStreamable() const
  359. {
  360. if ( !IsAWearable( GetDefaultLoadoutSlot() ) )
  361. return false;
  362. return ITEM_ENABLE_ITEM_CONTENT_STREAMING
  363. && CEconItemDefinition::IsContentStreamable();
  364. }
  365. #endif // !GC_DLL
  366. //-----------------------------------------------------------------------------
  367. // Purpose:
  368. //-----------------------------------------------------------------------------
  369. void CCStrike15ItemDefinition::FilloutSlotUsage( CBitVec<LOADOUT_COUNT> *pBV ) const
  370. {
  371. pBV->ClearAll();
  372. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  373. {
  374. if ( m_iLoadoutSlots[i] == LOADOUT_POSITION_INVALID )
  375. continue;
  376. pBV->Set( m_iLoadoutSlots[i] );
  377. }
  378. }
  379. //-----------------------------------------------------------------------------
  380. // Purpose:
  381. //-----------------------------------------------------------------------------
  382. int CCStrike15ItemDefinition::GetUsedByTeam( void ) const
  383. {
  384. if ( CanBeUsedByTeam(TEAM_TERRORIST) && CanBeUsedByTeam(TEAM_CT) )
  385. return TEAM_UNASSIGNED;
  386. if ( CanBeUsedByTeam(TEAM_TERRORIST) )
  387. return TEAM_TERRORIST;
  388. if ( CanBeUsedByTeam(TEAM_CT) )
  389. return TEAM_CT;
  390. return TEAM_UNASSIGNED;
  391. }
  392. //-----------------------------------------------------------------------------
  393. // Purpose:
  394. //-----------------------------------------------------------------------------
  395. bool CCStrike15ItemDefinition::CanBeUsedByAllTeams( void ) const
  396. {
  397. for ( int iTeam = 1; iTeam < (LOADOUT_COUNT-1); iTeam++ )
  398. {
  399. if ( !CanBeUsedByTeam(iTeam) )
  400. return false;
  401. }
  402. return true;
  403. }
  404. //-----------------------------------------------------------------------------
  405. // Purpose:
  406. //-----------------------------------------------------------------------------
  407. bool CCStrike15ItemDefinition::CanBePlacedInSlot( int nSlot ) const
  408. {
  409. for ( int i = 0; i < LOADOUT_COUNT; i++ )
  410. {
  411. if ( m_iLoadoutSlots[i] == nSlot )
  412. return true;
  413. }
  414. return false;
  415. }
  416. //-----------------------------------------------------------------------------
  417. // Purpose:
  418. //-----------------------------------------------------------------------------
  419. // Used to convert strings to ints for class usability
  420. const char *g_ClassUsabilityStrings[] =
  421. {
  422. "noteam",
  423. "undefined",
  424. "terrorists", // TEAM_TERRORIST
  425. "counter-terrorists", // TEAM_CT
  426. };
  427. // Loadout positions
  428. const char *g_szLoadoutStrings[] =
  429. {
  430. // Weapons & Equipment
  431. "melee", // LOADOUT_POSITION_MELEE = 0,
  432. "c4", // LOADOUT_POSITION_C4,
  433. "secondary", // LOADOUT_POSITION_SECONDARY0,
  434. "secondary", // LOADOUT_POSITION_SECONDARY1,
  435. "secondary", // LOADOUT_POSITION_SECONDARY2,
  436. "secondary", // LOADOUT_POSITION_SECONDARY3,
  437. "secondary", // LOADOUT_POSITION_SECONDARY4,
  438. "secondary", // LOADOUT_POSITION_SECONDARY5,
  439. "smg", // LOADOUT_POSITION_SMG0,
  440. "smg", // LOADOUT_POSITION_SMG1,
  441. "smg", // LOADOUT_POSITION_SMG2,
  442. "smg", // LOADOUT_POSITION_SMG3,
  443. "smg", // LOADOUT_POSITION_SMG4,
  444. "smg", // LOADOUT_POSITION_SMG5,
  445. "rifle", // LOADOUT_POSITION_RIFLE0,
  446. "rifle", // LOADOUT_POSITION_RIFLE1,
  447. "rifle", // LOADOUT_POSITION_RIFLE2,
  448. "rifle", // LOADOUT_POSITION_RIFLE3,
  449. "rifle", // LOADOUT_POSITION_RIFLE4,
  450. "rifle", // LOADOUT_POSITION_RIFLE5,
  451. "heavy", // LOADOUT_POSITION_HEAVY0,
  452. "heavy", // LOADOUT_POSITION_HEAVY1,
  453. "heavy", // LOADOUT_POSITION_HEAVY2,
  454. "heavy", // LOADOUT_POSITION_HEAVY3,
  455. "heavy", // LOADOUT_POSITION_HEAVY4,
  456. "heavy", // LOADOUT_POSITION_HEAVY5,
  457. "grenade", // LOADOUT_POSITION_GRENADE0,
  458. "grenade", // LOADOUT_POSITION_GRENADE1,
  459. "grenade", // LOADOUT_POSITION_GRENADE2,
  460. "grenade", // LOADOUT_POSITION_GRENADE3,
  461. "grenade", // LOADOUT_POSITION_GRENADE4,
  462. "grenade", // LOADOUT_POSITION_GRENADE5,
  463. "equipment", // LOADOUT_POSITION_EQUIPMENT0,
  464. "equipment", // LOADOUT_POSITION_EQUIPMENT1,
  465. "equipment", // LOADOUT_POSITION_EQUIPMENT2,
  466. "equipment", // LOADOUT_POSITION_EQUIPMENT3,
  467. "equipment", // LOADOUT_POSITION_EQUIPMENT4,
  468. "equipment", // LOADOUT_POSITION_EQUIPMENT5,
  469. "clothing", // LOADOUT_POSITION_CLOTHING_APPEARANCE,
  470. "clothing", // LOADOUT_POSITION_CLOTHING_TORSO,
  471. "clothing", // LOADOUT_POSITION_CLOTHING_LOWERBODY,
  472. "clothing", // LOADOUT_POSITION_CLOTHING_HANDS,
  473. "clothing", // LOADOUT_POSITION_CLOTHING_HAT,
  474. "clothing", // LOADOUT_POSITION_CLOTHING_FACEMASK,
  475. "clothing", // LOADOUT_POSITION_CLOTHING_EYEWEAR,
  476. "clothing", // LOADOUT_POSITION_CLOTHING_CUSTOMHEAD,
  477. "clothing", // LOADOUT_POSITION_CLOTHING_CUSTOMPLAYER,
  478. "misc", // LOADOUT_POSITION_MISC0,
  479. "misc", // LOADOUT_POSITION_MISC1,
  480. "misc", // LOADOUT_POSITION_MISC2,
  481. "misc", // LOADOUT_POSITION_MISC3,
  482. "misc", // LOADOUT_POSITION_MISC4,
  483. "misc", // LOADOUT_POSITION_MISC5,
  484. "misc", // LOADOUT_POSITION_MISC6,
  485. "musickit", // LOADOUT_POSITION_MUSICKIT,
  486. "flair0", // LOADOUT_POSITION_FLAIR0,
  487. "spray", // LOADOUT_POSITION_SPRAY0,
  488. };
  489. // Loadout positions
  490. const char *g_szLoadoutStringsSubPositions[] =
  491. {
  492. // Weapons & Equipment
  493. "melee", // LOADOUT_POSITION_MELEE = 0,
  494. "c4", // LOADOUT_POSITION_C4,
  495. "secondary0", // LOADOUT_POSITION_SECONDARY0,
  496. "secondary1", // LOADOUT_POSITION_SECONDARY1,
  497. "secondary2", // LOADOUT_POSITION_SECONDARY2,
  498. "secondary3", // LOADOUT_POSITION_SECONDARY3,
  499. "secondary4", // LOADOUT_POSITION_SECONDARY4,
  500. "secondary5", // LOADOUT_POSITION_SECONDARY5,
  501. "smg0", // LOADOUT_POSITION_SMG0,
  502. "smg1", // LOADOUT_POSITION_SMG1,
  503. "smg2", // LOADOUT_POSITION_SMG2,
  504. "smg3", // LOADOUT_POSITION_SMG3,
  505. "smg4", // LOADOUT_POSITION_SMG4,
  506. "smg5", // LOADOUT_POSITION_SMG5,
  507. "rifle0", // LOADOUT_POSITION_RIFLE0,
  508. "rifle1", // LOADOUT_POSITION_RIFLE1,
  509. "rifle2", // LOADOUT_POSITION_RIFLE2,
  510. "rifle3", // LOADOUT_POSITION_RIFLE3,
  511. "rifle4", // LOADOUT_POSITION_RIFLE4,
  512. "rifle5", // LOADOUT_POSITION_RIFLE5,
  513. "heavy0", // LOADOUT_POSITION_HEAVY0,
  514. "heavy1", // LOADOUT_POSITION_HEAVY1,
  515. "heavy2", // LOADOUT_POSITION_HEAVY2,
  516. "heavy3", // LOADOUT_POSITION_HEAVY3,
  517. "heavy4", // LOADOUT_POSITION_HEAVY4,
  518. "heavy5", // LOADOUT_POSITION_HEAVY5,
  519. "grenade0", // LOADOUT_POSITION_GRENADE0,
  520. "grenade1", // LOADOUT_POSITION_GRENADE1,
  521. "grenade2", // LOADOUT_POSITION_GRENADE2,
  522. "grenade3", // LOADOUT_POSITION_GRENADE3,
  523. "grenade4", // LOADOUT_POSITION_GRENADE4,
  524. "grenade5", // LOADOUT_POSITION_GRENADE5,
  525. "equipment0", // LOADOUT_POSITION_EQUIPMENT0,
  526. "equipment1", // LOADOUT_POSITION_EQUIPMENT1,
  527. "equipment2", // LOADOUT_POSITION_EQUIPMENT2,
  528. "equipment3", // LOADOUT_POSITION_EQUIPMENT3,
  529. "equipment4", // LOADOUT_POSITION_EQUIPMENT4,
  530. "equipment5", // LOADOUT_POSITION_EQUIPMENT5,
  531. "clothing0", // LOADOUT_POSITION_CLOTHING_APPEARANCE,
  532. "clothing1", // LOADOUT_POSITION_CLOTHING_TORSO,
  533. "clothing2", // LOADOUT_POSITION_CLOTHING_LOWERBODY,
  534. "clothing_hands", // LOADOUT_POSITION_CLOTHING_HANDS,
  535. "clothing4", // LOADOUT_POSITION_CLOTHING_HAT,
  536. "clothing5", // LOADOUT_POSITION_CLOTHING_FACEMASK,
  537. "clothing6", // LOADOUT_POSITION_CLOTHING_EYEWEAR,
  538. "clothing7", // LOADOUT_POSITION_CLOTHING_CUSTOMHEAD,
  539. "clothing8", // LOADOUT_POSITION_CLOTHING_CUSTOMPLAYER,
  540. "misc0", // LOADOUT_POSITION_MISC0,
  541. "misc1", // LOADOUT_POSITION_MISC1,
  542. "misc2", // LOADOUT_POSITION_MISC2,
  543. "misc3", // LOADOUT_POSITION_MISC3,
  544. "misc4", // LOADOUT_POSITION_MISC4,
  545. "misc5", // LOADOUT_POSITION_MISC5,
  546. "misc6", // LOADOUT_POSITION_MISC6,
  547. "musickit", // LOADOUT_POSITION_MUSICKIT,
  548. "flair0", // LOADOUT_POSITION_FLAIR0,
  549. "spray0", // LOADOUT_POSITION_SPRAY0,
  550. };
  551. // Loadout positions used to display loadout slots to players (localized)
  552. const char *g_szLoadoutStringsForDisplay[] =
  553. {
  554. "#LoadoutSlot_Melee", // LOADOUT_POSITION_MELEE = 0,
  555. "#LoadoutSlot_C4", // LOADOUT_POSITION_C4,
  556. "#LoadoutSlot_Secondary", // LOADOUT_POSITION_SECONDARY0,
  557. "#LoadoutSlot_Secondary", // LOADOUT_POSITION_SECONDARY1,
  558. "#LoadoutSlot_Secondary", // LOADOUT_POSITION_SECONDARY2,
  559. "#LoadoutSlot_Secondary", // LOADOUT_POSITION_SECONDARY3,
  560. "#LoadoutSlot_Secondary", // LOADOUT_POSITION_SECONDARY4,
  561. "#LoadoutSlot_Secondary", // LOADOUT_POSITION_SECONDARY5,
  562. "#LoadoutSlot_SMG", // LOADOUT_POSITION_SMG0,
  563. "#LoadoutSlot_SMG", // LOADOUT_POSITION_SMG1,
  564. "#LoadoutSlot_SMG", // LOADOUT_POSITION_SMG2,
  565. "#LoadoutSlot_SMG", // LOADOUT_POSITION_SMG3,
  566. "#LoadoutSlot_SMG", // LOADOUT_POSITION_SMG4,
  567. "#LoadoutSlot_SMG", // LOADOUT_POSITION_SMG5,
  568. "#LoadoutSlot_Rifle", // LOADOUT_POSITION_RIFLE0,
  569. "#LoadoutSlot_Rifle", // LOADOUT_POSITION_RIFLE1,
  570. "#LoadoutSlot_Rifle", // LOADOUT_POSITION_RIFLE2,
  571. "#LoadoutSlot_Rifle", // LOADOUT_POSITION_RIFLE3,
  572. "#LoadoutSlot_Rifle", // LOADOUT_POSITION_RIFLE4,
  573. "#LoadoutSlot_Rifle", // LOADOUT_POSITION_RIFLE5,
  574. "#LoadoutSlot_Heavy", // LOADOUT_POSITION_HEAVY0,
  575. "#LoadoutSlot_Heavy", // LOADOUT_POSITION_HEAVY1,
  576. "#LoadoutSlot_Heavy", // LOADOUT_POSITION_HEAVY2,
  577. "#LoadoutSlot_Heavy", // LOADOUT_POSITION_HEAVY3,
  578. "#LoadoutSlot_Heavy", // LOADOUT_POSITION_HEAVY4,
  579. "#LoadoutSlot_Heavy", // LOADOUT_POSITION_HEAVY5,
  580. "#LoadoutSlot_Grenade", // LOADOUT_POSITION_GRENADE0,
  581. "#LoadoutSlot_Grenade", // LOADOUT_POSITION_GRENADE1,
  582. "#LoadoutSlot_Grenade", // LOADOUT_POSITION_GRENADE2,
  583. "#LoadoutSlot_Grenade", // LOADOUT_POSITION_GRENADE3,
  584. "#LoadoutSlot_Grenade", // LOADOUT_POSITION_GRENADE4,
  585. "#LoadoutSlot_Grenade", // LOADOUT_POSITION_GRENADE5,
  586. "#LoadoutSlot_Equipment", // LOADOUT_POSITION_EQUIPMENT0,
  587. "#LoadoutSlot_Equipment", // LOADOUT_POSITION_EQUIPMENT1,
  588. "#LoadoutSlot_Equipment", // LOADOUT_POSITION_EQUIPMENT2,
  589. "#LoadoutSlot_Equipment", // LOADOUT_POSITION_EQUIPMENT3,
  590. "#LoadoutSlot_Equipment", // LOADOUT_POSITION_EQUIPMENT4,
  591. "#LoadoutSlot_Equipment", // LOADOUT_POSITION_EQUIPMENT5,
  592. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_APPEARANCE,
  593. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_TORSO,
  594. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_LOWERBODY,
  595. "#LoadoutSlot_Clothing_hands", // LOADOUT_POSITION_CLOTHING_HANDS,
  596. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_HAT,
  597. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_FACEMASK,
  598. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_EYEWEAR,
  599. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_CUSTOMHEAD,
  600. "#LoadoutSlot_Clothing", // LOADOUT_POSITION_CLOTHING_CUSTOMPLAYER,
  601. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC0,
  602. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC1,
  603. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC2,
  604. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC3,
  605. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC4,
  606. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC5,
  607. "#LoadoutSlot_Misc", // LOADOUT_POSITION_MISC6,
  608. "#LoadoutSlot_MusicKit", // LOADOUT_POSITION_MUSICKIT,
  609. "#LoadoutSlot_Flair", // LOADOUT_POSITION_FLAIR0,
  610. "#LoadoutSlot_Spray", // LOADOUT_POSITION_SPRAY0,
  611. };
  612. /*
  613. // Weapon types
  614. const char *g_szWeaponTypeSubstrings[TF_WPN_TYPE_COUNT] =
  615. {
  616. // Weapons & Equipment
  617. "PRIMARY",
  618. "SECONDARY",
  619. "MELEE",
  620. "GRENADE",
  621. "BUILDING",
  622. "PDA",
  623. "ITEM1",
  624. "ITEM2",
  625. "HEAD",
  626. "MISC",
  627. "MELEE_ALLCLASS",
  628. "SECONDARY2",
  629. "PRIMARY2"
  630. };
  631. */
  632. CCStrike15ItemSchema::CCStrike15ItemSchema()
  633. {
  634. COMPILE_TIME_ASSERT( ARRAYSIZE( g_szLoadoutStringsForDisplay ) == LOADOUT_POSITION_COUNT );
  635. COMPILE_TIME_ASSERT( ARRAYSIZE( g_szLoadoutStringsSubPositions ) == LOADOUT_POSITION_COUNT );
  636. COMPILE_TIME_ASSERT( ARRAYSIZE( g_szLoadoutStrings ) == LOADOUT_POSITION_COUNT );
  637. InitializeStringTable( &g_ClassUsabilityStrings[0], ARRAYSIZE(g_ClassUsabilityStrings), &m_vecClassUsabilityStrings );
  638. Assert( m_vecClassUsabilityStrings.Count() == LOADOUT_COUNT );
  639. InitializeStringTable( &g_szLoadoutStrings[0], ARRAYSIZE(g_szLoadoutStrings), &m_vecLoadoutStrings );
  640. Assert( m_vecLoadoutStrings.Count() == LOADOUT_POSITION_COUNT );
  641. InitializeStringTable( &g_szLoadoutStringsSubPositions[0], ARRAYSIZE(g_szLoadoutStringsSubPositions), &m_vecLoadoutStringsSubPositions );
  642. Assert( m_vecLoadoutStringsSubPositions.Count() == LOADOUT_POSITION_COUNT );
  643. InitializeStringTable( &g_szLoadoutStringsForDisplay[0], ARRAYSIZE(g_szLoadoutStringsForDisplay), &m_vecLoadoutStringsForDisplay );
  644. Assert( m_vecLoadoutStringsForDisplay.Count() == LOADOUT_POSITION_COUNT );
  645. // InitializeStringTable( &g_szWeaponTypeSubstrings[0], ARRAYSIZE(g_szWeaponTypeSubstrings), &m_vecWeaponTypeSubstrings );
  646. // Assert( m_vecWeaponTypeSubstrings.Count() == TF_WPN_TYPE_COUNT );
  647. }
  648. //-----------------------------------------------------------------------------
  649. // Purpose:
  650. //-----------------------------------------------------------------------------
  651. void CCStrike15ItemSchema::InitializeStringTable( const char **ppStringTable, unsigned int unStringCount, CUtlVector<const char *> *out_pvecStringTable )
  652. {
  653. Assert( ppStringTable != NULL );
  654. Assert( out_pvecStringTable != NULL );
  655. Assert( out_pvecStringTable->Count() == 0 );
  656. for ( unsigned int i = 0; i < unStringCount; i++ )
  657. {
  658. Assert( ppStringTable[i] != NULL );
  659. out_pvecStringTable->AddToTail( ppStringTable[i] );
  660. }
  661. }
  662. //-----------------------------------------------------------------------------
  663. // Purpose: Parses game specific items_master data.
  664. //-----------------------------------------------------------------------------
  665. bool CCStrike15ItemSchema::BInitSchema( KeyValues *pKVRawDefinition, CUtlVector<CUtlString> *pVecErrors )
  666. {
  667. return CEconItemSchema::BInitSchema( pKVRawDefinition, pVecErrors );
  668. }