Skip to content

Commit 8305ef5

Browse files
committed
fix Steam's broken auto_stack for playtime generators
1 parent 00f9d3b commit 8305ef5

4 files changed

Lines changed: 106 additions & 4 deletions

File tree

src/game/client/swarm/rd_collections_crafting.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ void CRD_Crafting_Panel::OnCommand( const char *szCommand )
136136
// (this assumption allows us to use a greedy algorithm)
137137
FOR_EACH_VEC( variant.m_Inputs, j )
138138
{
139+
Assert( variant.m_Inputs[j].m_iQuantity == 1 );
140+
139141
FOR_EACH_VEC( variant.m_Inputs[j].m_AllowedItem, k )
140142
{
141143
CUtlVector<ReactiveDropInventory::ItemInstance_t> instances;

src/game/shared/swarm/rd_crafting_defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct RD_Crafting_Recipe_Input
100100
{
101101
CCopyableUtlVector<SteamItemDef_t> m_AllowedItem;
102102
uint32_t m_iFlags = 0;
103+
uint32_t m_iQuantity = 1;
103104
};
104105

105106
struct RD_Crafting_Recipe_Variant

src/game/shared/swarm/rd_inventory_shared.cpp

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,21 +281,34 @@ static class CRD_Inventory_Manager final : public CAutoGameSystem, public CGameE
281281

282282
m_HighOwnedInventoryDefIDs.Purge();
283283

284+
CUtlMap<SteamItemDef_t, CCopyableUtlVector<SteamItemInstanceID_t>> autoStackDefs( DefLessFunc( SteamItemDef_t ) );
284285
for ( uint32 i = 0; i < nItems; i++ )
285286
{
286287
ReactiveDropInventory::ItemInstance_t instance{ hResult, i };
287288
m_LocalInventoryCache.AddToTail( instance );
288289

289-
// precache item def + icon
290-
( void )ReactiveDropInventory::GetItemDef( instance.ItemDefID );
290+
// precache item def + icon and check for auto-stack flag
291+
const ReactiveDropInventory::ItemDef_t *pDef = ReactiveDropInventory::GetItemDef( instance.ItemDefID );
292+
if ( pDef && pDef->AutoStack )
293+
{
294+
unsigned short index = autoStackDefs.Find( instance.ItemDefID );
295+
if ( !autoStackDefs.IsValidIndex( index ) )
296+
{
297+
index = autoStackDefs.Insert( instance.ItemDefID );
298+
}
299+
300+
autoStackDefs[index].AddToTail( instance.ItemID );
301+
}
291302

292303
// The Steam inventory API doesn't list item def IDs that are between 1 million and 1 billion unless we ask about them specifically.
293304
// If we own any items with def IDs in this range, remember that and re-write the schema cache to include them.
294305
// These IDs are used for donation receipt medals as well as unique medals.
295306
if ( instance.ItemDefID >= 1000000 )
296307
{
297308
if ( !m_HighOwnedInventoryDefIDs.IsValidIndex( m_HighOwnedInventoryDefIDs.Find( instance.ItemDefID ) ) )
309+
{
298310
m_HighOwnedInventoryDefIDs.AddToTail( instance.ItemDefID );
311+
}
299312
}
300313
}
301314

@@ -320,6 +333,33 @@ static class CRD_Inventory_Manager final : public CAutoGameSystem, public CGameE
320333
}
321334
}
322335

336+
if ( rd_debug_inventory.GetBool() )
337+
{
338+
DevMsg( 3, "Verifying %d auto-stack defs...\n", autoStackDefs.Count() );
339+
}
340+
FOR_EACH_MAP_FAST( autoStackDefs, i )
341+
{
342+
if ( autoStackDefs[i].Count() == 1 )
343+
{
344+
continue;
345+
}
346+
347+
Assert( autoStackDefs[i].Count() != 0 );
348+
349+
if ( rd_debug_inventory.GetBool() )
350+
{
351+
Msg( "Have %d stacks of auto-stack item %d; merging\n", autoStackDefs[i].Count(), autoStackDefs.Key( i ) );
352+
}
353+
354+
pInventory->TransferItemQuantity( AddCraftItemTask( CRAFT_AUTO_STACK, autoStackDefs.Key( i ) ), autoStackDefs[i][1], GetLocalItemCache( autoStackDefs[i][1] )->Quantity, autoStackDefs[i][0] );
355+
if ( autoStackDefs[i].Count() > 2 )
356+
{
357+
m_CraftingQueue.Tail()->m_RetryItemList.AddVectorToTail( autoStackDefs[i] );
358+
m_CraftingQueue.Tail()->m_RetryItemList.FastRemove( 1 );
359+
m_CraftingQueue.Tail()->m_RetryItemList.FastRemove( 0 );
360+
}
361+
}
362+
323363
ThreadExecute( WriteInventoryCacheHelper );
324364
}
325365

