diff --git a/src/game/client/tf/tf_partyclient.cpp b/src/game/client/tf/tf_partyclient.cpp index b54143b8bf..da865801d9 100644 --- a/src/game/client/tf/tf_partyclient.cpp +++ b/src/game/client/tf/tf_partyclient.cpp @@ -103,8 +103,7 @@ ConVar tf_party_join_request_mode( "tf_party_join_request_mode", "-1", FCVAR_ARC ConVar tf_party_ignore_invites( "tf_party_ignore_invites", "0", FCVAR_ARCHIVE, "If set, ignore incoming party invites", OnPartyClientPrefConVarChanged ); -// TODO(Universal Parties): Hook up and enable in UI -ConVar tf_party_keep_on_same_team( "tf_party_keep_on_same_team", "0", FCVAR_ARCHIVE ); +ConVar tf_party_keep_on_same_team( "tf_party_keep_on_same_team", "1", FCVAR_ARCHIVE ); //----------------------------------------------------------------------------- // Popup dialog for MM errors with an optional clickable url @@ -1019,6 +1018,9 @@ void CTFPartyClient::ReadConVarPreferences() // Ignore incoming invites SetIgnorePartyInvites( tf_party_ignore_invites.GetBool() ); + + // Keep party on same team + SetKeepPartyOnSameTeam( tf_party_keep_on_same_team.GetBool() ); } //----------------------------------------------------------------------------- @@ -1057,6 +1059,26 @@ void CTFPartyClient::SetIgnorePartyInvites( bool bIgnore ) } } +//----------------------------------------------------------------------------- +bool CTFPartyClient::GetKeepPartyOnSameTeam() const +{ + return m_bKeepPartyOnSameTeam; +} + +//----------------------------------------------------------------------------- +void CTFPartyClient::SetKeepPartyOnSameTeam( bool bKeepPartyOnSameTeam ) +{ + if ( m_bKeepPartyOnSameTeam != bKeepPartyOnSameTeam ) + { + m_bKeepPartyOnSameTeam = bKeepPartyOnSameTeam; + MutLocalGroupCriteria().SetKeepPartyOnSameTeam( bKeepPartyOnSameTeam ); + + // This will trigger a OnChanged and call us again, make sure we set the mode first so we don't get in a loop. + tf_party_keep_on_same_team.SetValue( bKeepPartyOnSameTeam ); + OnPartyPrefChanged(); + } +} + //----------------------------------------------------------------------------- bool CTFPartyClient::BInQueueForMatchGroup( ETFMatchGroup eMatchGroup ) const { diff --git a/src/game/client/tf/tf_partyclient.h b/src/game/client/tf/tf_partyclient.h index eec48865f8..a1d012449a 100644 --- a/src/game/client/tf/tf_partyclient.h +++ b/src/game/client/tf/tf_partyclient.h @@ -110,6 +110,10 @@ class CTFPartyClient : private CAutoGameSystemPerFrame, private CLocalSteamShare EPartyJoinRequestMode GetPartyJoinRequestMode() const; void SetPartyJoinRequestMode( EPartyJoinRequestMode ); + + bool GetKeepPartyOnSameTeam() const; + void SetKeepPartyOnSameTeam( bool bKeepPartyOnSameTeam ); + bool GetIgnorePartyInvites() const; void SetIgnorePartyInvites( bool bIgnore ); @@ -438,6 +442,9 @@ class CTFPartyClient : private CAutoGameSystemPerFrame, private CLocalSteamShare // (new session, leader changed, etc) bool m_bSentInitialCriteria = false; + // Whether auto-balance should try to keep members of this party on the same team. + bool m_bKeepPartyOnSameTeam = true; + // Cached criteria object from party updates CTFGroupMatchCriteria m_activePartyCriteria; diff --git a/src/game/client/tf/vgui/tf_ping_panel.cpp b/src/game/client/tf/vgui/tf_ping_panel.cpp index 19117bd114..b0ca253902 100644 --- a/src/game/client/tf/vgui/tf_ping_panel.cpp +++ b/src/game/client/tf/vgui/tf_ping_panel.cpp @@ -69,13 +69,6 @@ void CTFPingPanel::ApplySchemeSettings( IScheme *pScheme ) m_pIgnoreInvitesCheckBox = FindControl< CvarToggleCheckButton >( "IgnorePartyInvites", true ); m_pKeepTeamTogetherCheckBox = FindControl< CvarToggleCheckButton >( "KeepPartyOnSameTeam", true ); - if ( m_pKeepTeamTogetherCheckBox ) - { - m_pKeepTeamTogetherCheckBox->SetSelected( true ); - m_pKeepTeamTogetherCheckBox->SetEnabled( false ); - m_pKeepTeamTogetherCheckBox->SetTooltip( GetDashboardTooltip( k_eMediumFont ), "#TF_MM_ComingSoon" ); - } - RegeneratePingPanels(); m_pPingSlider->AddActionSignalTarget( this ); } diff --git a/src/game/server/tf/tf_autobalance.cpp b/src/game/server/tf/tf_autobalance.cpp index d88515a98f..d6c7aa5a03 100644 --- a/src/game/server/tf/tf_autobalance.cpp +++ b/src/game/server/tf/tf_autobalance.cpp @@ -13,6 +13,7 @@ #include "minigames/tf_duel.h" #include "player_resource.h" #include "tf_player_resource.h" +#include "tf_party.h" // memdbgon must be the last include file in a .cpp file!!! #include @@ -299,7 +300,7 @@ bool CTFAutobalance::ValidateCandidates() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -CTFPlayer *CTFAutobalance::FindNextCandidate() +CTFPlayer *CTFAutobalance::FindNextCandidate( bool bKeepPartiesOnSameTeam ) { CTFPlayer *pRetVal = NULL; @@ -313,6 +314,22 @@ CTFPlayer *CTFAutobalance::FindNextCandidate() CTFPlayer *pTFPlayer = ToTFPlayer( pTeam->GetPlayer( i ) ); if ( pTFPlayer && !IsAlreadyCandidate( pTFPlayer ) && pTFPlayer->CanBeAutobalanced() ) { + if ( bKeepPartiesOnSameTeam ) + { + // disqualify this player if they are in a party of 2 or more that wants to be kept on the same team. + CSteamID steamId; + + if ( pTFPlayer->GetSteamID( &steamId ) ) + { + CTFParty* pTFParty = GTFGCClientSystem()->GetPartyForPlayer( steamId ); + + if ( pTFParty && pTFParty->GetNumMembers() > 1 && pTFParty->GetKeepPartyOnSameTeam() ) + { + continue; + } + } + } + vecCandidates.AddToTail( pTFPlayer ); } } @@ -369,7 +386,15 @@ bool CTFAutobalance::FindCandidates() while ( nNumFound < nTotal ) { - CTFPlayer *pTFPlayer = FindNextCandidate(); + // find a candidate that is not currently in a party + CTFPlayer *pTFPlayer = FindNextCandidate( true ); + + if ( !pTFPlayer ) + { + // everyone is in a party, we have no choice but to split (?) + pTFPlayer = FindNextCandidate( false ); + } + if ( pTFPlayer ) { // the best candidates are towards the tail of the list so diff --git a/src/game/server/tf/tf_autobalance.h b/src/game/server/tf/tf_autobalance.h index 3329fa5b52..22a0426eba 100644 --- a/src/game/server/tf/tf_autobalance.h +++ b/src/game/server/tf/tf_autobalance.h @@ -55,7 +55,7 @@ class CTFAutobalance : public CAutoGameSystemPerFrame bool IsAlreadyCandidate( CTFPlayer *pTFPlayer ) const; double GetTeamAutoBalanceScore( int nTeam ) const; double GetPlayerAutoBalanceScore( CTFPlayer *pTFPlayer ) const; - CTFPlayer *FindNextCandidate(); + CTFPlayer *FindNextCandidate( bool bKeepPartiesOnSameTeam ); bool FindCandidates(); bool ValidateCandidates(); diff --git a/src/game/shared/tf/tf_gcmessages.proto b/src/game/shared/tf/tf_gcmessages.proto index 568afe5571..2538483554 100644 --- a/src/game/shared/tf/tf_gcmessages.proto +++ b/src/game/shared/tf/tf_gcmessages.proto @@ -1033,6 +1033,7 @@ message CTFGroupMatchCriteriaProto // optional TF_MatchmakingMode matchmaking_mode = 7; optional bool late_join_ok = 5; // Is my party willing to join late? optional uint32 custom_ping_tolerance = 13 [ default = 0 ]; // 0 == no custom tolerance + optional bool keep_party_on_same_team = 17 [ default = true ]; // Should auto-balance try to avoid splitting party members up? // Deprecated - with multi-queue, you are no longer locked to one match group, and criteria is universal (not one // per match-group) diff --git a/src/game/shared/tf/tf_matchcriteria.cpp b/src/game/shared/tf/tf_matchcriteria.cpp index 4a6ddbb535..304d24c118 100644 --- a/src/game/shared/tf/tf_matchcriteria.cpp +++ b/src/game/shared/tf/tf_matchcriteria.cpp @@ -124,6 +124,15 @@ void ITFGroupMatchCriteria::SetCustomPingTolerance( uint32_t unCustomPingToleran } } +//----------------------------------------------------------------------------- +void ITFGroupMatchCriteria::SetKeepPartyOnSameTeam( bool bKeepPartyOnSameTeam ) +{ + if ( Proto().keep_party_on_same_team() != bKeepPartyOnSameTeam ) + { + MutProto().set_keep_party_on_same_team( bKeepPartyOnSameTeam ); + } +} + //----------------------------------------------------------------------------- void ITFGroupMatchCriteria::SetCasualMapSelected( uint32 nMapDefIndex, bool bSelected ) { diff --git a/src/game/shared/tf/tf_matchcriteria.h b/src/game/shared/tf/tf_matchcriteria.h index 9c52831d20..14c4b4b77d 100644 --- a/src/game/shared/tf/tf_matchcriteria.h +++ b/src/game/shared/tf/tf_matchcriteria.h @@ -120,6 +120,7 @@ class ITFGroupMatchCriteria : public ITFGroupMatchCriteriaReader void SetLateJoin( bool bLateJoin ); void SetCustomPingTolerance( uint32_t unCustomPingTolerance ); + void SetKeepPartyOnSameTeam( bool bKeepPartyOnSameTeam ); void SetCasualMapSelected( uint32 nMapDefIndex, bool bSelected ); void SetCasualGroupSelected( EMatchmakingGroupType eGroup, bool bSelected ); void SetCasualCategorySelected( EGameCategory eCategory, bool bSelected ); diff --git a/src/game/shared/tf/tf_party.h b/src/game/shared/tf/tf_party.h index 61b429741a..6da1ff8352 100644 --- a/src/game/shared/tf/tf_party.h +++ b/src/game/shared/tf/tf_party.h @@ -42,6 +42,7 @@ class CTFParty : public GCSDK::CProtoBufSharedObject