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
|