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.

196 lines
7.3 KiB

  1. //========= Copyright � 1996-2003, Valve LLC, 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 "keyvalues.h"
  11. #include "attribute_manager.h"
  12. #include "vgui/ILocalize.h"
  13. #include "tier3/tier3.h"
  14. #include "util_shared.h"
  15. #include "props_shared.h"
  16. //==================================================================================
  17. // GENERATION SYSTEM
  18. //==================================================================================
  19. CItemGeneration g_ItemGenerationSystem;
  20. CItemGeneration *ItemGeneration( void )
  21. {
  22. return &g_ItemGenerationSystem;
  23. }
  24. //-----------------------------------------------------------------------------
  25. // Constructor, destructor
  26. //-----------------------------------------------------------------------------
  27. CItemGeneration::CItemGeneration( void )
  28. {
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Purpose: Generate a random item matching the specified criteria
  32. //-----------------------------------------------------------------------------
  33. CBaseEntity *CItemGeneration::GenerateRandomItem( CItemSelectionCriteria *pCriteria, const Vector &vecOrigin, const QAngle &vecAngles )
  34. {
  35. entityquality_t iQuality;
  36. int iChosenItem = ItemSystem()->GenerateRandomItem( pCriteria, &iQuality );
  37. if ( iChosenItem == INVALID_ITEM_INDEX )
  38. return NULL;
  39. return SpawnItem( iChosenItem, vecOrigin, vecAngles, pCriteria->GetItemLevel(), iQuality, NULL );
  40. }
  41. //-----------------------------------------------------------------------------
  42. // Purpose: Generate a random item matching the specified definition index
  43. //-----------------------------------------------------------------------------
  44. CBaseEntity *CItemGeneration::GenerateItemFromDefIndex( int iDefIndex, const Vector &vecOrigin, const QAngle &vecAngles )
  45. {
  46. return SpawnItem( iDefIndex, vecOrigin, vecAngles, 1, AE_UNIQUE, NULL );
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: Generate an item from the specified item data
  50. //-----------------------------------------------------------------------------
  51. CBaseEntity *CItemGeneration::GenerateItemFromScriptData( CEconItemView *pData, const Vector &vecOrigin, const QAngle &vecAngles, const char *pszOverrideClassName )
  52. {
  53. return SpawnItem( pData, vecOrigin, vecAngles, pszOverrideClassName );
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Purpose: Generate the base item for a class's loadout slot
  57. //-----------------------------------------------------------------------------
  58. CBaseEntity *CItemGeneration::GenerateBaseItem( struct baseitemcriteria_t *pCriteria )
  59. {
  60. int iChosenItem = ItemSystem()->GenerateBaseItem( pCriteria );
  61. if ( iChosenItem == INVALID_ITEM_INDEX )
  62. return NULL;
  63. return SpawnItem( iChosenItem, vec3_origin, vec3_angle, 1, AE_NORMAL, NULL );
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose: Create a new instance of the chosen item
  67. //-----------------------------------------------------------------------------
  68. CBaseEntity *CItemGeneration::SpawnItem( int iChosenItem, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles, int iItemLevel, entityquality_t entityQuality, const char *pszOverrideClassName )
  69. {
  70. const CEconItemDefinition *pData = ItemSystem()->GetStaticDataForItemByDefIndex( iChosenItem );
  71. if ( !pData )
  72. return NULL;
  73. if ( !pszOverrideClassName )
  74. {
  75. pszOverrideClassName = pData->GetItemClass();
  76. }
  77. CBaseEntity *pItem = CreateEntityByName( pszOverrideClassName );
  78. if ( !pItem )
  79. return NULL;
  80. // Set the item level & quality
  81. IHasAttributes *pItemInterface = dynamic_cast<IHasAttributes *>(pItem);
  82. Assert( pItemInterface );
  83. if ( pItemInterface )
  84. {
  85. // Setup the script item. Don't generate attributes here, because it'll be done during entity spawn.
  86. CEconItemView *pScriptItem = pItemInterface->GetAttributeContainer()->GetItem();
  87. pScriptItem->Init( iChosenItem, entityQuality, iItemLevel, false );
  88. }
  89. return PostSpawnItem( pItem, pItemInterface, vecAbsOrigin, vecAbsAngles );
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose: Create a base entity for the specified item data
  93. //-----------------------------------------------------------------------------
  94. CBaseEntity *CItemGeneration::SpawnItem( CEconItemView *pData, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles, const char *pszOverrideClassName )
  95. {
  96. if ( !pData->GetStaticData() )
  97. return NULL;
  98. if ( !pszOverrideClassName )
  99. {
  100. pszOverrideClassName = pData->GetStaticData()->GetItemClass();
  101. }
  102. CBaseEntity *pItem = CreateEntityByName( pszOverrideClassName );
  103. if ( !pItem )
  104. return NULL;
  105. // Set the item level & quality
  106. IHasAttributes *pItemInterface = dynamic_cast<IHasAttributes *>(pItem);
  107. Assert( pItemInterface );
  108. if ( pItemInterface )
  109. {
  110. pItemInterface->GetAttributeContainer()->SetItem( pData );
  111. }
  112. return PostSpawnItem( pItem, pItemInterface, vecAbsOrigin, vecAbsAngles );
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose:
  116. //-----------------------------------------------------------------------------
  117. CBaseEntity *CItemGeneration::PostSpawnItem( CBaseEntity *pItem, IHasAttributes *pItemInterface, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles )
  118. {
  119. const char *pszPlayerModel = NULL;
  120. CEconItemView *pScriptItem = NULL;
  121. if ( pItemInterface )
  122. {
  123. pScriptItem = pItemInterface->GetAttributeContainer()->GetItem();
  124. pszPlayerModel = pScriptItem->GetPlayerDisplayModel();
  125. }
  126. #ifndef CSTRIKE15
  127. if ( pScriptItem )
  128. {
  129. // For now, allow precaches until we have dynamic loading.
  130. bool allowPrecache = CBaseEntity::IsPrecacheAllowed();
  131. CBaseEntity::SetAllowPrecache( true );
  132. CUtlVector<const char *> vecPrecacheModelStrings;
  133. pScriptItem->GetStaticData()->GeneratePrecacheModelStrings( false, &vecPrecacheModelStrings );
  134. // Precache the models and the gibs for everything the definition requested.
  135. FOR_EACH_VEC( vecPrecacheModelStrings, i )
  136. {
  137. // Ignore any objects which requested an empty precache string for whatever reason.
  138. if ( vecPrecacheModelStrings[i] && vecPrecacheModelStrings[i][0] )
  139. {
  140. int iModelIndex = CBaseEntity::PrecacheModel( vecPrecacheModelStrings[i] );
  141. PrecacheGibsForModel( iModelIndex );
  142. }
  143. }
  144. // Precache any replacement sounds for this item.
  145. CUtlVector<const char *> vecPrecacheSoundStrings;
  146. pScriptItem->GetStaticData()->GeneratePrecacheSoundStrings( &vecPrecacheSoundStrings );
  147. FOR_EACH_VEC( vecPrecacheSoundStrings, i )
  148. {
  149. CBaseEntity::PrecacheScriptSound( vecPrecacheSoundStrings[i] );
  150. }
  151. // Precache any effects for this item
  152. CUtlVector<const char *> vecPrecacheEffectStrings;
  153. pScriptItem->GetStaticData()->GeneratePrecacheEffectStrings( &vecPrecacheEffectStrings );
  154. FOR_EACH_VEC( vecPrecacheEffectStrings, i )
  155. {
  156. PrecacheEffect( vecPrecacheEffectStrings[i] );
  157. }
  158. CBaseEntity::SetAllowPrecache( allowPrecache );
  159. }
  160. #endif
  161. #ifdef CLIENT_DLL
  162. // If we create a clientside item, we need to force it to initialize attributes
  163. if ( pItem->InitializeAsClientEntity( pszPlayerModel, false ) == false )
  164. return NULL;
  165. #endif
  166. pItem->SetAbsOrigin( vecAbsOrigin );
  167. pItem->SetAbsAngles( vecAbsAngles );
  168. pItem->Spawn();
  169. pItem->Activate();
  170. return pItem;
  171. }