@@ -1277,6 +1317,7 @@ static class CRD_Inventory_Manager final : public CAutoGameSystem, public CGameE
12771317
case CRAFT_DELETE_SILENT:
12781318
case CRAFT_NOTIFICATION_DYNAMIC_PROPERTY_UPDATE:
12791319
case CRAFT_AUTO_BACKGROUND:
1320+
case CRAFT_AUTO_STACK:
12801321
break;
12811322
default:
12821323
Assert( !"unhandled crafting task type" );
@@ -1313,6 +1354,7 @@ static class CRD_Inventory_Manager final : public CAutoGameSystem, public CGameE
13131354
case CRAFT_DELETE_SILENT:
13141355
case CRAFT_NOTIFICATION_DYNAMIC_PROPERTY_UPDATE:
13151356
case CRAFT_AUTO_BACKGROUND:
1357+
case CRAFT_AUTO_STACK:
13161358
break;
13171359
default:
13181360
Assert( !"unhandled crafting task type" );
@@ -1457,14 +1499,22 @@ static class CRD_Inventory_Manager final : public CAutoGameSystem, public CGameE
14571499
continue;
14581500
}
14591501

1502+
char buf[12]{};
1503+
uint32 len = sizeof( buf );
1504+
int32 quantity = 0;
1505+
if ( pInventory->GetResultItemProperty( pTask->m_hResult, i, "quantity", buf, &len ) )
1506+
{
1507+
quantity = strtol( buf, NULL, 10 );
1508+
}
1509+
14601510
if ( const ItemInstance_t *pCached = GetLocalItemCache( diff[i].m_itemId ) )
14611511
{
1462-
diff[i].m_unQuantity = MAX( 0, int( diff[i].m_unQuantity ) - pCached->Quantity );
1512+
quantity = MAX( 0, quantity - pCached->Quantity );
14631513
}
14641514

14651515
if ( diff[i].m_iDefinition == g_RD_Crafting_Material_Info[eMaterialType].m_iItemDef )
14661516
{
1467-
added = diff[i].m_unQuantity;
1517+
added += quantity;
14681518
}
14691519
}
14701520

@@ -1527,6 +1577,53 @@ static class CRD_Inventory_Manager final : public CAutoGameSystem, public CGameE
15271577
break;
15281578
case CRAFT_AUTO_BACKGROUND:
15291579
break;
1580+
case CRAFT_AUTO_STACK:
1581+
if ( pTask->m_RetryItemList.Count() != 0 )
1582+
{
1583+
uint32 nCount{};
1584+
pInventory->GetResultItems( pTask->m_hResult, NULL, &nCount );
1585+
CUtlVector<SteamItemDetails_t> items;
1586+
items.AddMultipleToTail( nCount );
1587+
pInventory->GetResultItems( pTask->m_hResult, items.Base(), &nCount );
1588+
1589+
SteamItemInstanceID_t iStacked = k_SteamItemInstanceIDInvalid;
1590+
FOR_EACH_VEC( items, i )
1591+
{
1592+
if ( items[i].m_unFlags & ( k_ESteamItemConsumed | k_ESteamItemRemoved ) )
1593+
{
1594+
continue;
1595+
}
1596+
1597+
char buf[12]{};
1598+
uint32 len = sizeof( buf );
1599+
int32 quantity = 0;
1600+
if ( pInventory->GetResultItemProperty( pTask->m_hResult, i, "quantity", buf, &len ) )
1601+
{
1602+
quantity = strtol( buf, NULL, 10 );
1603+
}
1604+
1605+
if ( quantity > 0 )
1606+
{
1607+
Assert( items[i].m_iDefinition == pTask->m_iAccessoryDef );
1608+
Assert( iStacked == k_SteamItemInstanceIDInvalid );
1609+
iStacked = items[i].m_itemId;
1610+
}
1611+
}
1612+
1613+
Assert( iStacked != k_SteamItemInstanceIDInvalid );
1614+
if ( iStacked != k_SteamItemInstanceIDInvalid )
1615+
{
1616+
if ( rd_debug_inventory.GetBool() )
1617+
{
1618+
Msg( "Have %d remaining stacks of auto-stack item %d; merging\n", pTask->m_RetryItemList.Count() + 1, pTask->m_iAccessoryDef );
1619+
}
1620+
1621+
pInventory->TransferItemQuantity( AddCraftItemTask( CRAFT_AUTO_STACK, pTask->m_iAccessoryDef ), pTask->m_RetryItemList[0], GetLocalItemCache( pTask->m_RetryItemList[0] )->Quantity, iStacked );
1622+
m_CraftingQueue.Tail()->m_RetryItemList.AddVectorToTail( pTask->m_RetryItemList );
1623+
m_CraftingQueue.Tail()->m_RetryItemList.FastRemove( 0 );
1624+
}
1625+
}
1626+
break;
15301627
default:
15311628
Assert( !"unhandled crafting task type" );
15321629
break;

src/game/shared/swarm/rd_inventory_shared.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ namespace ReactiveDropInventory
236236
CRAFT_NOTIFICATION_DYNAMIC_PROPERTY_UPDATE,
237237
// automated actions, like upgrading stacks of medals after a player has added a new color to the stack.
238238
CRAFT_AUTO_BACKGROUND,
239+
// automatically fixing auto-stack items that are in separate piles.
240+
CRAFT_AUTO_STACK,
239241
};
240242
void PerformCraftingAction( CraftItemType_t eCraftType, SteamItemDef_t recipe, std::initializer_list<SteamItemInstanceID_t> ingredient, std::initializer_list<uint32> quantity, SteamItemDef_t iAccessoryDef = 0, SteamItemInstanceID_t iReplaceItemInstance = k_SteamItemInstanceIDInvalid );
241243
void RequestFullInventoryRefresh();

0 commit comments

Comments
 (0)