From 2b7e5e095ffe93164414b566ca85662a2cb68b8b Mon Sep 17 00:00:00 2001 From: Hank Jordan Date: Mon, 6 Apr 2026 22:16:44 -0400 Subject: [PATCH] quickplay --- src/game/client/client_tf.vpc | 3 ++ src/game/client/tf/tf_quickplay_ui.cpp | 40 ++++++++++--------- .../tf/vgui/tf_matchmaking_dashboard.cpp | 6 +++ .../client/tf/vgui/tf_matchmaking_dashboard.h | 1 + .../tf_matchmaking_dashboard_playlist.cpp | 5 +++ src/game/shared/tf/tf_item_schema.cpp | 3 ++ src/game/shared/tf/tf_item_schema.h | 2 + src/game/shared/tf/tf_quickplay_shared.h | 2 +- 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/game/client/client_tf.vpc b/src/game/client/client_tf.vpc index 1143ff28d9f..eb31b40c3c5 100644 --- a/src/game/client/client_tf.vpc +++ b/src/game/client/client_tf.vpc @@ -416,6 +416,8 @@ $Project "Client (TF)" $File "$SRCDIR\game\shared\tf\tf_gamestats_shared.h" $File "tf\tf_hud_mainmenuoverride.cpp" $File "tf\tf_hud_mainmenuoverride.h" + $File "tf\tf_quickplay_ui.cpp" + $File "tf\tf_quickplay.h" $File "tf\tf_hud_minigame.cpp" $File "tf\tf_hud_minigame.h" $File "tf\tf_hud_saxxycontest.cpp" @@ -943,6 +945,7 @@ $Project "Client (TF)" $File "$SRCDIR\game\shared\tf\tf_lobby_shared.h" $File "$SRCDIR\game\shared\tf\tf_matchmaking_shared.h" $File "$SRCDIR\game\shared\tf\tf_matchmaking_shared.cpp" + $File "$SRCDIR\game\shared\tf\tf_quickplay_shared.h" $File "$SRCDIR\game\shared\tf\tf_gc_shared.h" $File "$SRCDIR\game\shared\tf\tf_gc_shared.cpp" $File "$SRCDIR\game\shared\tf\tf_match_description.cpp" diff --git a/src/game/client/tf/tf_quickplay_ui.cpp b/src/game/client/tf/tf_quickplay_ui.cpp index 8516dcf8d6c..970f84977b9 100644 --- a/src/game/client/tf/tf_quickplay_ui.cpp +++ b/src/game/client/tf/tf_quickplay_ui.cpp @@ -11,6 +11,8 @@ #include "tf_item_inventory.h" #include "econ_game_account_server.h" #include "gc_clientsystem.h" +#include "tf_gc_client.h" +#include "tf_partyclient.h" #include "tf_quickplay.h" // ui related @@ -139,7 +141,7 @@ static bool BHasTag( const CUtlStringList &TagList, const char *tag ) static void GetQuickplayTags( const QuickplaySearchOptions &opt, CUtlStringList &requiredTags, CUtlStringList &illegalTags ) { // Always required - requiredTags.CopyAndAddToTail( "_registered" ); + // requiredTags.CopyAndAddToTail( "_registered" ); // Always illegal illegalTags.CopyAndAddToTail( "friendlyfire" ); @@ -1308,7 +1310,7 @@ class CQuickplayWaitDialog : public CGenericWaitingDialog, public ISteamMatchmak // Check if the server is registered item.m_bRegistered = BHasTag( TagList, "_registered" ); - const SchemaMap_t *pMapInfo = GetItemSchema()->GetMapForName( item.server.m_szMap ); + const MapDef_t *pMapInfo = GetItemSchema()->GetMasterMapDefByName( item.server.m_szMap ); if ( pMapInfo != NULL ) { item.m_bMapIsQuickPlayOK = true; @@ -1338,7 +1340,8 @@ class CQuickplayWaitDialog : public CGenericWaitingDialog, public ISteamMatchmak switch ( m_options.m_eSelectedGameType ) { case kGameCategory_EventMix: - if ( pMapInfo->eGameCategory != kGameCategory_EventMix && pMapInfo->eGameCategory != kGameCategory_Event247 ) + if ( !pMapInfo->m_vecAssociatedGameCategories.HasElement( kGameCategory_EventMix ) + && !pMapInfo->m_vecAssociatedGameCategories.HasElement( kGameCategory_Event247 ) ) failureCodes |= (1<<12); break; @@ -1348,11 +1351,12 @@ class CQuickplayWaitDialog : public CGenericWaitingDialog, public ISteamMatchmak default: // Must match requested game mode - if ( pMapInfo->eGameCategory != m_options.m_eSelectedGameType ) + if ( !pMapInfo->m_vecAssociatedGameCategories.HasElement( m_options.m_eSelectedGameType ) ) failureCodes |= (1<<12); } } - if ( server.m_nPlayers >= server.m_nMaxPlayers ) failureCodes |= (1<<11); + int nNumInSearchParty = GTFPartyClient()->GetNumPartyMembers(); + if ( server.m_nPlayers + nNumInSearchParty > server.m_nMaxPlayers ) failureCodes |= (1<<11); if ( m_blackList.IsServerBlacklisted( server ) ) failureCodes |= (1<<10); if ( failureCodes != 0 ) @@ -1373,7 +1377,6 @@ class CQuickplayWaitDialog : public CGenericWaitingDialog, public ISteamMatchmak // Start a score based only on the server, not on us int nHumans = item.server.m_nPlayers - item.server.m_nBotPlayers; - int nNumInSearchParty = 1; // we are a party of 1 item.serverScore = QuickplayCalculateServerScore( nHumans, item.server.m_nBotPlayers, item.server.m_nMaxPlayers, nNumInSearchParty ); item.serverScore += 6.0f; // !KLUDGE! Add offset to keep score ranges comparable with historical norms. (We used to give bonuses for some things we now simply require.) @@ -1609,17 +1612,18 @@ class CQuickplayWaitDialog : public CGenericWaitingDialog, public ISteamMatchmak static void AddMapsFilter( CUtlVector &vecServerFilters, EGameCategory t ) { CUtlString sMapList; - for ( int i = 0 ; i < GetItemSchema()->GetMapCount() ; ++i ) + const CUtlVector &vecMaps = GetItemSchema()->GetMasterMapsList(); + FOR_EACH_VEC( vecMaps, i ) { - const SchemaMap_t& map = GetItemSchema()->GetMapForIndex( i ); - int mapType = map.eGameCategory; - if ( ( mapType == t ) || ( ( mapType == kGameCategory_Event247 ) && ( t == kGameCategory_EventMix ) ) ) + const MapDef_t *pMapDef = vecMaps[i]; + if ( pMapDef->m_vecAssociatedGameCategories.HasElement( t ) + || ( ( t == kGameCategory_EventMix ) && pMapDef->m_vecAssociatedGameCategories.HasElement( kGameCategory_Event247 ) ) ) { if ( !sMapList.IsEmpty() ) { sMapList.Append( "," ); } - sMapList.Append( map.pszMapName ); + sMapList.Append( pMapDef->pszMapName ); } } MatchMakingKeyValuePair_t kludge; @@ -2847,22 +2851,20 @@ class CQuickplayDialog : public CQuickplayPanelBase int nNumForThisMode = 0; // Go through each of the modes - for ( int j = 0 ; j < GetItemSchema()->GetMapCount(); ++j ) + const CUtlVector &vecMaps = GetItemSchema()->GetMasterMapsList(); + FOR_EACH_VEC( vecMaps, j ) { - const SchemaMap_t& map = GetItemSchema()->GetMapForIndex( j ); + const MapDef_t *pMapDef = vecMaps[j]; // Tally up maps for this mode - if ( map.eGameCategory == m_vecAllItems[i].gameType ) + if ( pMapDef->m_vecAssociatedGameCategories.HasElement( m_vecAllItems[i].gameType ) ) { nNumForThisMode++; // Check if any of the tags has "beta" as a tag, and tally that if so - for( int k = 0; k < map.vecTags.Count(); ++k ) + if ( pMapDef->vecTags.HasElement( GetItemSchema()->GetHandleForTag( "beta" ) ) ) { - if ( map.vecTags.HasElement( GetItemSchema()->GetHandleForTag( "beta" ) ) ) - { - nNumWithBetaContent++; - } + nNumWithBetaContent++; } } } diff --git a/src/game/client/tf/vgui/tf_matchmaking_dashboard.cpp b/src/game/client/tf/vgui/tf_matchmaking_dashboard.cpp index faa84c08761..527bb953a0f 100644 --- a/src/game/client/tf/vgui/tf_matchmaking_dashboard.cpp +++ b/src/game/client/tf/vgui/tf_matchmaking_dashboard.cpp @@ -921,6 +921,12 @@ void CTFMatchmakingDashboard::OnPlayCommunity() engine->ClientCmd_Unrestricted( "gamemenucommand openserverbrowser" ); } +void CTFMatchmakingDashboard::OnPlayQuickplay() +{ + ClearAllStacks(); + engine->ClientCmd_Unrestricted( "OpenQuickplayDialog" ); +} + void CTFMatchmakingDashboard::OnCreateServer() { ClearAllStacks(); diff --git a/src/game/client/tf/vgui/tf_matchmaking_dashboard.h b/src/game/client/tf/vgui/tf_matchmaking_dashboard.h index 160f2ef02aa..1ab1189f7ee 100644 --- a/src/game/client/tf/vgui/tf_matchmaking_dashboard.h +++ b/src/game/client/tf/vgui/tf_matchmaking_dashboard.h @@ -130,6 +130,7 @@ class CTFMatchmakingDashboard : public CExpandablePanel MESSAGE_FUNC( OnPlayMvM, "PlayMvM" ); MESSAGE_FUNC( OnPlayMvM_MannUp, "PlayMvM_MannUp" ); MESSAGE_FUNC( OnPlayMvM_BootCamp, "PlayMvM_BootCamp" ); + MESSAGE_FUNC( OnPlayQuickplay, "PlayQuickplay" ); MESSAGE_FUNC( OnPlayTraining, "PlayTraining" ); MESSAGE_FUNC( OnPlayCommunity, "PlayCommunity" ); MESSAGE_FUNC( OnCreateServer, "CreateServer" ); diff --git a/src/game/client/tf/vgui/tf_matchmaking_dashboard_playlist.cpp b/src/game/client/tf/vgui/tf_matchmaking_dashboard_playlist.cpp index 4209d24ebe3..e9377af099e 100644 --- a/src/game/client/tf/vgui/tf_matchmaking_dashboard_playlist.cpp +++ b/src/game/client/tf/vgui/tf_matchmaking_dashboard_playlist.cpp @@ -599,6 +599,11 @@ void CTFPlaylistPanel::OnCommand( const char *command ) PostActionSignal( new KeyValues( "PlayMvM" ) ); return; } + else if ( FStrEq( "play_quickplay", command ) ) + { + PostActionSignal( new KeyValues( "PlayQuickplay" ) ); + return; + } else if ( FStrEq( "play_training", command ) ) { PostActionSignal( new KeyValues( "PlayTraining" ) ); diff --git a/src/game/shared/tf/tf_item_schema.cpp b/src/game/shared/tf/tf_item_schema.cpp index 282ce03d286..49ccfc6563a 100644 --- a/src/game/shared/tf/tf_item_schema.cpp +++ b/src/game/shared/tf/tf_item_schema.cpp @@ -2005,6 +2005,9 @@ bool CTFItemSchema::BInitMaps( KeyValues *pKVMaps, CUtlVector *pVecE pMap->pszStrangePrefixLocKey = pKVMap->GetString( "strangeprefixtoken", NULL ); pMap->m_nStatsIdentifier = pKVMap->GetInt( "statsidentifier", -1 ); + int iQuickplayType = StringFieldToInt( pKVMap->GetString( "quickplay_type", NULL ), s_pszQuickplayMatchTypes, ARRAYSIZE( s_pszQuickplayMatchTypes ), true ); + pMap->eQuickplayType = ( iQuickplayType != -1 ) ? (eQuickplayMatchType)iQuickplayType : kQuickplay_Disabled; + // initialize from optional "tags" block KeyValues *pKVTags = pKVMap->FindKey( "tags" ); if ( pKVTags ) diff --git a/src/game/shared/tf/tf_item_schema.h b/src/game/shared/tf/tf_item_schema.h index be62d6a8aa8..ed08b787904 100644 --- a/src/game/shared/tf/tf_item_schema.h +++ b/src/game/shared/tf/tf_item_schema.h @@ -489,6 +489,7 @@ struct MapDef_t MapDef_t( const char* pszMapStampDefName ) : mapStampDef( pszMapStampDefName ) , m_nStatsIdentifier( (MapDefIndex_t)-1 ) + , eQuickplayType( kQuickplay_Disabled ) {} CSchemaItemDefHandle mapStampDef; @@ -508,6 +509,7 @@ struct MapDef_t map_identifier_t m_nStatsIdentifier; map_identifier_t GetStatsIdentifier() const { return m_nStatsIdentifier == -1 ? (m_nDefIndex << 16) : m_nStatsIdentifier; } bool IsCommunityMap() const { return pszAuthorsLocKey != NULL; } + eQuickplayMatchType eQuickplayType; CUtlVector< EGameCategory > m_vecAssociatedGameCategories; CUtlVector vecTags; // The rolling match tags for this map. When a rolling match vote happens, only allow voting on diff --git a/src/game/shared/tf/tf_quickplay_shared.h b/src/game/shared/tf/tf_quickplay_shared.h index 51eef5e1096..5ca4200a057 100644 --- a/src/game/shared/tf/tf_quickplay_shared.h +++ b/src/game/shared/tf/tf_quickplay_shared.h @@ -18,7 +18,7 @@ const int kTFQuickPlayIdealMaxNumberOfPlayers = 24; const int kTFQuickPlayMinMaxNumberOfPlayers = 18; // don't auto match to servers with max players set too low const int kTFQuickPlayMaxPlayers = 33; -const struct SchemaMap_t *GetQuickplayMapInfoByName( const char *pMapName ); +const struct MapDef_t *GetQuickplayMapInfoByName( const char *pMapName ); extern float QuickplayCalculateServerScore( int numHumans, int numBots, int maxPlayers, int nNumInSearchParty );