Team Fortress 2 Source Code as on 22/4/2020
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.

180 lines
6.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "econ_entity_creation.h"
  8. #include "utldict.h"
  9. #include "filesystem.h"
  10. #include "gamestringpool.h"
  11. #include "KeyValues.h"
  12. #include "attribute_manager.h"
  13. #include "vgui/ILocalize.h"
  14. #include "tier3/tier3.h"
  15. #include "util_shared.h"
  16. #ifdef TF_CLIENT_DLL
  17. #include "c_tf_player.h"
  18. #endif // TF_CLIENT_DLL
  19. //==================================================================================
  20. // GENERATION SYSTEM
  21. //==================================================================================
  22. CItemGeneration g_ItemGenerationSystem;
  23. CItemGeneration *ItemGeneration( void )
  24. {
  25. return &g_ItemGenerationSystem;
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Constructor, destructor
  29. //-----------------------------------------------------------------------------
  30. CItemGeneration::CItemGeneration( void )
  31. {
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Purpose: Generate a random item matching the specified criteria
  35. //-----------------------------------------------------------------------------
  36. CBaseEntity *CItemGeneration::GenerateRandomItem( CItemSelectionCriteria *pCriteria, const Vector &vecOrigin, const QAngle &vecAngles )
  37. {
  38. entityquality_t iQuality;
  39. int iChosenItem = ItemSystem()->GenerateRandomItem( pCriteria, &iQuality );
  40. if ( iChosenItem == INVALID_ITEM_DEF_INDEX )
  41. return NULL;
  42. return SpawnItem( iChosenItem, vecOrigin, vecAngles, pCriteria->GetItemLevel(), iQuality, NULL );
  43. }
  44. //-----------------------------------------------------------------------------
  45. // Purpose: Generate a random item matching the specified definition index
  46. //-----------------------------------------------------------------------------
  47. CBaseEntity *CItemGeneration::GenerateItemFromDefIndex( int iDefIndex, const Vector &vecOrigin, const QAngle &vecAngles )
  48. {
  49. return SpawnItem( iDefIndex, vecOrigin, vecAngles, 1, AE_UNIQUE, NULL );
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Purpose: Generate an item from the specified item data
  53. //-----------------------------------------------------------------------------
  54. CBaseEntity *CItemGeneration::GenerateItemFromScriptData( const CEconItemView *pData, const Vector &vecOrigin, const QAngle &vecAngles, const char *pszOverrideClassName )
  55. {
  56. return SpawnItem( pData, vecOrigin, vecAngles, pszOverrideClassName );
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Purpose: Generate the base item for a class's loadout slot
  60. //-----------------------------------------------------------------------------
  61. CBaseEntity *CItemGeneration::GenerateBaseItem( struct baseitemcriteria_t *pCriteria )
  62. {
  63. int iChosenItem = ItemSystem()->GenerateBaseItem( pCriteria );
  64. if ( iChosenItem == INVALID_ITEM_DEF_INDEX )
  65. return NULL;
  66. return SpawnItem( iChosenItem, vec3_origin, vec3_angle, 1, AE_NORMAL, NULL );
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Purpose: Create a new instance of the chosen item
  70. //-----------------------------------------------------------------------------
  71. CBaseEntity *CItemGeneration::SpawnItem( int iChosenItem, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles, int iItemLevel, entityquality_t entityQuality, const char *pszOverrideClassName )
  72. {
  73. CEconItemDefinition *pData = ItemSystem()->GetStaticDataForItemByDefIndex( iChosenItem );
  74. if ( !pData )
  75. return NULL;
  76. if ( !pszOverrideClassName )
  77. {
  78. pszOverrideClassName = pData->GetItemClass();
  79. }
  80. if ( !pszOverrideClassName )
  81. return NULL;
  82. CBaseEntity *pItem = CreateEntityByName( pszOverrideClassName );
  83. if ( !pItem )
  84. return NULL;
  85. // Set the item level & quality
  86. IHasAttributes *pItemInterface = GetAttribInterface( pItem );
  87. Assert( pItemInterface );
  88. if ( pItemInterface )
  89. {
  90. // Setup the script item. Don't generate attributes here, because it'll be done during entity spawn.
  91. CEconItemView *pScriptItem = pItemInterface->GetAttributeContainer()->GetItem();
  92. pScriptItem->Init( iChosenItem, entityQuality, iItemLevel, false );
  93. }
  94. return PostSpawnItem( pItem, pItemInterface, vecAbsOrigin, vecAbsAngles );
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Purpose: Create a base entity for the specified item data
  98. //-----------------------------------------------------------------------------
  99. CBaseEntity *CItemGeneration::SpawnItem( const CEconItemView *pData, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles, const char *pszOverrideClassName )
  100. {
  101. if ( !pData->GetStaticData() )
  102. return NULL;
  103. if ( !pszOverrideClassName )
  104. {
  105. pszOverrideClassName = pData->GetStaticData()->GetItemClass();
  106. }
  107. if ( !pszOverrideClassName )
  108. return NULL;
  109. CBaseEntity *pItem = CreateEntityByName( pszOverrideClassName );
  110. if ( !pItem )
  111. return NULL;
  112. // Set the item level & quality
  113. IHasAttributes *pItemInterface = GetAttribInterface( pItem );
  114. Assert( pItemInterface );
  115. if ( pItemInterface )
  116. {
  117. pItemInterface->GetAttributeContainer()->SetItem( pData );
  118. }
  119. return PostSpawnItem( pItem, pItemInterface, vecAbsOrigin, vecAbsAngles );
  120. }
  121. //-----------------------------------------------------------------------------
  122. // Purpose:
  123. //-----------------------------------------------------------------------------
  124. CBaseEntity *CItemGeneration::PostSpawnItem( CBaseEntity *pItem, IHasAttributes *pItemInterface, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles )
  125. {
  126. #ifdef CLIENT_DLL
  127. const char *pszPlayerModel = NULL;
  128. if ( pItemInterface )
  129. {
  130. CEconItemView *pScriptItem = pItemInterface->GetAttributeContainer()->GetItem();
  131. int iClass = 0;
  132. int iTeam = 0;
  133. #ifdef TF_CLIENT_DLL
  134. C_TFPlayer *pTFPlayer = ToTFPlayer( GetPlayerByAccountID( pScriptItem->GetAccountID() ) );
  135. if ( pTFPlayer )
  136. {
  137. iClass = pTFPlayer->GetPlayerClass()->GetClassIndex();
  138. iTeam = pTFPlayer->GetTeamNumber();
  139. }
  140. #endif // TF_CLIENT_DLL
  141. pszPlayerModel = pScriptItem->GetPlayerDisplayModel( iClass, iTeam );
  142. }
  143. // If we create a clientside item, we need to force it to initialize attributes
  144. if ( pItem->InitializeAsClientEntity( pszPlayerModel, RENDER_GROUP_OPAQUE_ENTITY ) == false )
  145. return NULL;
  146. #endif // CLIENT_DLL
  147. pItem->SetAbsOrigin( vecAbsOrigin );
  148. pItem->SetAbsAngles( vecAbsAngles );
  149. pItem->Spawn();
  150. pItem->Activate();
  151. return pItem;
  152. }