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.

1971 lines
73 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "cbase.h"
  7. #include "econ_item_view.h"
  8. #include "econ_item_system.h"
  9. #include "econ_item_description.h"
  10. #include "econ_item_inventory.h"
  11. #include "rtime.h"
  12. #include "econ_gcmessages.h"
  13. #include "gamestringpool.h"
  14. // For localization
  15. #include "tier3/tier3.h"
  16. #include "vgui/ILocalize.h"
  17. #include "isaverestore.h"
  18. #include "dt_utlvector_send.h"
  19. #include "dt_utlvector_recv.h"
  20. #include <vgui_controls/Panel.h>
  21. #ifdef CLIENT_DLL
  22. #ifndef DEDICATED
  23. #include "vgui/IScheme.h"
  24. #endif
  25. #endif
  26. #if defined(TF_CLIENT_DLL)
  27. #include "tf_duel_summary.h"
  28. #include "econ_contribution.h"
  29. #include "tf_player_info.h"
  30. #include "tf_gcmessages.h"
  31. #include "c_tf_freeaccount.h"
  32. #include "c_tf_player.h"
  33. #endif
  34. #include "materialsystem/itexture.h"
  35. #include "materialsystem/itexturecompositor.h"
  36. #include "activitylist.h"
  37. #ifdef CLIENT_DLL
  38. #include "gc_clientsystem.h"
  39. #endif // CLIENT_DLL
  40. #ifdef GC_DLL
  41. #error "CEconItemView is not meant to be compiled on the GC! There are silent assumptions made about attributes, etc."
  42. #endif // GC_DLL
  43. // memdbgon must be the last include file in a .cpp file!!!
  44. #include "tier0/memdbgon.h"
  45. #ifdef STAGING_ONLY
  46. ConVar econ_force_style_index( "econ_force_style_index", "-1", FCVAR_REPLICATED );
  47. #endif // STAGING_ONLY
  48. // Networking tables for attributes
  49. BEGIN_NETWORK_TABLE_NOBASE( CEconItemAttribute, DT_ScriptCreatedAttribute )
  50. // Note: we are networking the value as an int, even though it's a "float", because really it isn't
  51. // a float. It's 32 raw bits.
  52. #ifndef CLIENT_DLL
  53. SendPropInt( SENDINFO(m_iAttributeDefinitionIndex), -1, SPROP_UNSIGNED ),
  54. SendPropInt( SENDINFO_NAME(m_flValue, m_iRawValue32), 32, SPROP_UNSIGNED ),
  55. #if ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  56. SendPropInt( SENDINFO(m_nRefundableCurrency), -1, SPROP_UNSIGNED ),
  57. #endif // ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  58. #else
  59. RecvPropInt( RECVINFO(m_iAttributeDefinitionIndex) ),
  60. RecvPropInt( RECVINFO_NAME(m_flValue, m_iRawValue32) ),
  61. RecvPropFloat( RECVINFO(m_flValue), SPROP_NOSCALE ), // for demo compatibility only
  62. #if ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  63. RecvPropInt( RECVINFO(m_nRefundableCurrency) ),
  64. #endif // ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  65. #endif
  66. END_NETWORK_TABLE()
  67. //-----------------------------------------------------------------------------
  68. // Purpose:
  69. //-----------------------------------------------------------------------------
  70. CEconItemAttribute::CEconItemAttribute( void )
  71. {
  72. Init();
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose:
  76. //-----------------------------------------------------------------------------
  77. CEconItemAttribute::CEconItemAttribute( const attrib_definition_index_t iAttributeIndex, float flValue )
  78. {
  79. Init();
  80. m_iAttributeDefinitionIndex = iAttributeIndex;
  81. SetValue( flValue );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose:
  85. //-----------------------------------------------------------------------------
  86. CEconItemAttribute::CEconItemAttribute( const attrib_definition_index_t iAttributeIndex, uint32 unValue )
  87. {
  88. Init();
  89. m_iAttributeDefinitionIndex = iAttributeIndex;
  90. SetIntValue( unValue );
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose:
  94. //-----------------------------------------------------------------------------
  95. void CEconItemAttribute::SetValue( float flValue )
  96. {
  97. // Assert( GetStaticData() && GetStaticData()->IsStoredAsFloat() );
  98. m_flValue = flValue;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose:
  102. //-----------------------------------------------------------------------------
  103. void CEconItemAttribute::SetIntValue( uint32 unValue )
  104. {
  105. // @note we don't check the storage type here, because this is how it is set from the data file
  106. // Note that numbers approaching two billion cannot be stored in a float
  107. // representation because they will map to NaNs. Numbers below 16 million
  108. // will fail if denormals are disabled.
  109. m_flValue = *(float*)&unValue;
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose:
  113. //-----------------------------------------------------------------------------
  114. void CEconItemAttribute::Init( void )
  115. {
  116. m_iAttributeDefinitionIndex = INVALID_ATTRIB_DEF_INDEX;
  117. m_flValue = 0.0f;
  118. #if ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  119. m_nRefundableCurrency = 0;
  120. #endif // ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose:
  124. //-----------------------------------------------------------------------------
  125. void CEconItemAttribute::operator=( const CEconItemAttribute &val )
  126. {
  127. m_iAttributeDefinitionIndex = val.m_iAttributeDefinitionIndex;
  128. m_flValue = val.m_flValue;
  129. #if ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  130. m_nRefundableCurrency = val.m_nRefundableCurrency;
  131. #endif // ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose:
  135. //-----------------------------------------------------------------------------
  136. const CEconItemAttributeDefinition *CEconItemAttribute::GetStaticData( void ) const
  137. {
  138. return GetItemSchema()->GetAttributeDefinition( m_iAttributeDefinitionIndex );
  139. }
  140. BEGIN_NETWORK_TABLE_NOBASE( CAttributeList, DT_AttributeList )
  141. #if !defined( CLIENT_DLL )
  142. SendPropUtlVectorDataTable( m_Attributes, MAX_ATTRIBUTES_PER_ITEM, DT_ScriptCreatedAttribute ),
  143. #else
  144. RecvPropUtlVectorDataTable( m_Attributes, MAX_ATTRIBUTES_PER_ITEM, DT_ScriptCreatedAttribute ),
  145. #endif // CLIENT_DLL
  146. END_NETWORK_TABLE()
  147. BEGIN_DATADESC_NO_BASE( CAttributeList )
  148. END_DATADESC()
  149. //===========================================================================================================================
  150. // SCRIPT CREATED ITEMS
  151. //===========================================================================================================================
  152. BEGIN_NETWORK_TABLE_NOBASE( CEconItemView, DT_ScriptCreatedItem )
  153. #if !defined( CLIENT_DLL )
  154. SendPropInt( SENDINFO( m_iItemDefinitionIndex ), 20, SPROP_UNSIGNED ),
  155. SendPropInt( SENDINFO( m_iEntityLevel ), 8 ),
  156. //SendPropInt( SENDINFO( m_iItemID ), 64, SPROP_UNSIGNED ),
  157. SendPropInt( SENDINFO( m_iItemIDHigh ), 32, SPROP_UNSIGNED ),
  158. SendPropInt( SENDINFO( m_iItemIDLow ), 32, SPROP_UNSIGNED ),
  159. SendPropInt( SENDINFO( m_iAccountID ), 32, SPROP_UNSIGNED ),
  160. SendPropInt( SENDINFO( m_iEntityQuality ), 5 ),
  161. SendPropBool( SENDINFO( m_bInitialized ) ),
  162. SendPropBool( SENDINFO( m_bOnlyIterateItemViewAttributes) ),
  163. SendPropDataTable(SENDINFO_DT(m_AttributeList), &REFERENCE_SEND_TABLE(DT_AttributeList)),
  164. SendPropInt( SENDINFO( m_iTeamNumber ) ),
  165. SendPropDataTable(SENDINFO_DT( m_NetworkedDynamicAttributesForDemos ), &REFERENCE_SEND_TABLE( DT_AttributeList ) ),
  166. #else
  167. RecvPropInt( RECVINFO( m_iItemDefinitionIndex ) ),
  168. RecvPropInt( RECVINFO( m_iEntityLevel ) ),
  169. //RecvPropInt( RECVINFO( m_iItemID ) ),
  170. RecvPropInt( RECVINFO( m_iItemIDHigh ) ),
  171. RecvPropInt( RECVINFO( m_iItemIDLow ) ),
  172. RecvPropInt( RECVINFO( m_iAccountID ) ),
  173. RecvPropInt( RECVINFO( m_iEntityQuality ) ),
  174. RecvPropBool( RECVINFO( m_bInitialized ) ),
  175. RecvPropBool( RECVINFO( m_bOnlyIterateItemViewAttributes ) ),
  176. RecvPropDataTable(RECVINFO_DT(m_AttributeList), 0, &REFERENCE_RECV_TABLE(DT_AttributeList)),
  177. RecvPropInt( RECVINFO( m_iTeamNumber ) ),
  178. RecvPropDataTable( RECVINFO_DT( m_NetworkedDynamicAttributesForDemos ), 0, &REFERENCE_RECV_TABLE( DT_AttributeList ) ),
  179. #endif // CLIENT_DLL
  180. END_NETWORK_TABLE()
  181. BEGIN_DATADESC_NO_BASE( CEconItemView )
  182. DEFINE_FIELD( m_iItemDefinitionIndex, FIELD_INTEGER ),
  183. DEFINE_FIELD( m_iEntityQuality, FIELD_INTEGER ),
  184. DEFINE_FIELD( m_iEntityLevel, FIELD_INTEGER ),
  185. DEFINE_FIELD( m_iItemID, FIELD_INTEGER ),
  186. // DEFINE_FIELD( m_wszItemName, FIELD_STRING ), Regenerated post-save
  187. // DEFINE_FIELD( m_szItemName, FIELD_STRING ), Regenerated post-save
  188. // DEFINE_FIELD( m_szAttributeDescription, FIELD_STRING ), Regenerated post-save
  189. // m_AttributeLineColors // Regenerated post-save
  190. // m_Attributes // Custom handling in Save()/Restore()
  191. DEFINE_FIELD( m_bInitialized, FIELD_BOOLEAN ),
  192. DEFINE_FIELD( m_bOnlyIterateItemViewAttributes, FIELD_BOOLEAN ),
  193. DEFINE_EMBEDDED( m_AttributeList ),
  194. DEFINE_EMBEDDED( m_NetworkedDynamicAttributesForDemos ),
  195. END_DATADESC()
  196. //-----------------------------------------------------------------------------
  197. // Purpose:
  198. //-----------------------------------------------------------------------------
  199. CEconItemView::CEconItemView( void )
  200. {
  201. m_iItemDefinitionIndex = INVALID_ITEM_DEF_INDEX;
  202. m_iEntityQuality = (int)AE_UNDEFINED;
  203. m_iEntityLevel = 0;
  204. SetItemID( INVALID_ITEM_ID );
  205. m_iInventoryPosition = 0;
  206. m_bInitialized = false;
  207. m_bOnlyIterateItemViewAttributes = false;
  208. m_iAccountID = 0;
  209. m_pNonSOEconItem = NULL;
  210. m_bColorInit = false;
  211. m_bPaintOverrideInit = false;
  212. m_bHasPaintOverride = false;
  213. m_flOverrideIndex = 0.f;
  214. #if defined( CLIENT_DLL )
  215. m_bIsTradeItem = false;
  216. m_iEntityQuantity = 1;
  217. m_unClientFlags = 0;
  218. m_unOverrideStyle = INVALID_STYLE_INDEX;
  219. m_unOverrideOrigin = kEconItemOrigin_Max;
  220. #endif
  221. #if BUILD_ITEM_NAME_AND_DESC
  222. m_pDescription = NULL;
  223. m_pszGrayedOutReason = NULL;
  224. #endif
  225. #ifdef CLIENT_DLL
  226. m_pWeaponSkinBase = NULL;
  227. m_pWeaponSkinBaseCompositor = NULL;
  228. m_iLastGeneratedTeamSkin = TF_TEAM_RED;
  229. m_bWeaponSkinUseHighRes = false;
  230. m_bWeaponSkinUseLowRes = false;
  231. #endif // CLIENT_DLL
  232. m_iTeamNumber = TF_TEAM_RED;
  233. }
  234. //-----------------------------------------------------------------------------
  235. // Purpose:
  236. //-----------------------------------------------------------------------------
  237. CEconItemView::~CEconItemView( void )
  238. {
  239. #ifdef CLIENT_DLL
  240. SafeRelease( &m_pWeaponSkinBase );
  241. SafeRelease( &m_pWeaponSkinBaseCompositor );
  242. #endif // CLIENT_DLL
  243. DestroyAllAttributes();
  244. #if BUILD_ITEM_NAME_AND_DESC
  245. MarkDescriptionDirty();
  246. free( m_pszGrayedOutReason );
  247. #endif
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Purpose:
  251. //-----------------------------------------------------------------------------
  252. CEconItemView::CEconItemView( const CEconItemView &src )
  253. {
  254. #if BUILD_ITEM_NAME_AND_DESC
  255. m_pDescription = NULL;
  256. m_pszGrayedOutReason = NULL;
  257. #endif
  258. #ifdef CLIENT_DLL
  259. // Need to null these out here for initial behavior.
  260. m_pWeaponSkinBase = NULL;
  261. m_pWeaponSkinBaseCompositor = NULL;
  262. m_nWeaponSkinGeneration = 0;
  263. m_iLastGeneratedTeamSkin = TF_TEAM_RED;
  264. m_unWeaponSkinBaseCreateFlags = 0;
  265. m_bWeaponSkinUseHighRes = src.m_bWeaponSkinUseHighRes;
  266. m_bWeaponSkinUseLowRes = src.m_bWeaponSkinUseLowRes;
  267. #endif //CLIENT_DLL
  268. m_iTeamNumber = src.m_iTeamNumber; // keep the same team from the first creation
  269. *this = src;
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Purpose:
  273. //-----------------------------------------------------------------------------
  274. void CEconItemView::Init( int iDefIndex, int iQuality, int iLevel, uint32 iAccountID )
  275. {
  276. m_AttributeList.Init();
  277. m_NetworkedDynamicAttributesForDemos.Init();
  278. m_iItemDefinitionIndex = iDefIndex;
  279. CEconItemDefinition *pData = GetStaticData();
  280. if ( !pData )
  281. {
  282. // We've got an item that we don't have static data for.
  283. return;
  284. }
  285. SetItemID( INVALID_ITEM_ID );
  286. m_bInitialized = true;
  287. m_iAccountID = iAccountID;
  288. if ( iQuality == AE_USE_SCRIPT_VALUE )
  289. {
  290. m_iEntityQuality = pData->GetQuality();
  291. // Kyle says: this is a horrible hack because AE_UNDEFINED will get stuffed into a uint8 when
  292. // loaded into the item definition, but then read back out into a regular int here.
  293. if ( m_iEntityQuality == (uint8)AE_UNDEFINED )
  294. {
  295. m_iEntityQuality = (int)AE_NORMAL;
  296. }
  297. }
  298. else if ( iQuality == k_unItemQuality_Any )
  299. {
  300. m_iEntityQuality = (int)AE_RARITY1;
  301. }
  302. else
  303. {
  304. m_iEntityQuality = iQuality;
  305. }
  306. if ( iLevel == AE_USE_SCRIPT_VALUE )
  307. {
  308. m_iEntityLevel = pData->RollItemLevel();
  309. }
  310. else
  311. {
  312. m_iEntityLevel = iLevel;
  313. }
  314. // We made changes to quality, level, etc. so mark the description as dirty.
  315. MarkDescriptionDirty();
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Purpose:
  319. //-----------------------------------------------------------------------------
  320. CEconItemView& CEconItemView::operator=( const CEconItemView& src )
  321. {
  322. m_iItemDefinitionIndex = src.m_iItemDefinitionIndex;
  323. m_iEntityQuality = src.m_iEntityQuality;
  324. m_iEntityLevel = src.m_iEntityLevel;
  325. SetItemID( src.GetItemID() );
  326. m_iInventoryPosition = src.m_iInventoryPosition;
  327. m_bInitialized = src.m_bInitialized;
  328. m_bOnlyIterateItemViewAttributes = src.m_bOnlyIterateItemViewAttributes;
  329. m_iAccountID = src.m_iAccountID;
  330. SetNonSOEconItem(src.m_pNonSOEconItem);
  331. m_bColorInit = false; // reset Color init
  332. m_bPaintOverrideInit = false;
  333. m_bHasPaintOverride = false;
  334. m_flOverrideIndex = 0.f;
  335. #ifdef CLIENT_DLL
  336. m_iLastGeneratedTeamSkin = src.m_iLastGeneratedTeamSkin;
  337. m_bIsTradeItem = src.m_bIsTradeItem;
  338. m_iEntityQuantity = src.m_iEntityQuantity;
  339. m_unClientFlags = src.m_unClientFlags;
  340. m_unOverrideStyle = src.m_unOverrideStyle;
  341. m_unOverrideOrigin = src.m_unOverrideOrigin;
  342. SafeAssign( &m_pWeaponSkinBase, src.m_pWeaponSkinBase );
  343. SafeAssign( &m_pWeaponSkinBaseCompositor, src.m_pWeaponSkinBaseCompositor );
  344. m_nWeaponSkinGeneration = src.m_nWeaponSkinGeneration;
  345. m_unWeaponSkinBaseCreateFlags = src.m_unWeaponSkinBaseCreateFlags;
  346. m_bWeaponSkinUseHighRes = src.m_bWeaponSkinUseHighRes;
  347. m_bWeaponSkinUseLowRes = src.m_bWeaponSkinUseLowRes;
  348. #endif // CLIENT_DLL
  349. m_iTeamNumber = src.m_iTeamNumber; // keep the same team from the first creation
  350. DestroyAllAttributes();
  351. m_AttributeList = src.m_AttributeList;
  352. m_NetworkedDynamicAttributesForDemos = src.m_NetworkedDynamicAttributesForDemos;
  353. // TODO: Copying the description pointer and refcounting it would work also.
  354. MarkDescriptionDirty();
  355. // Clear out any overrides we currently have, they'll get reset up on demand.
  356. ResetMaterialOverrides();
  357. return *this;
  358. }
  359. //-----------------------------------------------------------------------------
  360. // Purpose:
  361. //-----------------------------------------------------------------------------
  362. bool CEconItemView::operator==( const CEconItemView &other ) const
  363. {
  364. if ( IsValid() != other.IsValid() )
  365. return false;
  366. if ( ( GetItemID() != INVALID_ITEM_ID || other.GetItemID() != INVALID_ITEM_ID ) && GetItemID() != other.GetItemID() )
  367. return false;
  368. if ( GetItemDefIndex() != other.GetItemDefIndex() )
  369. return false;
  370. return true;
  371. }
  372. //-----------------------------------------------------------------------------
  373. // Purpose:
  374. //-----------------------------------------------------------------------------
  375. GameItemDefinition_t *CEconItemView::GetStaticData( void ) const
  376. {
  377. CEconItemDefinition *pRet = GetItemSchema()->GetItemDefinition( m_iItemDefinitionIndex );
  378. GameItemDefinition_t *pTypedRet = dynamic_cast<GameItemDefinition_t *>( pRet );
  379. AssertMsg( pRet == pTypedRet, "Item definition of inappropriate type." );
  380. return pTypedRet;
  381. }
  382. //-----------------------------------------------------------------------------
  383. // Purpose:
  384. //-----------------------------------------------------------------------------
  385. int32 CEconItemView::GetQuality() const
  386. {
  387. return GetSOCData()
  388. ? GetSOCData()->GetQuality()
  389. #ifdef TF_CLIENT_DLL
  390. : GetFlags() & kEconItemFlagClient_StoreItem
  391. ? AE_UNIQUE
  392. #endif
  393. : GetOrigin() != kEconItemOrigin_Invalid
  394. ? GetItemQuality()
  395. : AE_NORMAL;
  396. }
  397. //-----------------------------------------------------------------------------
  398. // Purpose:
  399. //-----------------------------------------------------------------------------
  400. style_index_t CEconItemView::GetStyle() const
  401. {
  402. return GetItemStyle();
  403. }
  404. //-----------------------------------------------------------------------------
  405. // Purpose:
  406. //-----------------------------------------------------------------------------
  407. uint8 CEconItemView::GetFlags() const
  408. {
  409. uint8 unSOCFlags = GetSOCData() ? GetSOCData()->GetFlags() : 0;
  410. #if !defined( GAME_DLL )
  411. return unSOCFlags | m_unClientFlags;
  412. #else // defined( GAME_DLL )
  413. return unSOCFlags;
  414. #endif // !defined( GAME_DLL )
  415. }
  416. //-----------------------------------------------------------------------------
  417. // Purpose:
  418. //-----------------------------------------------------------------------------
  419. eEconItemOrigin CEconItemView::GetOrigin() const
  420. {
  421. #ifdef CLIENT_DLL
  422. if( m_unOverrideOrigin != kEconItemOrigin_Max )
  423. {
  424. return m_unOverrideOrigin;
  425. }
  426. #endif//CLIENT_DLL
  427. return GetSOCData() ? GetSOCData()->GetOrigin() : kEconItemOrigin_Invalid;
  428. }
  429. //-----------------------------------------------------------------------------
  430. // Purpose:
  431. //-----------------------------------------------------------------------------
  432. int CEconItemView::GetQuantity() const
  433. {
  434. return GetItemQuantity();
  435. }
  436. //-----------------------------------------------------------------------------
  437. // Purpose:
  438. //-----------------------------------------------------------------------------
  439. const char *CEconItemView::GetCustomName() const
  440. {
  441. return GetSOCData() ? GetSOCData()->GetCustomName() : NULL;
  442. }
  443. //-----------------------------------------------------------------------------
  444. // Purpose:
  445. //-----------------------------------------------------------------------------
  446. const char *CEconItemView::GetCustomDesc() const
  447. {
  448. return GetSOCData() ? GetSOCData()->GetCustomDesc() : NULL;
  449. }
  450. //-----------------------------------------------------------------------------
  451. // Purpose:
  452. //-----------------------------------------------------------------------------
  453. void CEconItemView::IterateAttributes( class IEconItemAttributeIterator *pIterator ) const
  454. {
  455. Assert( pIterator );
  456. // Note if we have network attribs, because m_NetworkedDynamicAttributesForDemos might be the iterator
  457. // which we're about to fill up below.
  458. const bool bHasNetworkedAttribsForDemos = m_NetworkedDynamicAttributesForDemos.GetNumAttributes() > 0;
  459. // First, we iterate over the attributes we have local copies of. If we have any attribute
  460. // values here they'll override whatever values we would otherwise have pulled from our
  461. // definition/CEconItem.
  462. const CAttributeList *pAttrList = GetAttributeList();
  463. if ( pAttrList )
  464. {
  465. pAttrList->IterateAttributes( pIterator );
  466. }
  467. if ( m_bOnlyIterateItemViewAttributes )
  468. return;
  469. // This wraps any other iterator class and will prevent double iteration of any attributes
  470. // that exist on us.
  471. class CEconItemAttributeIterator_EconItemViewWrapper : public IEconItemAttributeIterator
  472. {
  473. public:
  474. CEconItemAttributeIterator_EconItemViewWrapper( const CEconItemView *pEconItemView, IEconItemAttributeIterator *pIterator )
  475. : m_pEconItemView( pEconItemView )
  476. , m_pIterator( pIterator )
  477. {
  478. Assert( m_pEconItemView );
  479. Assert( m_pIterator );
  480. }
  481. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, attrib_value_t value )
  482. {
  483. Assert( pAttrDef );
  484. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  485. ? true
  486. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  487. }
  488. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float value )
  489. {
  490. Assert( pAttrDef );
  491. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  492. ? true
  493. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  494. }
  495. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const uint64& value )
  496. {
  497. Assert( pAttrDef );
  498. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  499. ? true
  500. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  501. }
  502. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_String& value )
  503. {
  504. Assert( pAttrDef );
  505. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  506. ? true
  507. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  508. }
  509. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_DynamicRecipeComponent& value )
  510. {
  511. Assert( pAttrDef );
  512. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  513. ? true
  514. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  515. }
  516. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_ItemSlotCriteria& value )
  517. {
  518. Assert( pAttrDef );
  519. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  520. ? true
  521. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  522. }
  523. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_WorldItemPlacement& value )
  524. {
  525. Assert( pAttrDef );
  526. return m_pEconItemView->GetAttributeList()->GetAttributeByID( pAttrDef->GetDefinitionIndex() )
  527. ? true
  528. : m_pIterator->OnIterateAttributeValue( pAttrDef, value );
  529. }
  530. private:
  531. const CEconItemView *m_pEconItemView;
  532. IEconItemAttributeIterator *m_pIterator;
  533. };
  534. CEconItemAttributeIterator_EconItemViewWrapper iteratorWrapper( this, pIterator );
  535. // Next, iterate over our database-backed item if we have one... if we do have a DB
  536. // backing for our item here, that will also feed in the definition attributes.
  537. CEconItem *pEconItem = GetSOCData();
  538. if ( pEconItem )
  539. {
  540. pEconItem->IterateAttributes( &iteratorWrapper );
  541. }
  542. else if ( GetItemID() != INVALID_ITEM_ID && bHasNetworkedAttribsForDemos )
  543. {
  544. // Since there's no persistent data available, try the networked values!
  545. // note: only copies the default type and floats
  546. m_NetworkedDynamicAttributesForDemos.IterateAttributes( &iteratorWrapper );
  547. }
  548. // If we didn't have a DB backing, we can still iterate over our item definition
  549. // attributes ourselves. This can happen if we're previewing an item in the store, etc.
  550. else if ( GetStaticData() )
  551. {
  552. GetStaticData()->IterateAttributes( &iteratorWrapper );
  553. }
  554. }
  555. //-----------------------------------------------------------------------------
  556. // Purpose:
  557. //-----------------------------------------------------------------------------
  558. void CEconItemView::EnsureDescriptionIsBuilt() const
  559. {
  560. #if BUILD_ITEM_NAME_AND_DESC
  561. if ( m_pDescription )
  562. {
  563. return;
  564. }
  565. m_pDescription = new CEconItemDescription;
  566. IEconItemDescription::YieldingFillOutEconItemDescription( m_pDescription, GLocalizationProvider(), this );
  567. // We use the empty string to mean "grey out but don't specify a user-facing reason".
  568. if ( m_pszGrayedOutReason && m_pszGrayedOutReason[0] )
  569. {
  570. m_pDescription->AddEmptyDescLine();
  571. m_pDescription->LocalizedAddDescLine( GLocalizationProvider(), m_pszGrayedOutReason, ATTRIB_COL_NEGATIVE, kDescLineFlag_Misc );
  572. }
  573. #endif
  574. }
  575. //-----------------------------------------------------------------------------
  576. // Purpose:
  577. //-----------------------------------------------------------------------------
  578. void CEconItemView::MarkDescriptionDirty()
  579. {
  580. #if BUILD_ITEM_NAME_AND_DESC
  581. if ( m_pDescription )
  582. {
  583. delete m_pDescription;
  584. m_pDescription = NULL;
  585. }
  586. #endif
  587. }
  588. //-----------------------------------------------------------------------------
  589. // Purpose:
  590. //-----------------------------------------------------------------------------
  591. void CEconItemView::SetGrayedOutReason( const char *pszGrayedOutReason )
  592. {
  593. #if BUILD_ITEM_NAME_AND_DESC
  594. if ( m_pszGrayedOutReason )
  595. {
  596. free( m_pszGrayedOutReason );
  597. m_pszGrayedOutReason = NULL;
  598. }
  599. if ( pszGrayedOutReason )
  600. {
  601. m_pszGrayedOutReason = strdup(pszGrayedOutReason);
  602. }
  603. MarkDescriptionDirty();
  604. #endif
  605. }
  606. //-----------------------------------------------------------------------------
  607. // Purpose:
  608. //-----------------------------------------------------------------------------
  609. int CEconItemView::GetItemQuantity() const
  610. {
  611. CEconItem *pSOCData = GetSOCData();
  612. if ( pSOCData )
  613. {
  614. return pSOCData->GetQuantity();
  615. }
  616. #ifdef CLIENT_DLL
  617. return m_iEntityQuantity;
  618. #else
  619. return 1;
  620. #endif
  621. }
  622. //-----------------------------------------------------------------------------
  623. // Purpose:
  624. //-----------------------------------------------------------------------------
  625. style_index_t CEconItemView::GetItemStyle() const
  626. {
  627. #ifdef STAGING_ONLY
  628. if ( econ_force_style_index.GetInt() != -1 )
  629. return econ_force_style_index.GetInt();
  630. #endif // STAGING_ONLY
  631. #ifdef CLIENT_DLL
  632. // Are we overriding the backing store style?
  633. if ( m_unOverrideStyle != INVALID_STYLE_INDEX )
  634. return m_unOverrideStyle;
  635. #endif // CLIENT_DLL
  636. static CSchemaAttributeDefHandle pAttrDef_ItemStyleOverride( "item style override" );
  637. float fStyleOverride = 0.f;
  638. if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( this, pAttrDef_ItemStyleOverride, &fStyleOverride ) )
  639. {
  640. return fStyleOverride;
  641. }
  642. static CSchemaAttributeDefHandle pAttrDef_ItemStyleStrange( "style changes on strange level" );
  643. uint32 iMaxStyle = 0;
  644. if ( pAttrDef_ItemStyleStrange && FindAttribute( pAttrDef_ItemStyleStrange, &iMaxStyle ) )
  645. {
  646. // Use the strange prefix if the weapon has one.
  647. uint32 unScore = 0;
  648. if ( !FindAttribute( GetKillEaterAttr_Score( 0 ), &unScore ) )
  649. return 0;
  650. // What type of event are we tracking and how does it describe itself?
  651. uint32 unKillEaterEventType = 0;
  652. // This will overwrite our default 0 value if we have a value set but leave it if not.
  653. float fKillEaterEventType;
  654. if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( this, GetKillEaterAttr_Type( 0 ), &fKillEaterEventType ) )
  655. {
  656. unKillEaterEventType = fKillEaterEventType;
  657. }
  658. const char *pszLevelingDataName = GetItemSchema()->GetKillEaterScoreTypeLevelingDataName( unKillEaterEventType );
  659. if ( !pszLevelingDataName )
  660. {
  661. pszLevelingDataName = KILL_EATER_RANK_LEVEL_BLOCK_NAME;
  662. }
  663. const CItemLevelingDefinition *pLevelDef = GetItemSchema()->GetItemLevelForScore( pszLevelingDataName, unScore );
  664. if ( !pLevelDef )
  665. return 0;
  666. return Min( pLevelDef->GetLevel(), iMaxStyle );
  667. }
  668. CEconItem *pSOCData = GetSOCData();
  669. if ( pSOCData )
  670. return pSOCData->GetStyle();
  671. return INVALID_STYLE_INDEX;
  672. }
  673. #ifdef CLIENT_DLL
  674. //-----------------------------------------------------------------------------
  675. // Purpose:
  676. //-----------------------------------------------------------------------------
  677. void CEconItemView::SetClientItemFlags( uint8 unFlags )
  678. {
  679. // Generally speaking, we have two uses for client flags:
  680. //
  681. // - we don't have a backing store (a real CEconItem) but want to pretend we do
  682. // for purposes of generating tooltips, graying out icons, etc.
  683. //
  684. // - we may or may not have a backing store but want to shove client-specific
  685. // information into the structure -- things like "this is the item being
  686. // actively previewed", etc.
  687. //
  688. // If neither of these two cases is true, then we're going to get unexpected
  689. // behavior where the GC and the client disagree about the item flags and then
  690. // Terrible Things happen. We assert to make sure we're in one of the above cases.
  691. Assert( !GetSOCData() || (unFlags & kEconItemFlags_CheckFlags_AllGCFlags) == 0 );
  692. m_unClientFlags = unFlags;
  693. MarkDescriptionDirty();
  694. }
  695. //-----------------------------------------------------------------------------
  696. // Purpose:
  697. //-----------------------------------------------------------------------------
  698. void CEconItemView::SetItemStyleOverride( style_index_t unNewStyleOverride )
  699. {
  700. // We should only ever override the style on items that don't have a real
  701. // backing store or we'll start getting disagreements about what the client
  702. // wants to happen and what's being stored on the GC. Unfortunately we can't
  703. // assert on this because we do it sometimes when previewing items.
  704. //Assert( !GetSOCData() );
  705. m_unOverrideStyle = unNewStyleOverride;
  706. MarkDescriptionDirty();
  707. }
  708. void CEconItemView::SetItemOriginOverride( eEconItemOrigin unNewOriginOverride )
  709. {
  710. Assert( !GetSOCData() || m_pNonSOEconItem );
  711. Assert( unNewOriginOverride >= kEconItemOrigin_Invalid );
  712. Assert( unNewOriginOverride <= kEconItemOrigin_Max ); // Allow max. We ignore this value if it's max
  713. m_unOverrideOrigin = unNewOriginOverride;
  714. }
  715. #endif // CLIENT_DLL
  716. //-----------------------------------------------------------------------------
  717. // Purpose:
  718. //-----------------------------------------------------------------------------
  719. CEconItem *CEconItemView::GetSOCData( void ) const
  720. {
  721. if ( m_pNonSOEconItem )
  722. return m_pNonSOEconItem;
  723. #ifdef CLIENT_DLL
  724. // We need to find the inventory that contains this item. If we're not connected
  725. // to a server, and the owner is the same as the local player, use the local inventory.
  726. // We need to do this for trading, since we are subscribed to the other person's cache.
  727. if ( !engine->IsInGame() && InventoryManager()->GetLocalInventory()->GetOwner().GetAccountID() == m_iAccountID )
  728. return InventoryManager()->GetLocalInventory()->GetSOCDataForItem( GetItemID() );
  729. #endif // CLIENT_DLL
  730. // We're in-game. Find the inventory with our account ID.
  731. CPlayerInventory *pInventory = InventoryManager()->GetInventoryForAccount( m_iAccountID );
  732. if ( pInventory )
  733. return pInventory->GetSOCDataForItem( GetItemID() );
  734. return NULL;
  735. }
  736. //-----------------------------------------------------------------------------
  737. // Purpose: Return the model to use for model panels containing this item
  738. //-----------------------------------------------------------------------------
  739. const char *CEconItemView::GetInventoryModel( void )
  740. {
  741. if ( !GetStaticData() )
  742. return NULL;
  743. return GetStaticData()->GetInventoryModel();
  744. }
  745. //-----------------------------------------------------------------------------
  746. // Purpose: Return the image to use for model panels containing this item
  747. //-----------------------------------------------------------------------------
  748. const char *CEconItemView::GetInventoryImage( void )
  749. {
  750. if ( !GetStaticData() )
  751. return NULL;
  752. // Do we have a style set?
  753. const char* pStyleImage = NULL;
  754. if ( GetStaticData()->GetNumStyles() )
  755. pStyleImage = GetStaticData()->GetStyleInventoryImage( GetItemStyle() );
  756. if ( pStyleImage && *pStyleImage )
  757. return pStyleImage;
  758. return GetStaticData()->GetInventoryImage();
  759. }
  760. //-----------------------------------------------------------------------------
  761. // Purpose: Return the drawing data for the image to use for model panels containing this item
  762. //-----------------------------------------------------------------------------
  763. bool CEconItemView::GetInventoryImageData( int *iPosition, int *iSize )
  764. {
  765. if ( !GetStaticData() )
  766. return false;
  767. for ( int i = 0; i < 2; i++ )
  768. {
  769. iPosition[i] = GetStaticData()->GetInventoryImagePosition(i);
  770. iSize[i] = GetStaticData()->GetInventoryImageSize(i);
  771. }
  772. return true;
  773. }
  774. //-----------------------------------------------------------------------------
  775. // Purpose: Return the image to use for model panels containing this item
  776. //-----------------------------------------------------------------------------
  777. const char *CEconItemView::GetInventoryOverlayImage( int idx )
  778. {
  779. if ( !GetStaticData() )
  780. return NULL;
  781. return GetStaticData()->GetInventoryOverlayImage( idx );
  782. }
  783. int CEconItemView::GetInventoryOverlayImageCount( void )
  784. {
  785. if ( !GetStaticData() )
  786. return 0;
  787. return GetStaticData()->GetInventoryOverlayImageCount();
  788. }
  789. //-----------------------------------------------------------------------------
  790. // Purpose: Return the model to use when displaying this model on the player character model, if any
  791. //-----------------------------------------------------------------------------
  792. const char *CEconItemView::GetPlayerDisplayModel( int iClass, int iTeam ) const
  793. {
  794. const CEconItemDefinition *pDef = GetStaticData();
  795. if ( !pDef )
  796. return NULL;
  797. // If we have styles, give the style system a chance to change the mesh used for this
  798. // player class.
  799. if ( pDef->GetNumStyles() )
  800. {
  801. style_index_t unStyle = GetItemStyle();
  802. const CEconStyleInfo *pStyle = pDef->GetStyleInfo( unStyle );
  803. // It's possible to get back a NULL pStyle if GetItemStyle() returns INVALID_STYLE_INDEX.
  804. if ( pStyle )
  805. {
  806. #if defined( TF_DLL ) || defined( TF_CLIENT_DLL )
  807. // TF styles support per-class models.
  808. const CTFStyleInfo *pTFStyle = assert_cast<const CTFStyleInfo *>( pStyle );
  809. if ( pTFStyle->GetPlayerDisplayModel( iClass, iTeam ) )
  810. return pTFStyle->GetPlayerDisplayModel( iClass, iTeam );
  811. #endif // defined( TF_DLL ) || defined( TF_CLIENT_DLL )
  812. if ( pStyle->GetBasePlayerDisplayModel() )
  813. return pStyle->GetBasePlayerDisplayModel();
  814. }
  815. }
  816. #if defined( TF_DLL ) || defined( TF_CLIENT_DLL )
  817. // If we don't have a style, we still a couple potential overrides.
  818. if ( iClass >= 0 && iClass < LOADOUT_COUNT )
  819. {
  820. // We don't support overriding meshes in the visuals section, but we might still be overriding
  821. // the model for each class at the schema level.
  822. const CTFItemDefinition *pTFDef = dynamic_cast<const CTFItemDefinition *>( pDef );
  823. if ( pTFDef )
  824. {
  825. const char *pszModel = pTFDef->GetPlayerDisplayModel(iClass);
  826. if ( pszModel && pszModel[0] )
  827. return pszModel;
  828. }
  829. }
  830. #endif // defined( TF_DLL ) || defined( TF_CLIENT_DLL )
  831. return pDef->GetBasePlayerDisplayModel();
  832. }
  833. //-----------------------------------------------------------------------------
  834. // Purpose:
  835. //-----------------------------------------------------------------------------
  836. int CEconItemView::GetSkin( int iTeam, bool bViewmodel /*= false*/ ) const
  837. {
  838. int iDefaultSkin = -1;
  839. #ifndef CSTRIKE_DLL
  840. // Immediately abort if we're out of range.
  841. if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS )
  842. return 0;
  843. // Do we have a style set?
  844. if ( GetStaticData()->GetNumStyles() )
  845. return GetStaticData()->GetStyleSkin( GetItemStyle(), iTeam, bViewmodel );
  846. iTeam = GetStaticData()->GetBestVisualTeamData( iTeam );
  847. if ( iTeam < 0 || iTeam >= TEAM_VISUAL_SECTIONS )
  848. return -1;
  849. // Do we have per-team skins set?
  850. const perteamvisuals_t *pVisData = GetStaticData()->GetPerTeamVisual( iTeam );
  851. if ( pVisData )
  852. return pVisData->iSkin;
  853. iDefaultSkin = GetItemDefinition()->GetDefaultSkin();
  854. #endif
  855. // Fallback case.
  856. return iDefaultSkin;
  857. }
  858. #ifdef CLIENT_DLL
  859. //-----------------------------------------------------------------------------
  860. // Purpose: Handle assignment for textures, which involves some reference counting shenanigans.
  861. //-----------------------------------------------------------------------------
  862. void CEconItemView::SetWeaponSkinBase( ITexture* pBaseTex )
  863. {
  864. SafeAssign( &m_pWeaponSkinBase, pBaseTex );
  865. }
  866. //-----------------------------------------------------------------------------
  867. // Purpose: Handle assignment for compositors, which involves some reference counting shenanigans.
  868. //-----------------------------------------------------------------------------
  869. void CEconItemView::SetWeaponSkinBaseCompositor( ITextureCompositor * pTexCompositor )
  870. {
  871. SafeAssign( &m_pWeaponSkinBaseCompositor, pTexCompositor );
  872. }
  873. //-----------------------------------------------------------------------------
  874. // Purpose: Cancels a pending composite, if one is currently in process.
  875. //-----------------------------------------------------------------------------
  876. void CEconItemView::CancelWeaponSkinComposite( )
  877. {
  878. SafeRelease( &m_pWeaponSkinBaseCompositor );
  879. }
  880. #endif // CLIENT_DLL
  881. //-----------------------------------------------------------------------------
  882. // Purpose:
  883. //-----------------------------------------------------------------------------
  884. const char *CEconItemView::GetWorldDisplayModel() const
  885. {
  886. CEconItemDefinition *pData = GetStaticData();
  887. if ( !pData )
  888. return NULL;
  889. return pData->GetWorldDisplayModel();
  890. }
  891. //-----------------------------------------------------------------------------
  892. // Purpose:
  893. //-----------------------------------------------------------------------------
  894. const char *CEconItemView::GetExtraWearableModel() const
  895. {
  896. CEconItemDefinition *pData = GetStaticData();
  897. if ( !pData )
  898. return NULL;
  899. return pData->GetExtraWearableModel();
  900. }
  901. const char *CEconItemView::GetExtraWearableViewModel() const
  902. {
  903. CEconItemDefinition *pData = GetStaticData();
  904. if ( !pData )
  905. return NULL;
  906. return pData->GetExtraWearableViewModel();
  907. }
  908. const char *CEconItemView::GetVisionFilteredDisplayModel() const
  909. {
  910. CEconItemDefinition *pData = GetStaticData();
  911. if ( !pData )
  912. return NULL;
  913. return pData->GetVisionFilteredDisplayModel();
  914. }
  915. //-----------------------------------------------------------------------------
  916. // Purpose:
  917. //-----------------------------------------------------------------------------
  918. int CEconItemView::GetQualityParticleType() const
  919. {
  920. static CSchemaParticleHandle pSparkleSystem( "community_sparkle" );
  921. CEconItem* pItem = GetSOCData();
  922. if ( !pItem )
  923. return 0;
  924. if( GetSOCData()->GetQuality() == AE_SELFMADE || GetSOCData()->GetQuality() == AE_COMMUNITY )
  925. return pSparkleSystem ? pSparkleSystem->nSystemID : 0;
  926. else
  927. return 0;
  928. }
  929. //-----------------------------------------------------------------------------
  930. // Purpose: Return the animation set that this item wants the player to use (ie., melee, item1, pda)
  931. //-----------------------------------------------------------------------------
  932. int CEconItemView::GetAnimationSlot( void ) const
  933. {
  934. if ( !GetStaticData() )
  935. return -1;
  936. #if defined( CSTRIKE_DLL ) || defined( DOTA_DLL )
  937. return -1;
  938. #else
  939. return GetStaticData()->GetAnimSlot();
  940. #endif
  941. }
  942. //-----------------------------------------------------------------------------
  943. // Purpose: Return an int that indicates whether the item should be dropped from a dead owner.
  944. //-----------------------------------------------------------------------------
  945. int CEconItemView::GetDropType( void )
  946. {
  947. if ( !GetStaticData() )
  948. return 0;
  949. return GetStaticData()->GetDropType();
  950. }
  951. //-----------------------------------------------------------------------------
  952. // Purpose:
  953. //-----------------------------------------------------------------------------
  954. void CEconItemView::DestroyAllAttributes( void )
  955. {
  956. m_AttributeList.DestroyAllAttributes();
  957. m_NetworkedDynamicAttributesForDemos.DestroyAllAttributes();
  958. NetworkStateChanged();
  959. MarkDescriptionDirty();
  960. }
  961. extern const char *g_EffectTypes[NUM_EFFECT_TYPES];
  962. //-----------------------------------------------------------------------------
  963. // Purpose:
  964. //-----------------------------------------------------------------------------
  965. #ifdef CLIENT_DLL
  966. const wchar_t *CEconItemView::GetItemName() const
  967. {
  968. static const wchar_t *pwzDefaultName = L"";
  969. const CEconItemDescription *pDescription = GetDescription();
  970. if ( !pDescription )
  971. return pwzDefaultName;
  972. const econ_item_description_line_t *pNameDescLine = pDescription->GetFirstLineWithMetaType( kDescLineFlag_Name );
  973. if ( !pNameDescLine )
  974. return pwzDefaultName;
  975. return pNameDescLine->sText.Get();
  976. }
  977. //-----------------------------------------------------------------------------
  978. void CEconItemView::GetRenderBounds( Vector& mins, Vector& maxs )
  979. {
  980. const CEconItemDefinition *pDef = GetStaticData();
  981. if ( !pDef )
  982. return;
  983. int iClass = 0;
  984. int iTeam = 0;
  985. #ifdef TF_CLIENT_DLL
  986. C_TFPlayer *pTFPlayer = ToTFPlayer( GetPlayerByAccountID( GetAccountID() ) );
  987. if ( pTFPlayer )
  988. {
  989. iClass = pTFPlayer->GetPlayerClass()->GetClassIndex();
  990. iTeam = pTFPlayer->GetTeamNumber();
  991. }
  992. #endif // TF_CLIENT_DLL
  993. const char * pszModel = GetPlayerDisplayModel( iClass, iTeam );
  994. if ( !pszModel )
  995. return;
  996. int iIndex = modelinfo->GetModelIndex( pszModel );
  997. if ( iIndex == -1 )
  998. {
  999. // hard load the model to get its bounds
  1000. MDLHandle_t hMDLFindResult = g_pMDLCache->FindMDL( pszModel );
  1001. MDLHandle_t hMDL = pszModel ? hMDLFindResult : MDLHANDLE_INVALID;
  1002. if ( g_pMDLCache->IsErrorModel( hMDL ) )
  1003. return;
  1004. const studiohdr_t * pStudioHdr = g_pMDLCache->GetStudioHdr( hMDL );
  1005. VectorCopy( pStudioHdr->hull_min, mins );
  1006. VectorCopy( pStudioHdr->hull_max, maxs );
  1007. g_pMDLCache->Release( hMDLFindResult );
  1008. }
  1009. else
  1010. {
  1011. const model_t *pModel = modelinfo->GetModel( iIndex );
  1012. modelinfo->GetModelRenderBounds( pModel, mins, maxs );
  1013. }
  1014. }
  1015. #endif
  1016. //-----------------------------------------------------------------------------
  1017. // Purpose:
  1018. //-----------------------------------------------------------------------------
  1019. void CEconItemView::InitNetworkedDynamicAttributesForDemos( void )
  1020. {
  1021. if ( !GetSOCData() )
  1022. return;
  1023. class CEconDynamicAttributesForDemosIterator : public CEconItemSpecificAttributeIterator
  1024. {
  1025. public:
  1026. CEconDynamicAttributesForDemosIterator( CAttributeList* out_NetworkedDynamicAttributesForDemos )
  1027. : m_NetworkedDynamicAttributesForDemos( out_NetworkedDynamicAttributesForDemos )
  1028. {
  1029. m_bAdded = false;
  1030. }
  1031. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, attrib_value_t value ) OVERRIDE
  1032. {
  1033. CEconItemAttribute attribute( pAttrDef->GetDefinitionIndex(), value );
  1034. m_NetworkedDynamicAttributesForDemos->AddAttribute( &attribute );
  1035. m_bAdded = true;
  1036. return true;
  1037. }
  1038. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float value ) OVERRIDE
  1039. {
  1040. CEconItemAttribute attribute( pAttrDef->GetDefinitionIndex(), value );
  1041. m_NetworkedDynamicAttributesForDemos->AddAttribute( &attribute );
  1042. m_bAdded = true;
  1043. return true;
  1044. }
  1045. bool BAdded( void ){ return m_bAdded; }
  1046. private:
  1047. bool m_bAdded;
  1048. CAttributeList *m_NetworkedDynamicAttributesForDemos;
  1049. };
  1050. m_NetworkedDynamicAttributesForDemos.DestroyAllAttributes();
  1051. CEconDynamicAttributesForDemosIterator it( &m_NetworkedDynamicAttributesForDemos );
  1052. IterateAttributes( &it );
  1053. if ( it.BAdded() )
  1054. {
  1055. NetworkStateChanged();
  1056. }
  1057. }
  1058. //-----------------------------------------------------------------------------
  1059. // Purpose:
  1060. //-----------------------------------------------------------------------------
  1061. static int RemapOverridePaintIndexToRGB( uint32 unIndex, uint32 unTeamIndex )
  1062. {
  1063. enum { kSamplePoints = 256, };
  1064. static uint32 k_unWitchYellow[] = {
  1065. 5328971, 5328971, 5328971, 5328971, 5328971, 5328971, 5328971, 5328971,
  1066. 5328971, 5328971, 5395018, 5591625, 5723465, 5855050, 5921095, 6052679,
  1067. 6315591, 6447429, 6513222, 6710852, 7039299, 7170884, 7433793, 7631425,
  1068. 7894336, 8222784, 8354622, 8618045, 8815420, 9078333, 9406779, 9604411,
  1069. 9802040, 10064952, 10328376, 10459959, 10722870, 11051318, 11314483, 11511859,
  1070. 11709490, 11841074, 12103729, 12301360, 12498479, 12630063, 12761901, 12959022,
  1071. 13090604, 13156651, 13288236, 13485099, 13616683, 13682474, 13748010, 13813801,
  1072. 13945386, 13945386, 14011433, 14011433, 14011433, 13945386, 13945386, 13879594,
  1073. 13814314, 13813801, 13748010, 13682474, 13616681, 13616683, 13550890, 13550890,
  1074. 13354027, 13288234, 13288236, 13222443, 13222443, 13156651, 13156651, 13025322,
  1075. 13025324, 12959531, 12893740, 12893740, 12893740, 12762413, 12696621, 12696621,
  1076. 12630828, 12630574, 12630574, 12499760, 12433713, 12433713, 12367922, 12302642,
  1077. 12302387, 12236596, 12236598, 12171575, 12105528, 12039736, 11908409, 11974204,
  1078. 11908413, 11842880, 11842880, 11842880, 11908421, 11776837, 11645765, 11579973,
  1079. 11579975, 11514182, 11448137, 11382344, 11316298, 11184712, 11053387, 11053387,
  1080. 10921802, 10855755, 10724941, 10659150, 10658896, 10527311, 10527057, 10395986,
  1081. 10330195, 10264147, 10264147, 10264149, 10263895, 10198104, 10132313, 10198106,
  1082. 10132058, 10263133, 10263133, 10328928, 10394721, 10394723, 10328675, 10394981,
  1083. 10460263, 10526056, 10329190, 10394983, 10329188, 10394723, 10328928, 10328926,
  1084. 10526042, 10526040, 10394452, 10459985, 10394446, 10460235, 10525511, 10525763,
  1085. 10657089, 10657341, 10723131, 10854456, 10920502, 11183156, 11380273, 11512111,
  1086. 11906350, 12038190, 12301100, 12629804, 12827436, 13221676, 13419306, 13616170,
  1087. 13813803, 13945386, 14077226, 13879593, 13813801, 13616170, 13485099, 13221674,
  1088. 12893227, 12630057, 12301098, 12103723, 11775018, 11511594, 11117353, 10853929,
  1089. 10459431, 10130984, 9868327, 9670182, 9472807, 9275686, 9013027, 8815396,
  1090. 8618019, 8420385, 8289569, 8223006, 8026399, 7894813, 7763484, 7829020,
  1091. 7763738, 7894810, 7960857, 8158234, 8552475, 8684059, 8881690, 9079324,
  1092. 9210908, 9407772, 9605405, 9671198, 9736989, 9736989, 9736991, 9605918,
  1093. 9473565, 9341979, 9078809, 8684059, 8355096, 7763224, 7434010, 6973206,
  1094. 6447895, 6118679, 5723416, 5394715, 5131549, 5000483, 5000234, 4999981,
  1095. 5000242, 4999990, 4868407, 4671291, 4539707, 4539709, 4605502, 4671041,
  1096. 4868420, 5000006, 5065799, 5131592, 5197385, 5263178, 5328971, 5263178,
  1097. };
  1098. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unWitchYellow ) == kSamplePoints );
  1099. static uint32 k_unDistinctiveLackOfSanity[] =
  1100. {
  1101. 5720667, 5720667, 5786460, 5720667, 5786460, 5786460, 5851996, 5851741,
  1102. 6048606, 6048606, 6114145, 6114145, 6245474, 6311013, 6311013, 6441829,
  1103. 6507624, 6573417, 6704491, 6704491, 6704493, 6901359, 6901359, 7097970,
  1104. 7097970, 7163252, 7229045, 7294840, 7425656, 7491449, 7622523, 7688062,
  1105. 7819137, 7950209, 8147077, 8277894, 8409226, 8540301, 8540303, 8671376,
  1106. 8737171, 8737171, 8867985, 8671376, 8671374, 8540301, 8475019, 8475273,
  1107. 8278408, 8147334, 8082309, 7885441, 7819902, 7754366, 7754621, 7558012,
  1108. 7492217, 7426937, 7361142, 7164533, 7164531, 7164529, 7033456, 6967663,
  1109. 6902382, 6836587, 6771564, 6771564, 6639978, 6574185, 6640232, 6508903,
  1110. 6443110, 6574439, 6443110, 6442599, 6442599, 6573415, 6508392, 6573417,
  1111. 6507624, 6572905, 6572905, 6572907, 6638187, 6703212, 6768494, 6834289,
  1112. 6965105, 6964850, 7030132, 7029621, 7226486, 7160439, 7225720, 7356538,
  1113. 7421820, 7421820, 7487102, 7617920, 7617921, 7748226, 7814021, 7879303,
  1114. 7944328, 7944330, 8074635, 8271500, 8271246, 8336527, 8336529, 8598420,
  1115. 8532629, 8597911, 8794521, 8859803, 8859803, 8990878, 9121440, 9120928,
  1116. 9317793, 9317539, 9382823, 9448103, 9513898, 9644714, 9709995, 9840813,
  1117. 9840815, 9906095, 9971890, 9971378, 10102194, 10167989, 10233269, 10364085,
  1118. 10364087, 10363833, 10429369, 10429114, 10560186, 10625725, 10625468, 10691007,
  1119. 10691007, 10756543, 10756289, 10756289, 10756289, 10756289, 10691007, 10625214,
  1120. 10625468, 10559932, 10560186, 10429114, 10363576, 10298040, 10232501, 10101429,
  1121. 10101683, 9970608, 9970608, 9773998, 9773998, 9642923, 9511848, 9511848,
  1122. 9381030, 9381030, 9249956, 9053345, 8987806, 8922270, 8856731, 8725656,
  1123. 8594839, 8463510, 8397971, 8201360, 8070287, 8070285, 7939211, 7807625,
  1124. 7676805, 7545732, 7479937, 7283582, 7152508, 7086972, 6890361, 6759029,
  1125. 6627700, 6496882, 6366064, 6300269, 6169194, 6103399, 5840997, 5775716,
  1126. 5513312, 5448030, 5251162, 5054551, 5054806, 4857684, 4661073, 4595534,
  1127. 4398666, 4267337, 4136776, 4070981, 4005186, 3874111, 3677502, 3480634,
  1128. 3414840, 3283767, 3152951, 3152949, 3153203, 3153203, 3153460, 3153460,
  1129. 3219253, 3285046, 3350839, 3416632, 3482425, 3614011, 3811133, 3942465,
  1130. 4008260, 4336455, 4533321, 4664908, 4730701, 4993362, 5124948, 5256536,
  1131. 5650013, 5781599, 6044003, 6175589, 6306920, 6504042, 6701167, 6898035,
  1132. 7029621, 7292279, 7489404, 7686526, 7752064, 8014722, 8080261, 8277127,
  1133. };
  1134. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unDistinctiveLackOfSanity ) == kSamplePoints );
  1135. static uint32 k_unOverabundanceOfRottingFlesh[] =
  1136. {
  1137. 12703514, 12703514, 12703514, 12703516, 12703516, 12703514, 12572700, 12506907,
  1138. 12506907, 12506652, 12506907, 12506907, 12506652, 12506652, 12506907, 12506652,
  1139. 12506652, 12506652, 12506654, 12506654, 12440861, 12441374, 12441374, 12375581,
  1140. 12375581, 12375583, 12375583, 12375583, 12375583, 12309536, 12309536, 12309536,
  1141. 12309536, 12309537, 12112928, 12243744, 12243744, 12177697, 12046881, 12046881,
  1142. 11981090, 11915299, 11915299, 11915044, 11915044, 11849253, 11783206, 11783206,
  1143. 11717415, 11717417, 11651624, 11585576, 11519785, 11519787, 11453994, 11388460,
  1144. 11387948, 11256621, 11190830, 11190832, 11124785, 11058993, 11058995, 10992948,
  1145. 10992950, 10861364, 10795572, 10729527, 10729527, 10663736, 10597690, 10466106,
  1146. 10466106, 10465852, 10400062, 10334015, 10202431, 10202433, 10136640, 10136385,
  1147. 10004801, 10004803, 10004549, 9938243, 10004037, 9938244, 9938246, 9872199,
  1148. 9937478, 9937224, 9871431, 9871433, 9871433, 9805640, 9870921, 9805128,
  1149. 9805128, 9805128, 9805128, 9805128, 9739337, 9804360, 9804360, 9804360,
  1150. 9804360, 9804360, 9869640, 9869640, 9803847, 9803847, 9803847, 9803847,
  1151. 9738054, 9803334, 9737541, 9672261, 9672261, 9672261, 9606468, 9606470,
  1152. 9606470, 9540677, 9475397, 9475397, 9409604, 9409604, 9212739, 9212741,
  1153. 9212741, 9146948, 9081668, 9081668, 8950596, 8950596, 9015875, 9015875,
  1154. 9081668, 9081668, 9081664, 8950850, 8950848, 8885568, 8819775, 8951359,
  1155. 8950846, 9016894, 9016892, 9016892, 9016890, 9147962, 9016376, 9147958,
  1156. 9082165, 9213494, 9081907, 9147698, 9147698, 9278768, 9212975, 9212973,
  1157. 9212716, 9278508, 9212713, 9212456, 9343272, 9212454, 9343524, 9343011,
  1158. 9277218, 9408034, 9342241, 9407523, 9341730, 9341730, 9341219, 9275426,
  1159. 9406242, 9339938, 9339938, 9339171, 9273380, 9272613, 9272613, 9141030,
  1160. 9206310, 9140519, 9140265, 9205290, 9138985, 9138985, 9138987, 9073453,
  1161. 9007662, 9007150, 9007150, 9137968, 9072945, 8941618, 9138484, 9007413,
  1162. 9138999, 9204788, 9270581, 9205556, 9271604, 9272115, 9469490, 9404210,
  1163. 9536049, 9536817, 9603119, 9734960, 9866542, 9801772, 9999147, 9999913,
  1164. 10197288, 10263848, 10264613, 10462244, 10462754, 10463776, 10661152, 10792988,
  1165. 10859547, 10991642, 11057688, 11190040, 11256086, 11388435, 11520274, 11521042,
  1166. 11652625, 11784463, 11784974, 11916813, 11916813, 11982604, 12048397, 12114188,
  1167. 12179981, 12246028, 12246028, 12311308, 12311308, 12311308, 12311308, 12377101,
  1168. 12377101, 12377101, 12377101, 12377101, 12377101, 12377101, 12377101, 12377101,
  1169. };
  1170. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unOverabundanceOfRottingFlesh ) == kSamplePoints );
  1171. // orange_flash
  1172. static uint32 k_unTheFlamesBelow[] =
  1173. {
  1174. 11548953, 11614745, 11746074, 11877659, 12008987, 12140572, 12337693, 12469278,
  1175. 12666655, 12863776, 13060897, 13258274, 13455395, 13652772, 13849893, 14047014,
  1176. 14244391, 14375976, 14573097, 14704681, 14836010, 14967595, 15033387, 15164716,
  1177. 15164972, 15230508, 15230508, 15230508, 15164716, 15033387, 14967595, 14836010,
  1178. 14638889, 14507304, 14310183, 14112806, 13915685, 13718308, 13455651, 13258274,
  1179. 13060897, 12863776, 12666399, 12469278, 12272157, 12075036, 11943451, 11811866,
  1180. 11680538, 11614745, 11548953, 11548953, 11548953, 11614745, 11680538, 11746330,
  1181. 11877659, 12009244, 12206364, 12403485, 12600862, 12797983, 12995360, 13192482,
  1182. 13389859, 13652772, 13849893, 14047270, 14244391, 14441512, 14638889, 14770474,
  1183. 14901802, 15033387, 15099179, 15164972, 15230508, 15230508, 15098924, 14835755,
  1184. 14572586, 14177832, 13783078, 13322789, 12862755, 12468001, 12139295, 11811101,
  1185. 11614491, 11548954, 11549209, 11747351, 12011542, 12407317, 12869139, 13396754,
  1186. 13924369, 14451983, 14979598, 15506957, 15902989, 16298508, 16562443, 16759819,
  1187. 16760075, 16562188, 16166669, 15704590, 15110927, 14451217, 13791507, 13132053,
  1188. 12538390, 12011032, 11681049, 11548953, 11614745, 11812888, 12142615, 12538646,
  1189. 13066005, 13593875, 14187538, 14780944, 15308815, 15836430, 16232204, 16561932,
  1190. 16694283, 16760075, 16561932, 16100621, 15506958, 14846992, 14121490, 13395732,
  1191. 12670486, 12142359, 11746585, 11548953, 11614745, 11812632, 12076824, 12472343,
  1192. 12934165, 13395988, 13923859, 14517265, 15044880, 15506702, 15968269, 16298508,
  1193. 16562187, 16759819, 16760075, 16627979, 16298508, 15902733, 15375374, 14781967,
  1194. 14188560, 13594897, 13066771, 12539156, 12077334, 11747351, 11549209, 11548954,
  1195. 11680028, 11876637, 12139295, 12533793, 12928291, 13323045, 13783335, 14178088,
  1196. 14572586, 14836011, 15098924, 15230508, 15230508, 15164972, 15099179, 15033387,
  1197. 14901802, 14770474, 14638889, 14441768, 14244391, 14047270, 13849893, 13652772,
  1198. 13455395, 13192482, 12995360, 12797983, 12600862, 12403485, 12206364, 12074780,
  1199. 11877659, 11746330, 11680538, 11614745, 11548953, 11548953, 11548953, 11614745,
  1200. 11680538, 11811866, 11943451, 12075036, 12272157, 12403742, 12600863, 12863776,
  1201. 13060897, 13258274, 13455395, 13718308, 13915685, 14112806, 14310183, 14507304,
  1202. 14638889, 14836010, 14967339, 15033387, 15164716, 15230508, 15230508, 15230508,
  1203. 15164972, 15164716, 15033387, 14967595, 14836010, 14704681, 14573097, 14375976,
  1204. 14244391, 14047014, 13849893, 13652772, 13455395, 13258274, 13060897, 12863776,
  1205. 12666655, 12469278, 12337693, 12140572, 12008987, 11877659, 11746074, 11614745,
  1206. };
  1207. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unTheFlamesBelow ) == kSamplePoints );
  1208. // green_pulse
  1209. static uint32 k_unThatQueesyFeeling[] =
  1210. {
  1211. 7439904, 7571489, 7703329, 7900706, 8032547, 8295716, 8493349, 8756518,
  1212. 9019943, 9283369, 9546794, 9810219, 10073644, 10402606, 10666031, 10929200,
  1213. 11192625, 11390259, 11653428, 11851061, 12048437, 12180278, 12312119, 12443703,
  1214. 12509496, 12575288, 12575288, 12509496, 12443703, 12312119, 12180278, 11982901,
  1215. 11785268, 11522099, 11258674, 10995249, 10731823, 10468398, 10139181, 9810219,
  1216. 9546794, 9217576, 8954151, 8690726, 8427557, 8229924, 7966755, 7834914,
  1217. 7637537, 7571488, 7440160, 7439904, 7439904, 7505696, 7637281, 7769121,
  1218. 7900962, 8098339, 8361508, 8624933, 8888359, 9151784, 9415209, 9744171,
  1219. 10073388, 10336814, 10666031, 10929456, 11192882, 11456051, 11719476, 11982645,
  1220. 12114486, 12311863, 12443447, 12509496, 12575288, 12575288, 12509496, 12443703,
  1221. 12311863, 12180278, 11982645, 11785012, 11521843, 11258674, 10995249, 10731823,
  1222. 10402862, 10139181, 9810219, 9546794, 9283368, 8954151, 8690982, 8427557,
  1223. 8229924, 8032291, 7834914, 7703073, 7571489, 7505696, 7439904, 7439904,
  1224. 7505696, 7571745, 7703329, 7900706, 8098083, 8295716, 8559141, 8822310,
  1225. 9085736, 9349161, 9678378, 9941804, 10270765, 10534447, 10863408, 11126833,
  1226. 11390258, 11653428, 11851061, 12048694, 12246070, 12377911, 12509240, 12575288,
  1227. 12575288, 12575288, 12509240, 12377911, 12246070, 12048694, 11851061, 11653428,
  1228. 11390258, 11126833, 10863408, 10534447, 10270765, 9941804, 9678378, 9349161,
  1229. 9085736, 8822310, 8559141, 8295716, 8098083, 7900706, 7703329, 7571745,
  1230. 7505696, 7439904, 7439904, 7505696, 7571489, 7703073, 7834914, 8032291,
  1231. 8229924, 8427557, 8690982, 8954151, 9283368, 9546794, 9810219, 10139181,
  1232. 10402862, 10731823, 10995249, 11258674, 11521843, 11785012, 11982645, 12180278,
  1233. 12311863, 12443703, 12509496, 12575288, 12575288, 12509496, 12443447, 12311863,
  1234. 12180022, 11982645, 11719476, 11521843, 11258418, 10929456, 10666031, 10336814,
  1235. 10073388, 9744427, 9480745, 9151784, 8888359, 8624933, 8361508, 8163875,
  1236. 7900962, 7769121, 7637281, 7505696, 7439904, 7439904, 7440160, 7571488,
  1237. 7637537, 7834914, 7966755, 8164132, 8427557, 8690726, 8954151, 9217576,
  1238. 9546538, 9810219, 10139181, 10402606, 10731823, 10995249, 11258674, 11521843,
  1239. 11785268, 11982645, 12180278, 12312119, 12443703, 12509496, 12575288, 12575288,
  1240. 12509496, 12443703, 12312119, 12180278, 12048437, 11851061, 11653428, 11390259,
  1241. 11192625, 10929200, 10666031, 10402606, 10073644, 9810219, 9546794, 9283369,
  1242. 9019943, 8756518, 8493349, 8295716, 8032547, 7900706, 7703329, 7571489,
  1243. };
  1244. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unThatQueesyFeeling ) == kSamplePoints );
  1245. // blue_pulse
  1246. static uint32 k_unBubbleBubble[] =
  1247. {
  1248. 9094364, 9160156, 9291485, 9357278, 9488607, 9685472, 9816801, 10013922,
  1249. 10145251, 10342372, 10539237, 10736358, 10933479, 11130345, 11327466, 11458795,
  1250. 11655916, 11852781, 11984366, 12115695, 12247024, 12378352, 12444145, 12509681,
  1251. 12575474, 12641010, 12641010, 12575474, 12509681, 12444145, 12312816, 12181487,
  1252. 12049902, 11853037, 11655916, 11458795, 11261930, 11064808, 10802151, 10605030,
  1253. 10407908, 10211043, 10013922, 9816801, 9619936, 9488607, 9357022, 9225693,
  1254. 9160156, 9094364, 9094364, 9094364, 9159900, 9225693, 9357022, 9553886,
  1255. 9751008, 9948129, 10210786, 10473444, 10736102, 11064551, 11392745, 11655659,
  1256. 11983853, 12312303, 12640496, 12903410, 13166068, 13494262, 13691383, 13954040,
  1257. 14150905, 14282490, 14413819, 14545148, 14545148, 14545148, 14545148, 14413819,
  1258. 14282490, 14151162, 13954040, 13756919, 13494262, 13231604, 12968947, 12706289,
  1259. 12377839, 12115181, 11786732, 11458538, 11195880, 10867430, 10604773, 10342115,
  1260. 10079458, 9816800, 9619679, 9422814, 9291485, 9160156, 9094364, 9094364,
  1261. 9094364, 9094364, 9160157, 9291485, 9422814, 9554143, 9685472, 9882593,
  1262. 10079458, 10276579, 10473701, 10736358, 10933479, 11130345, 11327466, 11590123,
  1263. 11787245, 11918574, 12115695, 12247024, 12378352, 12509681, 12575218, 12641010,
  1264. 12641010, 12641010, 12575218, 12509681, 12378352, 12247024, 12115695, 11918574,
  1265. 11787245, 11590123, 11327466, 11130345, 10933479, 10736358, 10473701, 10276579,
  1266. 10079458, 9882593, 9685472, 9554143, 9422814, 9291485, 9160157, 9094364,
  1267. 9094364, 9094364, 9094364, 9160156, 9291485, 9422814, 9619679, 9816800,
  1268. 10079458, 10342115, 10604773, 10867430, 11195880, 11458538, 11786732, 12115181,
  1269. 12377839, 12706289, 12968947, 13231604, 13494262, 13756919, 13954040, 14151162,
  1270. 14282490, 14413819, 14545148, 14545148, 14545148, 14545148, 14413819, 14282490,
  1271. 14150905, 13954040, 13691383, 13494262, 13231604, 12903410, 12640497, 12312303,
  1272. 11983853, 11721195, 11392745, 11064551, 10801638, 10473444, 10210786, 9948129,
  1273. 9751008, 9553887, 9357022, 9225693, 9159900, 9094364, 9094364, 9094364,
  1274. 9160156, 9225693, 9357022, 9488351, 9619935, 9816801, 10013922, 10210787,
  1275. 10407908, 10605030, 10802151, 11064808, 11261674, 11458795, 11655916, 11853037,
  1276. 12049902, 12181231, 12312560, 12443889, 12575217, 12641010, 12641010, 12641010,
  1277. 12575474, 12575217, 12509681, 12378352, 12247024, 12115695, 11984366, 11852781,
  1278. 11655916, 11524331, 11327466, 11130345, 10933479, 10736358, 10539237, 10342372,
  1279. 10145251, 10013922, 9816801, 9685472, 9554143, 9422814, 9291485, 9160156,
  1280. };
  1281. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unBubbleBubble ) == kSamplePoints );
  1282. // purple_orange_rand
  1283. static uint32 k_unAfraidOfShadowsDark[] =
  1284. {
  1285. 4536928, 4536928, 4602721, 4602721, 4668515, 4668515, 4734308, 4734308,
  1286. 4734308, 4734309, 4734309, 4734309, 4865896, 4865896, 4931689, 4931689,
  1287. 4997226, 4997226, 5063019, 5063019, 5128813, 5194606, 5194607, 5260400,
  1288. 5260400, 5391730, 5457523, 5457524, 5457524, 5523317, 5589111, 5654904,
  1289. 5654905, 5654905, 5720698, 5852028, 5917821, 5917822, 5983615, 5983615,
  1290. 6115202, 6115202, 6115203, 6180996, 6312326, 6378119, 6378120, 6443913,
  1291. 6444683, 6576785, 6577556, 6709913, 6710941, 6843555, 6844583, 6845868,
  1292. 6912945, 6914230, 6915515, 6982592, 6983877, 6985161, 6986446, 6987986,
  1293. 6989014, 6924762, 6926046, 6926817, 6862308, 6863079, 6863593, 6798827,
  1294. 6799597, 6799083, 6929385, 6863079, 6927845, 6992866, 7057632, 7187677,
  1295. 7252442, 7382487, 7447251, 7577296, 7641805, 7772362, 7836871, 7967172,
  1296. 8097473, 8227774, 8292283, 8422841, 8487607, 8749750, 8814516, 8879794,
  1297. 8945072, 9075888, 8946614, 8752575, 8427464, 8102353, 7842008, 7647197,
  1298. 7582176, 7842777, 8233938, 8559562, 8950979, 9277117, 9537977, 9733814,
  1299. 9734070, 9734070, 9734070, 9734070, 9734071, 9799863, 9799863, 9799863,
  1300. 9799863, 9799863, 9799863, 9799863, 9799863, 9799604, 9799863, 9799604,
  1301. 9799344, 9733548, 9733032, 9732771, 9732509, 9731992, 9731473, 9731211,
  1302. 9796485, 9861502, 9861239, 9926256, 10057321, 10122338, 10253403, 10450004,
  1303. 10580557, 10777414, 10974016, 11235897, 11432754, 11629612, 11825958, 12088353,
  1304. 12350747, 12547606, 12875538, 13072654, 13203723, 13531656, 13729032, 13729032,
  1305. 13794568, 13991688, 14188808, 14254344, 14385672, 14451464, 14648328, 14845704,
  1306. 14977032, 15108360, 15239689, 15436809, 15568393, 15831050, 15962892, 16160781,
  1307. 16226832, 16293140, 16294170, 16294943, 16295713, 16296229, 16297257, 16363566,
  1308. 16364595, 16365365, 16431930, 16432957, 16433729, 16500037, 16501065, 16501836,
  1309. 16502864, 16503634, 16569685, 16570712, 16571482, 16637789, 16638303, 16639072,
  1310. 16639586, 16640355, 16640869, 16707173, 16707430, 16707943, 16708456, 16708712,
  1311. 16709224, 16775016, 16775272, 16775784, 16776040, 16776552, 16776295, 16776551,
  1312. 16776551, 16776039, 16709991, 16709736, 16709224, 16511336, 16247913, 16116074,
  1313. 15786858, 15457899, 15193963, 14865004, 14601837, 14206573, 13811822, 13351022,
  1314. 12890479, 12429935, 11969392, 11508591, 11048049, 10587504, 10192752, 9732208,
  1315. 9337455, 8877166, 8482670, 8153453, 7758957, 7430252, 7101291, 6772586,
  1316. 6509418, 6246505, 5983337, 5786216, 5588840, 5391719, 5194599, 5063014,
  1317. };
  1318. COMPILE_TIME_ASSERT( ARRAYSIZE( k_unAfraidOfShadowsDark ) == kSamplePoints );
  1319. static uint32 *k_pPointSampleContent_Team0[] =
  1320. {
  1321. &k_unWitchYellow[0],
  1322. &k_unDistinctiveLackOfSanity[0],
  1323. &k_unOverabundanceOfRottingFlesh[0],
  1324. &k_unTheFlamesBelow[0],
  1325. &k_unThatQueesyFeeling[0],
  1326. &k_unAfraidOfShadowsDark[0],
  1327. };
  1328. static uint32 *k_pPointSampleContent_Team1[] =
  1329. {
  1330. &k_unWitchYellow[0],
  1331. &k_unDistinctiveLackOfSanity[0],
  1332. &k_unOverabundanceOfRottingFlesh[0],
  1333. &k_unBubbleBubble[0],
  1334. &k_unThatQueesyFeeling[0],
  1335. &k_unAfraidOfShadowsDark[0],
  1336. };
  1337. COMPILE_TIME_ASSERT( ARRAYSIZE( k_pPointSampleContent_Team0 ) == ARRAYSIZE( k_pPointSampleContent_Team1 ) );
  1338. if ( unIndex >= ARRAYSIZE( k_pPointSampleContent_Team0 ) )
  1339. return 0;
  1340. if ( unTeamIndex > 1 )
  1341. return 0;
  1342. const float fScaledTime = gpGlobals->curtime * 22.0f; // arbitrary time scalar people liked
  1343. const unsigned int unSamplePoint0 = (unsigned int)fScaledTime % kSamplePoints;
  1344. const unsigned int unSamplePoint1 = (unSamplePoint0 + 1) % kSamplePoints;
  1345. const float fDelta = fScaledTime - (unsigned int)fScaledTime; // offset between two sample points for blending
  1346. const uint32 *punData = (unTeamIndex == 0 ? k_pPointSampleContent_Team0 : k_pPointSampleContent_Team1)[unIndex];
  1347. Color c0;
  1348. c0.SetRawColor( punData[unSamplePoint0] );
  1349. Color c1;
  1350. c1.SetRawColor( punData[unSamplePoint1] );
  1351. const Color cBlend( Lerp( fDelta, c0.r(), c1.r() ),
  1352. Lerp( fDelta, c0.g(), c1.g() ),
  1353. Lerp( fDelta, c0.b(), c1.b() ) );
  1354. return cBlend.GetRawColor();
  1355. }
  1356. //-----------------------------------------------------------------------------
  1357. // Purpose: Get RGB modifying attribute value
  1358. //-----------------------------------------------------------------------------
  1359. int CEconItemView::GetModifiedRGBValue( bool bAltColor )
  1360. {
  1361. enum
  1362. {
  1363. kPaintConstant_Default = 0,
  1364. kPaintConstant_OldTeamColor = 1,
  1365. };
  1366. static CSchemaAttributeDefHandle pAttr_Paint( "set item tint rgb" );
  1367. static CSchemaAttributeDefHandle pAttr_Paint2( "set item tint rgb 2" );
  1368. static CSchemaAttributeDefHandle pAttr_PaintOverride( "SPELL: set item tint RGB" );
  1369. // Do we have an override paint color? This takes precedence over base paints and team
  1370. // paints.
  1371. #if defined( TF_DLL ) || defined( TF_CLIENT_DLL )
  1372. extern bool TF_IsHolidayActive( /*EHoliday*/ int eHoliday );
  1373. if ( TF_IsHolidayActive( kHoliday_HalloweenOrFullMoon ) )
  1374. #endif // defined( TF_DLL ) || defined( TF_CLIENT_DLL )
  1375. {
  1376. if ( !m_bPaintOverrideInit )
  1377. {
  1378. m_bHasPaintOverride = FindAttribute_UnsafeBitwiseCast<attrib_value_t>( this, pAttr_PaintOverride, &m_flOverrideIndex );
  1379. m_bPaintOverrideInit = true;
  1380. }
  1381. if ( m_bHasPaintOverride )
  1382. return RemapOverridePaintIndexToRGB( (uint32)m_flOverrideIndex, bAltColor ? 1 : 0 );
  1383. }
  1384. if ( !m_bColorInit )
  1385. {
  1386. // See if we also have a secondary paint color.
  1387. uint32 unRGB = kPaintConstant_Default;
  1388. uint32 unRGBAlt = kPaintConstant_Default;
  1389. float fRGB;
  1390. float fRGBAlt;
  1391. // If we have no base paint color we don't do anything special.
  1392. if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( this, pAttr_Paint, &fRGB ) )
  1393. {
  1394. unRGB = (uint32)fRGB;
  1395. unRGBAlt = unRGB;
  1396. }
  1397. // Backwards compatibility for old team colored items.
  1398. if ( unRGB == kPaintConstant_OldTeamColor )
  1399. {
  1400. unRGB = RGB_INT_RED;
  1401. unRGBAlt = RGB_INT_BLUE;
  1402. }
  1403. else if ( FindAttribute_UnsafeBitwiseCast<attrib_value_t>( this, pAttr_Paint2, &fRGBAlt ) )
  1404. {
  1405. unRGBAlt = (uint32)fRGBAlt;
  1406. }
  1407. else
  1408. {
  1409. // By default our secondary color will match our primary if we can't find a replacement.
  1410. unRGBAlt = unRGB;
  1411. }
  1412. m_unRGB = unRGB;
  1413. m_unAltRGB = unRGBAlt;
  1414. m_bColorInit = true;
  1415. }
  1416. return bAltColor ? m_unAltRGB : m_unRGB;
  1417. }
  1418. uint64 CEconItemView::GetCustomUserTextureID()
  1419. {
  1420. static CSchemaAttributeDefHandle pAttr_CustomTextureLo( "custom texture lo" );
  1421. static CSchemaAttributeDefHandle pAttr_CustomTextureHi( "custom texture hi" );
  1422. uint32 unLowVal, unHighVal;
  1423. const bool bHasLowVal = FindAttribute( pAttr_CustomTextureLo, &unLowVal ),
  1424. bHasHighVal = FindAttribute( pAttr_CustomTextureHi, &unHighVal );
  1425. // We should have both, or neither. We should never have just one
  1426. Assert( bHasLowVal == bHasHighVal );
  1427. if ( bHasLowVal && bHasHighVal )
  1428. {
  1429. return ((uint64)unHighVal << 32) | (uint64)unLowVal;
  1430. }
  1431. // No attribute set
  1432. return 0;
  1433. }
  1434. //-----------------------------------------------------------------------------
  1435. // Purpose:
  1436. //-----------------------------------------------------------------------------
  1437. CAttributeList::CAttributeList()
  1438. {
  1439. m_pManager = NULL;
  1440. m_Attributes.Purge();
  1441. }
  1442. //-----------------------------------------------------------------------------
  1443. // Purpose:
  1444. //-----------------------------------------------------------------------------
  1445. void CAttributeList::SetManager( CAttributeManager *pManager )
  1446. {
  1447. m_pManager = pManager;
  1448. }
  1449. //-----------------------------------------------------------------------------
  1450. // Purpose:
  1451. //-----------------------------------------------------------------------------
  1452. void CAttributeList::Init()
  1453. {
  1454. m_Attributes.Purge();
  1455. }
  1456. //-----------------------------------------------------------------------------
  1457. // Purpose:
  1458. //-----------------------------------------------------------------------------
  1459. void CAttributeList::IterateAttributes( class IEconItemAttributeIterator *pIterator ) const
  1460. {
  1461. Assert( pIterator );
  1462. FOR_EACH_VEC( m_Attributes, i )
  1463. {
  1464. const CEconItemAttribute *pAttrInst = &m_Attributes[i];
  1465. const CEconItemAttributeDefinition *pAttrDef = pAttrInst->GetStaticData();
  1466. if ( !pAttrDef )
  1467. continue;
  1468. const ISchemaAttributeType *pAttrType = pAttrDef->GetAttributeType();
  1469. Assert( pAttrType );
  1470. Assert( pAttrType->BSupportsGameplayModificationAndNetworking() );
  1471. // We know (and assert) that we only need 32 bits of data to store this attribute
  1472. // data. We don't know anything about the type but we'll let the type handle it
  1473. // below.
  1474. attribute_data_union_t value;
  1475. value.asFloat = pAttrInst->m_flValue;
  1476. if ( !pAttrType->OnIterateAttributeValue( pIterator, pAttrDef, value ) )
  1477. return;
  1478. }
  1479. }
  1480. //-----------------------------------------------------------------------------
  1481. // Purpose:
  1482. //-----------------------------------------------------------------------------
  1483. void CAttributeList::DestroyAllAttributes( void )
  1484. {
  1485. if ( m_Attributes.Count() )
  1486. {
  1487. m_Attributes.Purge();
  1488. NotifyManagerOfAttributeValueChanges();
  1489. NetworkStateChanged();
  1490. }
  1491. }
  1492. //-----------------------------------------------------------------------------
  1493. // Purpose:
  1494. //-----------------------------------------------------------------------------
  1495. void CAttributeList::AddAttribute( CEconItemAttribute *pAttribute )
  1496. {
  1497. Assert( pAttribute );
  1498. // Only add attributes to the attribute list if they have a definition we can
  1499. // pull data from.
  1500. if ( !pAttribute->GetStaticData() )
  1501. return;
  1502. m_Attributes.AddToTail( *pAttribute );
  1503. NetworkStateChanged();
  1504. NotifyManagerOfAttributeValueChanges();
  1505. }
  1506. //-----------------------------------------------------------------------------
  1507. // Purpose:
  1508. //-----------------------------------------------------------------------------
  1509. void CAttributeList::SetRuntimeAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float flValue )
  1510. {
  1511. Assert( pAttrDef );
  1512. // Look for an existing attribute.
  1513. const int iAttributes = GetNumAttributes();
  1514. for ( int i = 0; i < iAttributes; i++ )
  1515. {
  1516. CEconItemAttribute *pAttribute = GetAttribute(i);
  1517. if ( pAttribute->GetAttribIndex() == pAttrDef->GetDefinitionIndex() )
  1518. {
  1519. // Found existing attribute -- change value.
  1520. pAttribute->m_flValue = flValue;
  1521. NotifyManagerOfAttributeValueChanges();
  1522. return;
  1523. }
  1524. }
  1525. // Couldn't find an existing attribute for this definition -- make a new one.
  1526. CEconItemAttribute attribute;
  1527. attribute.m_iAttributeDefinitionIndex = pAttrDef->GetDefinitionIndex();
  1528. attribute.m_flValue = flValue;
  1529. m_Attributes.AddToTail( attribute );
  1530. NotifyManagerOfAttributeValueChanges();
  1531. }
  1532. #if ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  1533. //-----------------------------------------------------------------------------
  1534. // Purpose:
  1535. //-----------------------------------------------------------------------------
  1536. void CAttributeList::SetRuntimeAttributeRefundableCurrency( const CEconItemAttributeDefinition *pAttrDef, int iRefundableCurrency )
  1537. {
  1538. Assert( pAttrDef );
  1539. // Look for an existing attribute.
  1540. const int iAttributes = GetNumAttributes();
  1541. for ( int i = 0; i < iAttributes; i++ )
  1542. {
  1543. CEconItemAttribute *pAttribute = GetAttribute(i);
  1544. if ( pAttribute->GetAttribIndex() == pAttrDef->GetDefinitionIndex() )
  1545. {
  1546. // Found existing attribute -- change value.
  1547. pAttribute->m_nRefundableCurrency = iRefundableCurrency;
  1548. return;
  1549. }
  1550. }
  1551. AssertMsg1( false, "Unable to find attribute '%s' for setting currency!", pAttrDef->GetDefinitionName() );
  1552. }
  1553. //-----------------------------------------------------------------------------
  1554. // Purpose:
  1555. //-----------------------------------------------------------------------------
  1556. int CAttributeList::GetRuntimeAttributeRefundableCurrency( const CEconItemAttributeDefinition *pAttrDef ) const
  1557. {
  1558. const int iAttributes = GetNumAttributes();
  1559. for ( int i = 0; i < iAttributes; i++ )
  1560. {
  1561. const CEconItemAttribute *pAttribute = GetAttribute(i);
  1562. if ( pAttribute->GetAttribIndex() == pAttrDef->GetDefinitionIndex() )
  1563. return pAttribute->m_nRefundableCurrency;
  1564. }
  1565. AssertMsg1( false, "Unable to find attribute '%s' for getting currency!", pAttrDef->GetDefinitionName() );
  1566. return 0;
  1567. }
  1568. #endif // ENABLE_ATTRIBUTE_CURRENCY_TRACKING
  1569. //-----------------------------------------------------------------------------
  1570. // Purpose: Remove an attribute by name
  1571. //-----------------------------------------------------------------------------
  1572. void CAttributeList::RemoveAttribute( const CEconItemAttributeDefinition *pAttrDef )
  1573. {
  1574. const int iAttributes = m_Attributes.Count();
  1575. for ( int i = 0; i < iAttributes; i++ )
  1576. {
  1577. if ( m_Attributes[i].GetStaticData() == pAttrDef )
  1578. {
  1579. m_Attributes.Remove( i );
  1580. NotifyManagerOfAttributeValueChanges();
  1581. return;
  1582. }
  1583. }
  1584. }
  1585. //-----------------------------------------------------------------------------
  1586. // Purpose: Remove an attribute by index
  1587. //-----------------------------------------------------------------------------
  1588. void CAttributeList::RemoveAttributeByIndex( int iIndex )
  1589. {
  1590. if ( iIndex < 0 || iIndex >= GetNumAttributes() )
  1591. return;
  1592. m_Attributes.Remove( iIndex );
  1593. NotifyManagerOfAttributeValueChanges();
  1594. }
  1595. //-----------------------------------------------------------------------------
  1596. // Purpose:
  1597. //-----------------------------------------------------------------------------
  1598. const CEconItemAttribute *CAttributeList::GetAttributeByID( int iAttributeID ) const
  1599. {
  1600. int iAttributes = m_Attributes.Count();
  1601. for ( int i = 0; i < iAttributes; i++ )
  1602. {
  1603. const CEconItemAttributeDefinition *pData = m_Attributes[i].GetStaticData();
  1604. if ( pData && ( pData->GetDefinitionIndex() == iAttributeID ) )
  1605. return &m_Attributes[i];
  1606. }
  1607. return NULL;
  1608. }
  1609. //-----------------------------------------------------------------------------
  1610. // Purpose:
  1611. //-----------------------------------------------------------------------------
  1612. const CEconItemAttribute *CAttributeList::GetAttributeByName( const char *pszAttribDefName ) const
  1613. {
  1614. CEconItemAttributeDefinition *pDef = GetItemSchema()->GetAttributeDefinitionByName( pszAttribDefName );
  1615. if ( !pDef )
  1616. return NULL;
  1617. int iAttributes = m_Attributes.Count();
  1618. for ( int i = 0; i < iAttributes; i++ )
  1619. {
  1620. if ( m_Attributes[i].GetStaticData()->GetDefinitionIndex() == pDef->GetDefinitionIndex() )
  1621. return &m_Attributes[i];
  1622. }
  1623. return NULL;
  1624. }
  1625. //-----------------------------------------------------------------------------
  1626. // Purpose:
  1627. //-----------------------------------------------------------------------------
  1628. void CAttributeList::operator=( const CAttributeList& src )
  1629. {
  1630. m_Attributes = src.m_Attributes;
  1631. // HACK: We deliberately don't copy managers, because attributelists are contained inside
  1632. // CEconItemViews, which we duplicate inside CItemModelPanels all the time. If the manager
  1633. // is copied, copies will mess with the attribute caches of the copied item.
  1634. // Our manager will be setup properly by the CAttributeManager itself if we have an associated entity.
  1635. m_pManager = NULL;
  1636. }
  1637. //-----------------------------------------------------------------------------
  1638. // Purpose:
  1639. //-----------------------------------------------------------------------------
  1640. void CAttributeList::NotifyManagerOfAttributeValueChanges( void )
  1641. {
  1642. if ( m_pManager )
  1643. {
  1644. m_pManager->OnAttributeValuesChanged();
  1645. }
  1646. }
  1647. #ifdef CLIENT_DLL
  1648. //-----------------------------------------------------------------------------
  1649. // Purpose:
  1650. //-----------------------------------------------------------------------------
  1651. bool DoesItemPassSearchFilter( const IEconItemDescription *pDescription, const wchar_t* wszFilter )
  1652. {
  1653. // check if item matches name filter
  1654. if ( wszFilter && *wszFilter )
  1655. {
  1656. if ( !pDescription )
  1657. {
  1658. return false;
  1659. }
  1660. wchar_t wszBuffer[ 4096 ] = L"";
  1661. for ( unsigned int i = 0; i < pDescription->GetLineCount(); i++ )
  1662. {
  1663. const econ_item_description_line_t& line = pDescription->GetLine(i);
  1664. if ( !(line.unMetaType & ( kDescLineFlag_Collection | kDescLineFlag_CollectionCurrentItem ) ) )
  1665. {
  1666. V_wcscat_safe( wszBuffer, line.sText.Get() );
  1667. }
  1668. }
  1669. V_wcslower( wszBuffer );
  1670. if ( !wcsstr( wszBuffer, wszFilter ) )
  1671. {
  1672. return false;
  1673. }
  1674. }
  1675. return true;
  1676. }
  1677. //-----------------------------------------------------------------------------
  1678. // Purpose:
  1679. //-----------------------------------------------------------------------------
  1680. CBasePlayer *GetPlayerByAccountID( uint32 unAccountID )
  1681. {
  1682. for ( int i = 1; i <= gpGlobals->maxClients; i++ )
  1683. {
  1684. CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
  1685. if ( pPlayer == NULL )
  1686. continue;
  1687. CSteamID steamIDPlayer;
  1688. if ( !pPlayer->GetSteamID( &steamIDPlayer ) )
  1689. continue;
  1690. // return the player with the matching ID
  1691. if ( steamIDPlayer.GetAccountID() == unAccountID )
  1692. {
  1693. return pPlayer;
  1694. }
  1695. }
  1696. return NULL;
  1697. }
  1698. #endif // CLIENT_DLL