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.

304 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Container that allows client & server access to data in player inventories & loadouts
  4. //
  5. //=============================================================================
  6. #ifndef TF_ITEM_INVENTORY_H
  7. #define TF_ITEM_INVENTORY_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "econ_item_inventory.h"
  12. #include "tf_shareddefs.h"
  13. #include "econ_item_constants.h"
  14. #include "tf_item_constants.h"
  15. #ifdef CLIENT_DLL
  16. #include "econ_notifications.h"
  17. #endif
  18. #define LOADOUT_SLOT_USE_BASE_ITEM 0
  19. namespace vgui
  20. {
  21. class Panel;
  22. }
  23. struct baseitemcriteria_t;
  24. //===============================================================================================================
  25. //-----------------------------------------------------------------------------
  26. // Purpose: A single TF player's inventory.
  27. // On the client, the inventory manager contains an instance of this for the local player.
  28. // On the server, each player contains an instance of this.
  29. //-----------------------------------------------------------------------------
  30. class CTFPlayerInventory : public CPlayerInventory
  31. {
  32. DECLARE_CLASS( CTFPlayerInventory, CPlayerInventory );
  33. public:
  34. CTFPlayerInventory();
  35. virtual ~CTFPlayerInventory();
  36. virtual CEconItemView *GetItemInLoadout( int iClass, int iSlot );
  37. #ifdef CLIENT_DLL
  38. // Removes any item in a loadout slot. If the slot has a base item,
  39. // the player essentially returns to using that item.
  40. // NOTE: This can fail if the player has no backpack space to contain the equipped item.
  41. bool ClearLoadoutSlot( int iClass, int iSlot );
  42. CEconItemView *GetCacheServerItemInLoadout( int iClass, int iSlot );
  43. void UpdateWeaponSkinRequest();
  44. #endif
  45. virtual int GetMaxItemCount( void ) const;
  46. virtual bool CanPurchaseItems( int iItemCount ) const;
  47. virtual int GetPreviewItemDef( void ) const;
  48. // Derived inventory hooks
  49. virtual void ItemHasBeenUpdated( CEconItemView *pItem, bool bUpdateAckFile, bool bWriteAckFile ) OVERRIDE;
  50. virtual void ItemIsBeingRemoved( CEconItemView *pItem );
  51. bool UpdateEquipStateForClass( const itemid_t& itemID, equipped_slot_t nSlot, itemid_t *pLoadout, int nCount );
  52. // Debugging
  53. virtual void DumpInventoryToConsole( bool bRoot );
  54. bool ClassLoadoutHasChanged( int iClass ) { return m_bLoadoutChanged[iClass]; }
  55. void ClearClassLoadoutChangeTracking( void );
  56. virtual void NotifyHasNewItems() { OnHasNewItems(); }
  57. #ifdef CLIENT_DLL
  58. virtual ITexture *GetWeaponSkinBaseLowRes( itemid_t nItemId, int iTeam ) const;
  59. #endif
  60. void OnHasNewQuest();
  61. static CEconItemView *GetFirstItemOfItemDef( item_definition_index_t nDefIndex, CPlayerInventory* pInventory = NULL );
  62. protected:
  63. virtual void SOCreated( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;
  64. #ifdef CLIENT_DLL
  65. // Converts an old format inventory to the new format.
  66. void ConvertOldFormatInventoryToNew( void );
  67. virtual void PostSOUpdate( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;
  68. virtual void SOCacheSubscribed( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;
  69. virtual bool AddEconItem( CEconItem * pItem, bool bUpdateAckFile, bool bWriteAckFile, bool bCheckForNewItems ) OVERRIDE;
  70. void VerifyChangedLoadoutsAreValid();
  71. void VerifyLoadoutItemsAreValid( int iClass );
  72. #endif
  73. virtual void OnHasNewItems();
  74. virtual void ValidateInventoryPositions( void );
  75. // Extracts the position that should be used to sort items in the inventory from the backend position.
  76. // Necessary if your inventory packs a bunch of info into the position instead of using it just as a position.
  77. virtual int ExtractInventorySortPosition( uint32 iBackendPosition )
  78. {
  79. // Consider unack'd items as -1, so they get stacked up before the 0th slot item
  80. if ( IsUnacknowledged(iBackendPosition) )
  81. return -1;
  82. return ExtractBackpackPositionFromBackend(iBackendPosition);
  83. }
  84. virtual void SOUpdated( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;
  85. #ifdef CLIENT_DLL
  86. private:
  87. void CheckSaxtonMaskAchievement( const CEconItem *pEconItem );
  88. void UpdateCachedServerLoadoutItems();
  89. #endif
  90. protected:
  91. // Global indices of the items in our inventory in the loadout slots
  92. #ifdef CLIENT_DLL
  93. struct SkinRequest_t
  94. {
  95. int m_nTeam;
  96. itemid_t m_nID;
  97. MDLHandle_t m_hModel;
  98. };
  99. CUtlVector< SkinRequest_t > m_vecWeaponSkinRequestList;
  100. itemid_t m_CachedServerLoadoutItems[ TF_CLASS_COUNT ][ CLASS_LOADOUT_POSITION_COUNT ];
  101. CUtlMap< itemid_t, ITexture* > m_CachedBaseTextureLowRes[ TF_TEAM_COUNT ];
  102. #endif // CLIENT_DLL
  103. itemid_t m_LoadoutItems[ TF_CLASS_COUNT ][ CLASS_LOADOUT_POSITION_COUNT ];
  104. bool m_bLoadoutChanged[ TF_CLASS_COUNT ];
  105. itemid_t m_AccountLoadoutItems[ ACCOUNT_LOADOUT_POSITION_COUNT ];
  106. friend class CTFInventoryManager;
  107. };
  108. //-----------------------------------------------------------------------------
  109. // Purpose:
  110. //-----------------------------------------------------------------------------
  111. class CTFInventoryManager : public CInventoryManager
  112. {
  113. DECLARE_CLASS( CTFInventoryManager, CInventoryManager );
  114. public:
  115. CTFInventoryManager();
  116. ~CTFInventoryManager();
  117. virtual void PostInit( void );
  118. #ifdef CLIENT_DLL
  119. virtual CPlayerInventory *GeneratePlayerInventoryObject() const { return new CTFPlayerInventory; }
  120. //-----------------------------------------------------------------------
  121. // CLIENT PICKUP UI HANDLING
  122. //-----------------------------------------------------------------------
  123. // Get the number of items picked up
  124. virtual int GetNumItemPickedUpItems( void );
  125. // Show the player a pickup screen with any items they've collected recently, if any
  126. virtual bool ShowItemsPickedUp( bool bForce = false, bool bReturnToGame = true, bool bNoPanel = false );
  127. // Show the player a pickup screen with the items they've crafted
  128. virtual void ShowItemsCrafted( CUtlVector<itemid_t> *vecCraftedIndices );
  129. // Force the player to discard an item to make room for a new item, if they have one
  130. virtual bool CheckForRoomAndForceDiscard( void );
  131. // Tells the GC that the player has acknowledged an item and attempts to move it in to the first available BP slot
  132. virtual void AcknowledgeItem( CEconItemView *pItem, bool bMoveToBackpack = true );
  133. // Gets called each frame
  134. virtual void Update( float frametime ) OVERRIDE;
  135. #endif
  136. // Returns the item data for the base item in the loadout slot for a given class
  137. CEconItemView *GetBaseItemForClass( int iClass, int iSlot );
  138. void GenerateBaseItems( void );
  139. // Gets the specified inventory for the steam ID
  140. CTFPlayerInventory *GetInventoryForPlayer( const CSteamID &playerID );
  141. // Returns the item in the specified loadout slot for a given class
  142. CEconItemView *GetItemInLoadoutForClass( int iClass, int iSlot, CSteamID *pID = NULL );
  143. CEconItemView *GetItemInLoadoutForAccount( int nSlot, CSteamID *pID = NULL );
  144. // Fills out the vector with the sets that are currently active on the specified player & class
  145. void GetActiveSets( CUtlVector<const CEconItemSetDefinition *> *pItemSets, CSteamID steamIDForPlayer, int iClass );
  146. // We're generating a base item. We need to add the game-specific keys to the criteria so that it'll find the right base item.
  147. virtual void AddBaseItemCriteria( baseitemcriteria_t *pCriteria, CItemSelectionCriteria *pSelectionCriteria );
  148. bool SlotContainsBaseItems( EEquipType_t eType, int iSlot );
  149. int GetBaseItemCount( ) { return m_pBaseLoadoutItems.Count(); }
  150. CEconItemView* GetBaseItem( int iIndex ) { return m_pBaseLoadoutItems[iIndex]; }
  151. private:
  152. // Base items, returned for slots that the player doesn't have anything in
  153. CEconItemView *m_pDefaultItem;
  154. CUtlVector<CEconItemView*> m_pBaseLoadoutItems;
  155. #ifdef CLIENT_DLL
  156. // On the client, we have a single inventory for the local player. Stored here, instead of in the
  157. // local player entity, because players need to access it while not being connected to a server.
  158. public:
  159. CPlayerInventory *GetLocalInventory( void ) { return &m_LocalInventory; }
  160. CTFPlayerInventory *GetLocalTFInventory( void );
  161. // Try and equip the specified item in the specified class's loadout slot
  162. bool EquipItemInLoadout( int iClass, int iSlot, itemid_t iItemID );
  163. // Fills out pList with all inventory items that could fit into the specified loadout slot for a given class
  164. int GetAllUsableItemsForSlot( int iClass, int iSlot, CUtlVector<CEconItemView*> *pList );
  165. virtual int GetBackpackPositionFromBackend( uint32 iBackendPosition ) { return ExtractBackpackPositionFromBackend(iBackendPosition); }
  166. // Fills out pList with all quest item in the local inventory
  167. int GetAllQuestItems( CUtlVector<CEconItemView*> *pList );
  168. private:
  169. CTFPlayerInventory m_LocalInventory;
  170. #endif // CLIENT_DLL
  171. };
  172. CTFInventoryManager *TFInventoryManager( void );
  173. #ifdef CLIENT_DLL
  174. //-----------------------------------------------------------------------------
  175. // Econ Notifications
  176. //-----------------------------------------------------------------------------
  177. class CEconNotification_HasNewItems : public CEconNotification
  178. {
  179. public:
  180. CEconNotification_HasNewItems();
  181. ~CEconNotification_HasNewItems();
  182. virtual void SetLifetime( float flSeconds )
  183. {
  184. m_flExpireTime = engine->Time() + flSeconds;
  185. }
  186. virtual float GetExpireTime() const
  187. {
  188. if ( m_flExpireTime != 0 )
  189. return -1.0f;
  190. return 0;
  191. }
  192. virtual float GetInGameLifeTime() const
  193. {
  194. return m_flExpireTime;
  195. }
  196. virtual void MarkForDeletion()
  197. {
  198. m_bHasTriggered = true;
  199. CEconNotification::MarkForDeletion();
  200. }
  201. virtual EType NotificationType() { return eType_Trigger; }
  202. virtual void Trigger()
  203. {
  204. m_bHasTriggered = true;
  205. TFInventoryManager()->ShowItemsPickedUp( true );
  206. MarkForDeletion();
  207. }
  208. virtual bool BShowInGameElements() const
  209. {
  210. return m_bShowInGame;
  211. }
  212. static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast<CEconNotification_HasNewItems *>( pNotification ) != NULL; }
  213. protected:
  214. bool m_bHasTriggered;
  215. bool m_bShowInGame;
  216. };
  217. //-----------------------------------------------------------------------------
  218. class CEconNotification_HasNewItemsOnKill : public CEconNotification_HasNewItems
  219. {
  220. public:
  221. CEconNotification_HasNewItemsOnKill( int iVictimID );
  222. virtual EType NotificationType() { return eType_Basic; }
  223. virtual void Trigger() {}
  224. static bool HasUnacknowledgedItems();
  225. static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast<CEconNotification_HasNewItemsOnKill *>( pNotification ) != NULL; }
  226. };
  227. #endif
  228. #endif // TF_ITEM_INVENTORY_H