summaryrefslogtreecommitdiff
path: root/game/shared/tf/tf_item_inventory.h
blob: 8d1f305164b42437d84c74f26dd8a511ea88376f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Container that allows client & server access to data in player inventories & loadouts
//
//=============================================================================

#ifndef TF_ITEM_INVENTORY_H
#define TF_ITEM_INVENTORY_H
#ifdef _WIN32
#pragma once
#endif

#include "econ_item_inventory.h"
#include "tf_shareddefs.h"
#include "econ_item_constants.h"
#include "tf_item_constants.h"

#ifdef CLIENT_DLL
#include "econ_notifications.h"
#endif

#define LOADOUT_SLOT_USE_BASE_ITEM		0

namespace vgui
{
	class Panel;
}

struct baseitemcriteria_t;

//===============================================================================================================
//-----------------------------------------------------------------------------
// Purpose: A single TF player's inventory. 
//		On the client, the inventory manager contains an instance of this for the local player.
//		On the server, each player contains an instance of this.
//-----------------------------------------------------------------------------
class CTFPlayerInventory : public CPlayerInventory
{
	DECLARE_CLASS( CTFPlayerInventory, CPlayerInventory );
public:
	CTFPlayerInventory();
	virtual ~CTFPlayerInventory();

	virtual CEconItemView	*GetItemInLoadout( int iClass, int iSlot );

#ifdef CLIENT_DLL
	// Removes any item in a loadout slot. If the slot has a base item,
	// the player essentially returns to using that item.
	// NOTE: This can fail if the player has no backpack space to contain the equipped item.
	bool				ClearLoadoutSlot( int iClass, int iSlot );
	CEconItemView		*GetCacheServerItemInLoadout( int iClass, int iSlot );

	void				UpdateWeaponSkinRequest();
#endif

	virtual int			GetMaxItemCount( void ) const;
	virtual bool		CanPurchaseItems( int iItemCount ) const;
	virtual int			GetPreviewItemDef( void ) const;

	// Derived inventory hooks
	virtual void		ItemHasBeenUpdated( CEconItemView *pItem, bool bUpdateAckFile, bool bWriteAckFile ) OVERRIDE;
	virtual void		ItemIsBeingRemoved( CEconItemView *pItem );
	bool				UpdateEquipStateForClass( const itemid_t& itemID, equipped_slot_t nSlot, itemid_t *pLoadout, int nCount );

	// Debugging
	virtual void		DumpInventoryToConsole( bool bRoot );

	bool				ClassLoadoutHasChanged( int iClass ) { return m_bLoadoutChanged[iClass]; }
	void				ClearClassLoadoutChangeTracking( void );

	virtual void		NotifyHasNewItems() { OnHasNewItems(); }

#ifdef CLIENT_DLL
	virtual ITexture	*GetWeaponSkinBaseLowRes( itemid_t nItemId, int iTeam ) const;
#endif

	void				OnHasNewQuest();

