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.

546 lines
24 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: CEconItem, a shared object for econ items
  4. //
  5. //=============================================================================
  6. #ifndef ECONITEMINTERFACE_H
  7. #define ECONITEMINTERFACE_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "game_item_schema.h" // needed for GameItemDefinition_t
  12. class CAttribute_String;
  13. class CAttribute_DynamicRecipeComponent;
  14. class CAttribute_ItemSlotCriteria;
  15. class CAttribute_WorldItemPlacement;
  16. class IMaterial;
  17. //-----------------------------------------------------------------------------
  18. // Purpose: Template helper classes for dealing with types.
  19. //-----------------------------------------------------------------------------
  20. // StripConstIfPresent<T> will take an input type T and "return" via ResultType:
  21. //
  22. // - T: T
  23. // - const T: T
  24. //
  25. // This is used to prevent having to have different specializations for "T" versus
  26. // "const T" when checking for equivalent template type arguments, etc.
  27. template < typename T >
  28. struct StripConstIfPresent { typedef T ResultType; };
  29. template < typename T > struct StripConstIfPresent<const T> { typedef T ResultType; };
  30. // AreTypesIdentical<T, U> takes two input types and "returns" via kValue whether the
  31. // types are exactly equal. This is intended for checking type equivalence at compile-time
  32. // in ways that template specializations for functions/classes may not be ideal for.
  33. //
  34. // We use it in the attribute code to guarantee that we're only doing The Old, Scary Path
  35. // when dealing with attributes of The Old, Scary Type.
  36. template < typename T, typename U >
  37. struct AreTypesIdentical { enum { kValue = false }; };
  38. template < typename T > struct AreTypesIdentical<T, T> { enum { kValue = true }; };
  39. // IsPointerType<T> takes one input and "returns" via kValue whether the type is a pointer
  40. // type in any way, const, volatile, whatever.
  41. template < typename T >
  42. struct IsPointerType { enum { kValue = false }; };
  43. template < typename T > struct IsPointerType<T *> { enum { kValue = true }; };
  44. // IsValidAttributeValueTypeImpl<T> is a hand-made specialization for what types we want
  45. // to consider valid attribute data types. This is used as a sanity check to make sure we
  46. // don't pass in completely arbitrary types to things like FindAttribute(). (Doing so
  47. // would cause an assert at runtime, but it seems like getting compile-time asserts is
  48. // advantageous, and probably worth paying the small cost of adding to this list whenever
  49. // a new attribute type is added.)
  50. template < typename T>
  51. struct IsValidAttributeValueTypeImpl { enum { kValue = false }; };
  52. template < > struct IsValidAttributeValueTypeImpl<attrib_value_t> { enum { kValue = true }; };
  53. template < > struct IsValidAttributeValueTypeImpl<float> { enum { kValue = true }; };
  54. template < > struct IsValidAttributeValueTypeImpl<uint64> { enum { kValue = true }; };
  55. template < > struct IsValidAttributeValueTypeImpl<CAttribute_String> { enum { kValue = true }; };
  56. template < > struct IsValidAttributeValueTypeImpl<CAttribute_DynamicRecipeComponent> { enum { kValue = true }; };
  57. template < > struct IsValidAttributeValueTypeImpl < CAttribute_ItemSlotCriteria > { enum { kValue = true }; };
  58. template < > struct IsValidAttributeValueTypeImpl < CAttribute_WorldItemPlacement > { enum { kValue = true }; };
  59. template < typename T >
  60. struct IsValidAttributeValueType : public IsValidAttributeValueTypeImpl< typename StripConstIfPresent<T>::ResultType > { };
  61. //-----------------------------------------------------------------------------
  62. // Purpose: Interface for callback functions per-attribute-data-type. When adding
  63. // a new attribute data type that can't be converted to any existing type,
  64. // you'll need to add a new virtual function here or the code will fail
  65. // to compile.
  66. //-----------------------------------------------------------------------------
  67. class IEconItemAttributeIterator
  68. {
  69. public:
  70. virtual ~IEconItemAttributeIterator ( ) { }
  71. // Returns whether to continue iteration after this element.
  72. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, attrib_value_t value ) = 0;
  73. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float value ) = 0;
  74. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const uint64& value ) = 0;
  75. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_String& value ) = 0;
  76. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_DynamicRecipeComponent& value ) = 0;
  77. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_ItemSlotCriteria& value ) = 0;
  78. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_WorldItemPlacement& value ) = 0;
  79. };
  80. //-----------------------------------------------------------------------------
  81. // Purpose: Iterator where each callback is default implemented, but the value
  82. // is ignored. Derive from this iterator when you only care about certain
  83. // attribute types.
  84. //
  85. //-----------------------------------------------------------------------------
  86. class CEconItemSpecificAttributeIterator : public IEconItemAttributeIterator
  87. {
  88. // By default, always return true
  89. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, attrib_value_t value ) { return true; }
  90. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float value ) { return true; }
  91. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const uint64& value ) { return true; }
  92. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_String& value ) { return true; }
  93. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_DynamicRecipeComponent& value ) { return true; }
  94. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_ItemSlotCriteria& value ) { return true; }
  95. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_WorldItemPlacement& value ) { return true; }
  96. };
  97. //-----------------------------------------------------------------------------
  98. // Purpose: Interface for a single callback function per-attribute, regardless of
  99. // what type of data it stores and what the value is. This can be used
  100. // to count attributes, display generic information about definitions, etc.
  101. // but can't be used to pull data.
  102. //
  103. // To implement a subclass, override the OnIterateAttributeValueUntyped()
  104. // method.
  105. //-----------------------------------------------------------------------------
  106. class IEconItemUntypedAttributeIterator : public IEconItemAttributeIterator
  107. {
  108. public:
  109. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, attrib_value_t ) OVERRIDE
  110. {
  111. return OnIterateAttributeValueUntyped( pAttrDef );
  112. }
  113. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float ) OVERRIDE
  114. {
  115. return OnIterateAttributeValueUntyped( pAttrDef );
  116. }
  117. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const uint64& ) OVERRIDE
  118. {
  119. return OnIterateAttributeValueUntyped( pAttrDef );
  120. }
  121. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_String& ) OVERRIDE
  122. {
  123. return OnIterateAttributeValueUntyped( pAttrDef );
  124. }
  125. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_DynamicRecipeComponent& ) OVERRIDE
  126. {
  127. return OnIterateAttributeValueUntyped( pAttrDef );
  128. }
  129. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_ItemSlotCriteria& ) OVERRIDE
  130. {
  131. return OnIterateAttributeValueUntyped( pAttrDef );
  132. }
  133. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_WorldItemPlacement& ) OVERRIDE
  134. {
  135. return OnIterateAttributeValueUntyped( pAttrDef );
  136. }
  137. private:
  138. virtual bool OnIterateAttributeValueUntyped( const CEconItemAttributeDefinition *pAttrDef ) = 0;
  139. };
  140. //-----------------------------------------------------------------------------
  141. // Purpose: Simple class to answer the question "does this attribute exist" without
  142. // regards to what value it might have. Intended to be used by FindAttribute()
  143. // but made global because why not.
  144. //-----------------------------------------------------------------------------
  145. class CAttributeIterator_HasAttribute : public IEconItemUntypedAttributeIterator
  146. {
  147. public:
  148. CAttributeIterator_HasAttribute( const CEconItemAttributeDefinition *pAttrDef )
  149. : m_pAttrDef( pAttrDef )
  150. , m_bFound( false )
  151. {
  152. Assert( m_pAttrDef );
  153. }
  154. bool WasFound() const
  155. {
  156. return m_bFound;
  157. }
  158. private:
  159. bool OnIterateAttributeValueUntyped( const CEconItemAttributeDefinition *pAttrDef ) OVERRIDE
  160. {
  161. // We don't assert because we might be reusing the same iterator between calls.
  162. // Assert( !m_bFound );
  163. if ( m_pAttrDef == pAttrDef )
  164. {
  165. m_bFound = true;
  166. }
  167. return !m_bFound;
  168. }
  169. private:
  170. const CEconItemAttributeDefinition *m_pAttrDef;
  171. bool m_bFound;
  172. };
  173. //-----------------------------------------------------------------------------
  174. // Purpose: Helper class to answer the question "does this attribute exist? and if
  175. // so what is its value?". There are some template shenanigans that happen
  176. // to make things as safe as possible, and to catch errors as early as
  177. // possible.
  178. //
  179. // TActualTypeInMemory: the in-memory type of the data we're going to try
  180. // to read out (ie., "attrib_value_t", "CAttribute_String",
  181. // etc.
  182. //
  183. // TTreatAsThisType: if TActualTypeInMemory is "attrib_value_t", then we're
  184. // dealing with the old attribute system and so maybe we
  185. // want to treat these bits as a float, or a bitmask, or
  186. // who knows! Specifying this type for non-attrib_value_t
  187. // in-memory types is invalid and will fail to compile.
  188. //
  189. // This class isn't intended to be used directly but instead called from
  190. // either FindAttribute() or FindAttribute_UnsafeBitwiseCast(). It's
  191. // global because C++ doesn't support template member functions on a
  192. // template class inside a standalone template function. Weird.
  193. //-----------------------------------------------------------------------------
  194. template < typename TActualTypeInMemory, typename TTreatAsThisType = TActualTypeInMemory >
  195. class CAttributeIterator_GetTypedAttributeValue : public IEconItemAttributeIterator
  196. {
  197. public:
  198. CAttributeIterator_GetTypedAttributeValue( const CEconItemAttributeDefinition *pAttrDef, TTreatAsThisType *outpValue )
  199. : m_pAttrDef( pAttrDef )
  200. , m_outpValue( outpValue )
  201. , m_bFound( false )
  202. {
  203. // If this fails, it means that the type TActualTypeInMemory isn't something the attribute
  204. // system is prepared to recognize as a valid attribute storage type. The list of valid types
  205. // are IsValidAttributeValueTypeImpl<> specializations.
  206. //
  207. // If you added a new type and didn't make a specialization for it, this will fail. If you
  208. // *didn't* add a new type, it probably means you're passing a pointer of an incorrect type
  209. // in to FindAttribute().
  210. COMPILE_TIME_ASSERT( IsValidAttributeValueType<TActualTypeInMemory>::kValue );
  211. // The only reason we allow callers to specify a different TTreatAsThisType (versus having
  212. // it always match TActualTypeInMemory) is to deal with the old attribute system, which sometimes
  213. // had attributes have int/float types and sometimes had attribute data values that were 32
  214. // arbitrary bits. We test here to make sure that we're only using the "treat these bits as
  215. // a different type" behavior code when dealing with attributes using the old storage system
  216. // (attrib_value_t) or when we're trying to get the pointer to buffer contents for a string.
  217. COMPILE_TIME_ASSERT( ((AreTypesIdentical<TActualTypeInMemory, attrib_value_t>::kValue && AreTypesIdentical<TTreatAsThisType, float>::kValue) ||
  218. (AreTypesIdentical<TActualTypeInMemory, CAttribute_String>::kValue && AreTypesIdentical<TTreatAsThisType, const char *>::kValue) ||
  219. AreTypesIdentical<TActualTypeInMemory, TTreatAsThisType>::kValue) );
  220. Assert( m_pAttrDef );
  221. Assert( outpValue );
  222. }
  223. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, attrib_value_t value ) OVERRIDE
  224. {
  225. return OnIterateAttributeValueTyped( pAttrDef, value );
  226. }
  227. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, float value ) OVERRIDE
  228. {
  229. return OnIterateAttributeValueTyped( pAttrDef, value );
  230. }
  231. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const uint64 & value ) OVERRIDE
  232. {
  233. return OnIterateAttributeValueTyped( pAttrDef, value );
  234. }
  235. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_String & value ) OVERRIDE
  236. {
  237. return OnIterateAttributeValueTyped( pAttrDef, value );
  238. }
  239. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_DynamicRecipeComponent & value ) OVERRIDE
  240. {
  241. return OnIterateAttributeValueTyped( pAttrDef, value );
  242. }
  243. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_ItemSlotCriteria & value ) OVERRIDE
  244. {
  245. return OnIterateAttributeValueTyped( pAttrDef, value );
  246. }
  247. virtual bool OnIterateAttributeValue( const CEconItemAttributeDefinition *pAttrDef, const CAttribute_WorldItemPlacement & value ) OVERRIDE
  248. {
  249. return OnIterateAttributeValueTyped( pAttrDef, value );
  250. }
  251. bool WasFound() const
  252. {
  253. return m_bFound;
  254. }
  255. private:
  256. // Generic template function for handling any attribute value of any type besides the one that we're looking
  257. // for. For example, if we say "we're looking for attribute 'damage multiplier' and give me back a float", then
  258. // all other attribute value types (strings, structures, etc.) will go through this code, which does nothing
  259. // except look for caller errors.
  260. //
  261. // If you call FindAttribute() and specify the wrong type for an attribute (ie., using the above example, looking
  262. // for "damage multiplier" but feeding in a string), it will get found in this function, which will assert and
  263. // tell you you've got the wrong type. (FindAttribute() in that case will return false because it's impossible
  264. // for us to safely copy the value out.)
  265. template < typename TAnyOtherType >
  266. bool OnIterateAttributeValueTyped( const CEconItemAttributeDefinition *pAttrDef, const TAnyOtherType& value )
  267. {
  268. COMPILE_TIME_ASSERT( IsValidAttributeValueType<TAnyOtherType>::kValue );
  269. // We don't assert because we might be reusing the same iterator between calls.
  270. // Assert( !m_bFound );
  271. AssertMsg( m_pAttrDef != pAttrDef, "Incorrect type found for attribute during iteration." );
  272. return true;
  273. }
  274. // Overload for attributes of the data type we're looking for. ie., if we say "we're looking for attribute
  275. // 'damage multiplier' and give me back a float", this will be the <float> specialization. We assume that
  276. // we're only going to find at most one attribute per definition and stop looking after we've found the first.
  277. //
  278. // Note that this is just a normal member function, but is *not* a template member function, which would compile
  279. // under VC but otherwise be illegal.
  280. bool OnIterateAttributeValueTyped( const CEconItemAttributeDefinition *pAttrDef, const TActualTypeInMemory& value )
  281. {
  282. // We don't assert because we might be reusing the same iterator between calls.
  283. // Assert( !m_bFound );
  284. if ( m_pAttrDef == pAttrDef )
  285. {
  286. m_bFound = true;
  287. CopyAttributeValueToOutput( &value, reinterpret_cast<TTreatAsThisType *>( m_outpValue ) );
  288. }
  289. return !m_bFound;
  290. }
  291. private:
  292. static void CopyAttributeValueToOutput( const TActualTypeInMemory *pValue, TTreatAsThisType *out_pValue )
  293. {
  294. // Even if we are using the old attribute type system, we need to guarantee that the type
  295. // in memory (ie., uint32) and the type we're considering it as (ie., float) are the same size
  296. // because we're going to be doing bitwise casts.
  297. COMPILE_TIME_ASSERT( sizeof( TActualTypeInMemory ) == sizeof( TTreatAsThisType ) );
  298. Assert( pValue );
  299. Assert( out_pValue );
  300. *out_pValue = *reinterpret_cast<const TTreatAsThisType *>( pValue );
  301. }
  302. private:
  303. const CEconItemAttributeDefinition *m_pAttrDef;
  304. TTreatAsThisType *m_outpValue;
  305. bool m_bFound;
  306. };
  307. //-----------------------------------------------------------------------------
  308. // Purpose: Custom code path to support getting the char * result from an
  309. // attribute of type CAttribute_String.
  310. //
  311. // We can't specify the implementation here because we may or may not
  312. // have the definition of CAttribute_String in scope. We also can't
  313. // declare the template specialization here and define it later because
  314. // that would violate the standard, so instead we have the template
  315. // function call a declared-but-not-defined non-template function that
  316. // we can define later.
  317. //-----------------------------------------------------------------------------
  318. void CopyStringAttributeValueToCharPointerOutput( const CAttribute_String *pValue, const char **out_pValue );
  319. template < >
  320. inline void CAttributeIterator_GetTypedAttributeValue<CAttribute_String, const char *>::CopyAttributeValueToOutput( const CAttribute_String *pValue, const char **out_pValue )
  321. {
  322. CopyStringAttributeValueToCharPointerOutput( pValue, out_pValue );
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Purpose: Look for the existence/nonexistence of an attribute with the
  326. // definition [pAttrDef]. Can be called on anything with an IterateAttributes()
  327. // member functions (IEconItemInterface, CEconItemDefinition).
  328. //-----------------------------------------------------------------------------
  329. template < typename TAttributeContainerType >
  330. bool FindAttribute( const TAttributeContainerType *pSomethingThatHasAnIterateAttributesFunction, const CEconItemAttributeDefinition *pAttrDef )
  331. {
  332. #ifdef CLIENT_DLL
  333. VPROF_BUDGET( "IEconItemInterface::FindAttribute", VPROF_BUDGETGROUP_FINDATTRIBUTE );
  334. #endif
  335. if ( !pAttrDef )
  336. return false;
  337. CAttributeIterator_HasAttribute it( pAttrDef );
  338. pSomethingThatHasAnIterateAttributesFunction->IterateAttributes( &it );
  339. return it.WasFound();
  340. }
  341. //-----------------------------------------------------------------------------
  342. // Purpose:
  343. //-----------------------------------------------------------------------------
  344. template < typename TActualTypeInMemory, typename TTreatAsThisType, typename TAttributeContainerType >
  345. bool FindAttribute_UnsafeBitwiseCast( const TAttributeContainerType *pSomethingThatHasAnIterateAttributesFunction, const CEconItemAttributeDefinition *pAttrDef, TTreatAsThisType *out_pValue )
  346. {
  347. #ifdef CLIENT_DLL
  348. VPROF_BUDGET( "IEconItemInterface::FindAttribute_UnsafeBitwiseCast", VPROF_BUDGETGROUP_FINDATTRIBUTEUNSAFE );
  349. #endif
  350. if ( !pAttrDef )
  351. return false;
  352. CAttributeIterator_GetTypedAttributeValue<TActualTypeInMemory, TTreatAsThisType> it( pAttrDef, out_pValue );
  353. pSomethingThatHasAnIterateAttributesFunction->IterateAttributes( &it );
  354. return it.WasFound();
  355. }
  356. //-----------------------------------------------------------------------------
  357. // Purpose:
  358. //-----------------------------------------------------------------------------
  359. template < typename TAttributeContainerType, typename T >
  360. bool FindAttribute( const TAttributeContainerType *pSomethingThatHasAnIterateAttributesFunction, const CEconItemAttributeDefinition *pAttrDef, T *out_pValue )
  361. {
  362. return FindAttribute_UnsafeBitwiseCast<T, T, TAttributeContainerType>( pSomethingThatHasAnIterateAttributesFunction, pAttrDef, out_pValue );
  363. }
  364. //-----------------------------------------------------------------------------
  365. // Purpose:
  366. //-----------------------------------------------------------------------------
  367. class IEconItemInterface
  368. {
  369. public:
  370. virtual ~IEconItemInterface() { }
  371. // Is an attribute present? We neither know nor care anything about the attribute
  372. // value stored.
  373. bool FindAttribute( const CEconItemAttributeDefinition *pAttrDef ) const
  374. {
  375. return ::FindAttribute( this, pAttrDef );
  376. }
  377. // If an attribute is present, it will copy the value into out_pValue and return true.
  378. // If the attribute is not present, it will return false and not touch the value in
  379. // out_pValue. If a T is passed in that is not a type the attribute system understands,
  380. // this function will fail to compile.
  381. template < typename T >
  382. bool FindAttribute( const CEconItemAttributeDefinition *pAttrDef, T *out_pValue ) const
  383. {
  384. return ::FindAttribute( this, pAttrDef, out_pValue );
  385. }
  386. // Helpers to look for specific attribute values
  387. virtual CEconItemPaintKitDefinition *GetCustomPainkKitDefinition( void ) const { return GetItemDefinition() ? GetItemDefinition()->GetCustomPainkKitDefinition() : NULL; }
  388. virtual bool GetCustomPaintKitWear( float &flWear ) const;
  389. // IEconItemInterface common implementation.
  390. virtual bool IsTradable() const;
  391. virtual int GetUntradabilityFlags() const;
  392. virtual bool IsCommodity() const;
  393. virtual bool IsUsableInCrafting() const;
  394. virtual bool IsMarketable() const; // can this item be listed on the Marketplace?
  395. bool IsTemporaryItem() const; // returns whether this item is a temporary instance of an item that is not by nature temporary (ie., a preview item, an item with an attribute expiration timer)
  396. RTime32 GetExpirationDate() const; // will return RTime32( 0 ) if this item will not expire, otherwise the time that it will auto-delete itself; this looks at both static and dynamic ways of expiring timers
  397. // IEconItemInterface interface.
  398. virtual const GameItemDefinition_t *GetItemDefinition() const = 0;
  399. virtual itemid_t GetID() const = 0; // intentionally not called GetItemID to avoid stomping non-virtual GetItemID() on CEconItem
  400. virtual uint32 GetAccountID() const = 0;
  401. virtual int32 GetQuality() const = 0;
  402. virtual style_index_t GetStyle() const = 0;
  403. virtual uint8 GetFlags() const = 0;
  404. virtual eEconItemOrigin GetOrigin() const = 0;
  405. virtual int GetQuantity() const = 0;
  406. virtual uint32 GetItemLevel() const = 0;
  407. virtual bool GetInUse() const = 0; // is this item in use somewhere in the backend? (ie., cross-game trading)
  408. virtual const char *GetCustomName() const = 0; // get a user-generated name, if present, otherwise NULL; return value is UTF8
  409. virtual const char *GetCustomDesc() const = 0; // get a user-generated flavor text, if present, otherwise NULL; return value is UTF8
  410. // IEconItemInterface attribute iteration interface. This is not meant to be used for
  411. // attribute lookup! This is meant for anything that requires iterating over the full
  412. // attribute list.
  413. virtual void IterateAttributes( IEconItemAttributeIterator *pIterator ) const = 0;
  414. // Fetch values from the definition
  415. const char *GetDefinitionString( const char *pszKeyName, const char *pszDefaultValue = "" ) const;
  416. KeyValues *GetDefinitionKey( const char *pszKeyName ) const;
  417. RTime32 GetTradableAfterDateTime() const;
  418. virtual item_definition_index_t GetItemDefIndex() const { return GetItemDefinition() ? GetItemDefinition()->GetDefinitionIndex() : INVALID_ITEM_DEF_INDEX; }
  419. virtual IMaterial* GetMaterialOverride( int iTeam ) = 0;
  420. protected:
  421. bool IsPermanentlyUntradable() const;
  422. bool IsTemporarilyUntradable() const;
  423. };
  424. //-----------------------------------------------------------------------------
  425. // Purpose: Classes that want default behavior for GetMaterialOverride, which
  426. // currently derive from IEconItemInterface can instead derive from
  427. // CMaterialOverrideContainer< IEconItemInterface > and have the details
  428. // of material overrides hidden from them.
  429. //-----------------------------------------------------------------------------
  430. template <typename TBaseClass>
  431. class CMaterialOverrideContainer : public TBaseClass
  432. {
  433. public:
  434. virtual IMaterial* GetMaterialOverride( int iTeam ) OVERRIDE
  435. {
  436. #ifdef CLIENT_DLL
  437. Assert( iTeam >= 0 && iTeam < ARRAYSIZE( m_materialOverrides ) );
  438. if ( m_materialOverrides[ iTeam ].IsValid() )
  439. return m_materialOverrides[ iTeam ];
  440. if ( !this->GetItemDefinition() )
  441. return NULL;
  442. const char* pName = this->GetItemDefinition()->GetMaterialOverride( iTeam );
  443. if ( pName == NULL )
  444. return NULL;
  445. m_materialOverrides[ iTeam ].Init( pName, TEXTURE_GROUP_CLIENT_EFFECTS );
  446. return m_materialOverrides[ iTeam ];
  447. #else
  448. return NULL;
  449. #endif
  450. }
  451. protected:
  452. void ResetMaterialOverrides()
  453. {
  454. #ifdef CLIENT_DLL
  455. for ( int i = 0; i < TF_TEAM_COUNT; ++i )
  456. m_materialOverrides[ i ].Shutdown();
  457. #endif
  458. }
  459. private:
  460. #ifdef CLIENT_DLL
  461. CMaterialReference m_materialOverrides[ TF_TEAM_COUNT ];
  462. #endif
  463. };
  464. #endif // ECONITEMINTERFACE_H