	static CEconItemView *GetFirstItemOfItemDef( item_definition_index_t nDefIndex, CPlayerInventory* pInventory = NULL );

protected:
	virtual void		SOCreated( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;
#ifdef CLIENT_DLL
	// Converts an old format inventory to the new format.
	void				ConvertOldFormatInventoryToNew( void );

	virtual void		PostSOUpdate( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;
	virtual void		SOCacheSubscribed( const CSteamID & steamIDOwner, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;

	virtual bool		AddEconItem( CEconItem * pItem, bool bUpdateAckFile, bool bWriteAckFile, bool bCheckForNewItems ) OVERRIDE;

	void				VerifyChangedLoadoutsAreValid();
	void				VerifyLoadoutItemsAreValid( int iClass );
#endif

	virtual void		OnHasNewItems();
	virtual void		ValidateInventoryPositions( void );

	// Extracts the position that should be used to sort items in the inventory from the backend position.
	// Necessary if your inventory packs a bunch of info into the position instead of using it just as a position.
	virtual int			ExtractInventorySortPosition( uint32 iBackendPosition )
	{ 
		// Consider unack'd items as -1, so they get stacked up before the 0th slot item
		if ( IsUnacknowledged(iBackendPosition) )
			return -1;
		return ExtractBackpackPositionFromBackend(iBackendPosition); 
	}

	virtual void		SOUpdated( const CSteamID & steamIDOwner, const GCSDK::CSharedObject *pObject, GCSDK::ESOCacheEvent eEvent ) OVERRIDE;

#ifdef CLIENT_DLL
private:
	void				CheckSaxtonMaskAchievement( const CEconItem *pEconItem );
	void				UpdateCachedServerLoadoutItems();
#endif

protected:
	// Global indices of the items in our inventory in the loadout slots
#ifdef CLIENT_DLL
	struct SkinRequest_t
	{
		int m_nTeam;
		itemid_t m_nID;
		MDLHandle_t m_hModel;
	};
	CUtlVector< SkinRequest_t > m_vecWeaponSkinRequestList;


	itemid_t		m_CachedServerLoadoutItems[ TF_CLASS_COUNT ][ CLASS_LOADOUT_POSITION_COUNT ];

	CUtlMap< itemid_t, ITexture* > m_CachedBaseTextureLowRes[ TF_TEAM_COUNT ];

#endif // CLIENT_DLL
	itemid_t		m_LoadoutItems[ TF_CLASS_COUNT ][ CLASS_LOADOUT_POSITION_COUNT ];
	bool			m_bLoadoutChanged[ TF_CLASS_COUNT ];
	itemid_t		m_AccountLoadoutItems[ ACCOUNT_LOADOUT_POSITION_COUNT ];


	friend class CTFInventoryManager;
};

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
class CTFInventoryManager : public CInventoryManager
{
	DECLARE_CLASS( CTFInventoryManager, CInventoryManager );
public:
	CTFInventoryManager();
	~CTFInventoryManager();

	virtual void		PostInit( void );

#ifdef CLIENT_DLL
	virtual CPlayerInventory *GeneratePlayerInventoryObject() const { return new CTFPlayerInventory; }

	//-----------------------------------------------------------------------
	// CLIENT PICKUP UI HANDLING
	//-----------------------------------------------------------------------

	// Get the number of items picked up
	virtual int			GetNumItemPickedUpItems( void );				

	// Show the player a pickup screen with any items they've collected recently, if any
	virtual bool		ShowItemsPickedUp( bool bForce = false, bool bReturnToGame = true, bool bNoPanel = false );

	// Show the player a pickup screen with the items they've crafted
	virtual void		ShowItemsCrafted( CUtlVector<itemid_t> *vecCraftedIndices );

	// Force the player to discard an item to make room for a new item, if they have one
	virtual bool		CheckForRoomAndForceDiscard( void );

	// Tells the GC that the player has acknowledged an item and attempts to move it in to the first available BP slot
	virtual void		AcknowledgeItem( CEconItemView *pItem, bool bMoveToBackpack = true );

	// Gets called each frame
	virtual void		Update( float frametime ) OVERRIDE;
#endif

	// Returns the item data for the base item in the loadout slot for a given class
	CEconItemView		*GetBaseItemForClass( int iClass, int iSlot );
	void				GenerateBaseItems( void );

	// Gets the specified inventory for the steam ID
	CTFPlayerInventory	*GetInventoryForPlayer( const CSteamID &playerID );

	// Returns the item in the specified loadout slot for a given class
	CEconItemView		*GetItemInLoadoutForClass( int iClass, int iSlot, CSteamID *pID = NULL );
	
	CEconItemView		*GetItemInLoadoutForAccount( int nSlot, CSteamID *pID = NULL );

	// Fills out the vector with the sets that are currently active on the specified player & class
	void				GetActiveSets( CUtlVector<const CEconItemSetDefinition *> *pItemSets, CSteamID steamIDForPlayer, int iClass );

	// 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.
	virtual void		AddBaseItemCriteria( baseitemcriteria_t *pCriteria, CItemSelectionCriteria *pSelectionCriteria );
	
	bool				SlotContainsBaseItems( EEquipType_t eType, int iSlot );

	int					GetBaseItemCount( )			{ return m_pBaseLoadoutItems.Count(); }
	CEconItemView*		GetBaseItem( int iIndex )	{ return m_pBaseLoadoutItems[iIndex]; }

private:
	// Base items, returned for slots that the player doesn't have anything in
	CEconItemView				*m_pDefaultItem;
	CUtlVector<CEconItemView*>	m_pBaseLoadoutItems;

#ifdef CLIENT_DLL
	// On the client, we have a single inventory for the local player. Stored here, instead of in the
	// local player entity, because players need to access it while not being connected to a server.
public:
	CPlayerInventory	*GetLocalInventory( void ) { return &m_LocalInventory; }
	CTFPlayerInventory	*GetLocalTFInventory( void );

	// Try and equip the specified item in the specified class's loadout slot
	bool				EquipItemInLoadout( int iClass, int iSlot, itemid_t iItemID );

	// Fills out pList with all inventory items that could fit into the specified loadout slot for a given class
	int					GetAllUsableItemsForSlot( int iClass, int iSlot, CUtlVector<CEconItemView*> *pList );

	virtual int			GetBackpackPositionFromBackend( uint32 iBackendPosition ) { return ExtractBackpackPositionFromBackend(iBackendPosition); }

	// Fills out pList with all quest item in the local inventory
	int					GetAllQuestItems( CUtlVector<CEconItemView*> *pList );

private:
	CTFPlayerInventory	m_LocalInventory;
#endif // CLIENT_DLL
};

CTFInventoryManager *TFInventoryManager( void );



#ifdef CLIENT_DLL
//-----------------------------------------------------------------------------
// Econ Notifications
//-----------------------------------------------------------------------------
class CEconNotification_HasNewItems : public CEconNotification
{
public:
	CEconNotification_HasNewItems();
	~CEconNotification_HasNewItems();

	virtual void SetLifetime( float flSeconds )
	{
		m_flExpireTime = engine->Time() + flSeconds;
	}

	virtual float GetExpireTime() const
	{
		if ( m_flExpireTime != 0 )
			return -1.0f;
		return 0;
	}

	virtual float GetInGameLifeTime() const
	{
		return m_flExpireTime;
	}

	virtual void MarkForDeletion()
	{
		m_bHasTriggered = true;
		CEconNotification::MarkForDeletion();
	}

	virtual EType NotificationType() { return eType_Trigger; }
	virtual void Trigger()
	{
		m_bHasTriggered = true;
		TFInventoryManager()->ShowItemsPickedUp( true );
		MarkForDeletion();
	}

	virtual bool BShowInGameElements() const
	{
		return m_bShowInGame;
	}

	static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast<CEconNotification_HasNewItems *>( pNotification ) != NULL; }

protected:

	bool m_bHasTriggered;
	bool m_bShowInGame;
};

//-----------------------------------------------------------------------------
class CEconNotification_HasNewItemsOnKill : public CEconNotification_HasNewItems
{
public:
	CEconNotification_HasNewItemsOnKill( int iVictimID );

	virtual EType NotificationType() { return eType_Basic; }
	virtual void Trigger() {}

	static bool HasUnacknowledgedItems();
	static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast<CEconNotification_HasNewItemsOnKill *>( pNotification ) != NULL; }
};
#endif


#endif // TF_ITEM_INVENTORY_H