summaryrefslogtreecommitdiff
path: root/game/client/tf/tf_hud_mann_vs_machine_victory.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_hud_mann_vs_machine_victory.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/tf_hud_mann_vs_machine_victory.cpp')
-rw-r--r--game/client/tf/tf_hud_mann_vs_machine_victory.cpp2049
1 files changed, 2049 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_mann_vs_machine_victory.cpp b/game/client/tf/tf_hud_mann_vs_machine_victory.cpp
new file mode 100644
index 0000000..f557d41
--- /dev/null
+++ b/game/client/tf/tf_hud_mann_vs_machine_victory.cpp
@@ -0,0 +1,2049 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Scoreboard for MvM
+//
+// $NoKeywords: $
+//=============================================================================
+#include "cbase.h"
+#include "tf_hud_mann_vs_machine_victory.h"
+#include "tf_playermodelpanel.h"
+#include "econ_item_inventory.h"
+#include "vgui/IInput.h"
+#include "vgui_controls/PanelListPanel.h"
+#include "tf_particlepanel.h"
+#include "engine/IEngineSound.h"
+#include "econ_notifications.h"
+#include "tf_hud_mann_vs_machine_status.h"
+#include "tf_lobby_server.h"
+
+using namespace vgui;
+extern const ConVar *sv_cheats;
+
+#define MVM_PLAYER_COUNT 6
+#define SQUAD_SURPLUS_COUNT 6
+
+//#define WAVE_SUMMARY_TOTAL_TIME 5.0f;
+#define CREDITS_COLLECTED_TIME 2.0f
+#define CREDITS_MISSED_TIME 1.0f
+#define CREDITS_BONUS_TIME 0.5f
+#define RATING_LABEL_TIME 0.5f
+#define RATING_SCORE_TIME 0.5f
+#define SHORT_TIME 0.5f
+
+#define RATING_LABEL_TIME 0.5f
+#define RATING_SCORE_TIME 0.5f
+
+#define WAIT_TIME 12.0f
+
+#define STARTING_LOOT_PAUSE_TIME 2.f
+
+// String constants that match variable names in .res files
+#define CREDITS_COLLECTED_STR "creditscollected"
+#define CREDITS_MISSED_STR "creditsmissed"
+#define CREDITS_BONUS_STR "creditbonus"
+
+#define YOUR_UPGRADES_STR "upgrades"
+#define YOUR_BUYBACKS_STR "buybacks"
+#define YOUR_BOTTLES_STR "bottles"
+
+#define RATING_LABEL_STR "ratinglabel"
+#define RATING_SCORE_STR "ratingscore"
+
+
+#ifdef STAGING_ONLY
+ConVar tf_mvm_fake_loot( "tf_mvm_fake_loot", "0" );
+#endif
+
+extern const char *g_szItemBorders[AE_MAX_TYPES][5];
+extern int g_iLegacyClassSelectWeaponSlots[TF_LAST_NORMAL_CLASS];
+
+class CShowMannUpLootNotification : public CEconNotification
+{
+public:
+ CShowMannUpLootNotification()
+ {
+ m_pObjective = TFObjectiveResource();
+ }
+
+ virtual EType NotificationType() { return eType_AcceptDecline; }
+ virtual bool BShowInGameElements() const OVERRIDE { return true; }
+
+ virtual void Accept() OVERRIDE
+ {
+ CTFHudMannVsMachineStatus *pMannVsMachineStatus = GET_HUDELEMENT( CTFHudMannVsMachineStatus );
+ if ( pMannVsMachineStatus && TFObjectiveResource() )
+ {
+ pMannVsMachineStatus->ReopenVictoryPanel();
+ }
+
+ MarkForDeletion();
+ }
+
+ virtual void Decline() OVERRIDE
+ {
+ MarkForDeletion();
+ }
+
+ virtual void Trigger() OVERRIDE { Accept(); }
+ virtual void UpdateTick() OVERRIDE
+ {
+ CTFHudMannVsMachineStatus *pMannVsMachineStatus = GET_HUDELEMENT( CTFHudMannVsMachineStatus );
+ if ( !pMannVsMachineStatus || !pMannVsMachineStatus->IsVisible() || m_pObjective != TFObjectiveResource() )
+ {
+ MarkForDeletion();
+ }
+ }
+
+ static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast< CShowMannUpLootNotification *>( pNotification ) != NULL; }
+ const C_TFObjectiveResource* m_pObjective;
+
+};
+
+//-----------------------------------------------------------------------------
+// CVictoryPanel
+//-----------------------------------------------------------------------------
+DECLARE_BUILD_FACTORY( CVictoryPanel );
+
+CVictoryPanel::CVictoryPanel( Panel *parent, const char *pName )
+ : vgui::EditablePanel( parent, pName )
+ , m_pHeaderContainer( NULL )
+ , m_pCreditContainerPanel( NULL )
+ , m_pTotalGameCreditSpendPanel( NULL )
+ , m_pTeamStatsContainerPanel( NULL)
+ , m_pYourStatsContainerPanel( NULL)
+ , m_pRatingContainerPanel( NULL)
+ , m_pDoneButton( NULL)
+{
+ SetMouseInputEnabled( true );
+
+ m_pDoneButton = new CExImageButton( this, "DoneButton", g_pVGuiLocalize->Find( "#DoneButton" ), this );
+}
+
+//-----------------------------------------------------------------------------
+void CVictoryPanel::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ LoadControlSettings( "resource/UI/MvMVictoryPanel.res" );
+
+ m_pDoneButton->AddActionSignalTarget( GetParent() );
+
+ CExButton *pButton = dynamic_cast<CExButton*>( FindChildByName("DoneButton") );
+ if ( pButton )
+ {
+ pButton->AddActionSignalTarget( this );
+ }
+
+ vgui::EditablePanel* pStatsContainer = dynamic_cast<vgui::EditablePanel*>( FindChildByName("StatsContainer") );
+ if ( pStatsContainer )
+ {
+ m_pHeaderContainer = dynamic_cast<vgui::EditablePanel*>( pStatsContainer->FindChildByName("HeaderContainer") );
+ m_pCreditContainerPanel = dynamic_cast<vgui::EditablePanel*>( pStatsContainer->FindChildByName("CreditContainer") );
+ m_pRatingContainerPanel = dynamic_cast<vgui::EditablePanel*>( pStatsContainer->FindChildByName("RatingContainer") );
+ m_pTotalGameCreditSpendPanel = dynamic_cast<CCreditSpendPanel*>( pStatsContainer->FindChildByName("TotalGameCreditSpendPanel") );
+ }
+
+ if ( m_pCreditContainerPanel )
+ {
+ m_pCreditContainerPanel->SetDialogVariable( "header", "" );
+ m_pCreditContainerPanel->SetDialogVariable( "rating", "" );
+ m_pCreditContainerPanel->SetDialogVariable( "ratingshadow", "" );
+ }
+
+ if ( m_pTotalGameCreditSpendPanel )
+ {
+ m_pTotalGameCreditSpendPanel->SetDialogVariable( "header", "" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CVictoryPanel::OnTick( void )
+{
+ if ( m_eState == FINISHED )
+ return;
+
+ m_fStateRunningTime += gpGlobals->curtime - m_fPreviousTick;
+ m_fPreviousTick = gpGlobals->curtime;
+
+ // Run through animation loop
+ switch ( m_eState )
+ {
+ case CREDITS_COLLECT:
+ StateUpdateValue ( m_pCreditContainerPanel, CREDITS_COLLECTED_STR, CREDITS_COLLECTED_TIME, m_fStateRunningTime, CREDITS_MISSED, m_nCreditsCollected );
+ break;
+ case CREDITS_MISSED:
+ StateUpdateValue ( m_pCreditContainerPanel, CREDITS_MISSED_STR, CREDITS_MISSED_TIME, m_fStateRunningTime, CREDITS_BONUS, m_nCreditsMissed );
+ break;
+ case CREDITS_BONUS:
+ StateUpdateValue ( m_pCreditContainerPanel, CREDITS_BONUS_STR, CREDITS_BONUS_TIME, m_fStateRunningTime, YOUR_UPGRADES, m_nCreditBonus );
+ break;
+ case YOUR_UPGRADES:
+ StateUpdateValue ( m_pTotalGameCreditSpendPanel, YOUR_UPGRADES_STR, SHORT_TIME, m_fStateRunningTime, YOUR_BUYBACK, m_nYourUpgradeCredits );
+ break;
+ case YOUR_BUYBACK:
+ StateUpdateValue ( m_pTotalGameCreditSpendPanel, YOUR_BUYBACKS_STR, SHORT_TIME, m_fStateRunningTime, YOUR_BOTTLES, m_nYourBuybacksCredits );
+ break;
+ case YOUR_BOTTLES:
+ StateUpdateValue ( m_pTotalGameCreditSpendPanel, YOUR_BOTTLES_STR, SHORT_TIME, m_fStateRunningTime, RATING_LABEL, m_nYourBottlesCredits );
+ break;
+ case RATING_LABEL:
+ RatingLabelUpdate();
+ CheckState( RATING_LABEL_TIME, m_fStateRunningTime, RATING_SCORE );
+ break;
+ case RATING_SCORE:
+ RatingScoreUpdate();
+ CheckState( RATING_SCORE_TIME, m_fStateRunningTime, FINISHED );
+ break;
+
+ default:
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CVictoryPanel::ResetVictoryPanel()
+{
+ m_fStateRunningTime = 0;
+
+ if ( m_pCreditContainerPanel )
+ {
+ // Set all the values to empty strings
+ m_pCreditContainerPanel->SetDialogVariable( CREDITS_COLLECTED_STR, "" );
+ m_pCreditContainerPanel->SetDialogVariable( CREDITS_MISSED_STR, "" );
+ m_pCreditContainerPanel->SetDialogVariable( CREDITS_BONUS_STR, "" );
+ }
+
+ if ( m_pTotalGameCreditSpendPanel )
+ {
+ m_pTotalGameCreditSpendPanel->SetDialogVariable( YOUR_UPGRADES_STR, "" );
+ m_pTotalGameCreditSpendPanel->SetDialogVariable( YOUR_BUYBACKS_STR, "" );
+ m_pTotalGameCreditSpendPanel->SetDialogVariable( YOUR_BOTTLES_STR, "" );
+ }
+
+ if ( m_pRatingContainerPanel )
+ {
+ m_pRatingContainerPanel->SetDialogVariable( RATING_LABEL_STR, "" );
+ m_pRatingContainerPanel->SetDialogVariable( RATING_SCORE_STR, "" );
+ }
+
+ m_eState = CREDITS_COLLECT;
+ m_fStateRunningTime = 0;
+ m_fPreviousTick = gpGlobals->curtime;
+
+ CaptureStats();
+}
+
+//-----------------------------------------------------------------------------
+void CVictoryPanel::SetMapAndPopFile ( )
+{
+ // Map Name
+ char szTempMapName[MAX_PATH];
+ Q_FileBase( engine->GetLevelName(), szTempMapName, sizeof ( szTempMapName ) );
+
+ wchar_t wszMapName[MAX_PATH];
+ g_pVGuiLocalize->ConvertANSIToUnicode( GetMapDisplayName( szTempMapName ), wszMapName, sizeof(wszMapName) );
+
+ char szTempName[MAX_PATH];
+ V_FileBase( TFObjectiveResource()->GetMvMPopFileName(), szTempName, sizeof( szTempName ) );
+ int iMissionIndex = GetItemSchema()->FindMvmMissionByName( szTempName );
+
+ wchar_t wszLocalizedSummary[ 256 ];
+
+ if ( GetItemSchema()->GetMvmMissions().IsValidIndex( iMissionIndex ) )
+ {
+ const MvMMission_t &mission = GetItemSchema()->GetMvmMissions()[ iMissionIndex ];
+ g_pVGuiLocalize->ConstructString_safe( wszLocalizedSummary, L"%s1 : %s2", 2,
+ wszMapName, g_pVGuiLocalize->Find( mission.m_sDisplayName.Get() ) );
+ }
+ else
+ {
+ //Popfile
+ wchar_t wszPopFileName[MAX_PATH];
+ g_pVGuiLocalize->ConvertANSIToUnicode( GetMapDisplayName(szTempName), wszPopFileName, sizeof(wszPopFileName) );
+
+ g_pVGuiLocalize->ConstructString_safe( wszLocalizedSummary, L"%s1 : %s2", 2,
+ wszMapName, wszPopFileName );
+ }
+
+ if ( m_pHeaderContainer )
+ {
+ m_pHeaderContainer->SetDialogVariable( "header", wszLocalizedSummary );
+ m_pHeaderContainer->SetDialogVariable( "headershadow", wszLocalizedSummary );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose : Save all the stats info incase they reset (Lvl reset) while this screen is active
+//-----------------------------------------------------------------------------
+void CVictoryPanel::CaptureStats()
+{
+ CMannVsMachineStats *pStats = MannVsMachineStats_GetInstance();
+ if ( !pStats )
+ return;
+
+ int nAcquired = pStats->GetAcquiredCredits( -1, false );
+ int nDropped = pStats->GetDroppedCredits( -1 );
+ int nMissed = nDropped - nAcquired;
+ int nBonus = pStats->GetBonusCredits( -1 );
+
+ m_nCreditsCollected = nAcquired;
+ m_nCreditsMissed = nMissed;
+ m_nCreditBonus = nBonus;
+
+ m_nYourBuybacksCredits = pStats->GetLocalPlayerBuyBackSpending( -1 );
+ m_nYourBottlesCredits = pStats->GetLocalPlayerBottleSpending( -1 );
+ m_nYourUpgradeCredits = pStats->GetLocalPlayerUpgradeSpending( -1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: updates the target field based on the input args. Returns TRUE if transitioning to new state
+//-----------------------------------------------------------------------------
+bool CVictoryPanel::StateUpdateValue( vgui::EditablePanel *parent, char* field, float targetTime, float currentTime, int nextState, int endValue )
+{
+ float fPercent = currentTime / targetTime;
+ fPercent = 1.0 < fPercent ? 1.0f : fPercent;
+
+ int displayValue = (int)(endValue * fPercent);
+ parent->SetDialogVariable( field, displayValue );
+ if ( displayValue != endValue )
+ {
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( pPlayer )
+ {
+ pPlayer->EmitSound( "Credits.Updated" );
+ }
+ }
+
+ // transition to next state
+ if ( fPercent >= 1.0f )
+ {
+ m_fStateRunningTime = 0;
+ m_eState = nextState;
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: updates the target field based on the input args. Returns TRUE if transitioning to new state
+// Adds "Credit" count text
+//-----------------------------------------------------------------------------
+bool CVictoryPanel::StateUpdateCreditText( vgui::EditablePanel *parent, char* field, float targetTime, float currentTime, int nextState, int useValue, int creditValue )
+{
+ float fPercent = currentTime / targetTime;
+ fPercent = 1.0 < fPercent ? 1.0f : fPercent;
+ int displayValue = (int)(useValue * fPercent);
+
+ char szTmp[32];
+ Q_snprintf(szTmp, sizeof(szTmp), "%d (%d Credits)", displayValue, (int)(creditValue * fPercent));
+ parent->SetDialogVariable( field, szTmp );
+
+ if ( displayValue != useValue )
+ {
+ C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
+ if ( pPlayer )
+ {
+ pPlayer->EmitSound( "Credits.Updated" );
+ }
+ }
+
+ // transition to next state
+ if ( fPercent >= 1.0f )
+ {
+ m_fStateRunningTime = 0;
+ m_eState = nextState;
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+bool CVictoryPanel::CheckState( float targetTime, float currentTime, int nextState )
+{
+ if ( currentTime >= targetTime )
+ {
+ m_fStateRunningTime = 0;
+ m_eState = nextState;
+ return true;
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CVictoryPanel::RatingLabelUpdate( void )
+{
+ m_pRatingContainerPanel->SetDialogVariable( RATING_LABEL_STR, g_pVGuiLocalize->Find( "#TF_PVE_CreditRating" ) );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CVictoryPanel::RatingScoreUpdate( )
+{
+ //calc a score
+ const char* pletterScore = "F";
+
+ float fPercent = (float)m_nCreditsCollected / (float)(m_nCreditsCollected + m_nCreditsMissed);
+
+ if ( fPercent >= 1.0 )
+ {
+ pletterScore = "A+";
+ }
+ else if ( fPercent >= 0.9 )
+ {
+ pletterScore = "A";
+ }
+ else if ( fPercent >= 0.8 )
+ {
+ pletterScore = "B";
+ }
+ else if ( fPercent >= 0.7 )
+ {
+ pletterScore = "C";
+ }
+ else if ( fPercent >= 0.6 )
+ {
+ pletterScore = "D";
+ }
+
+ m_pRatingContainerPanel->SetDialogVariable( RATING_SCORE_STR, pletterScore );
+}
+
+
+//-----------------------------------------------------------------------------
+// CMvMVictoryMannUpLoot
+//-----------------------------------------------------------------------------
+DECLARE_BUILD_FACTORY( CMvMVictoryMannUpLoot );
+
+CMvMVictoryMannUpLoot::CMvMVictoryMannUpLoot( Panel *parent, const char *pName ): vgui::EditablePanel( parent, pName )
+{
+ m_pItemModelPanel = new CItemModelPanel( this, "EconItemModel" );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpLoot::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+ LoadControlSettings( "resource/UI/MvMVictoryMannUpLoot.res" );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpLoot::SetEconItem ( CEconItem *econItem )
+{
+ if ( econItem != NULL )
+ {
+ m_pItemModelPanel->SetEconItem( econItem );
+ m_pItemModelPanel->SetVisible( true );
+ }
+ else
+ {
+ HideEconItem();
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpLoot::HideEconItem ( )
+{
+ m_pItemModelPanel->SetVisible( false );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpLoot::SetEconToolTip( CItemModelPanelToolTip *pToolTip)
+{
+ m_pItemModelPanel->SetTooltip( pToolTip, "" );
+}
+
+//-----------------------------------------------------------------------------
+DECLARE_BUILD_FACTORY( CMvMVictoryMannUpEntry );
+
+CMvMVictoryMannUpEntry::CMvMVictoryMannUpEntry( Panel *parent, const char *pName )
+ : vgui::EditablePanel( parent, pName )
+ , m_LootLables( DefLessFunc(int) )
+ , m_pPlayerModelPanel( NULL )
+ , m_bHasData( false )
+{
+ m_bBadgeUpdated = false;
+ m_iProgressWidthStart = 0;
+ m_iProgressWidthEnd = 0;
+
+ m_iLootAnimIndex = 0;
+ m_flLootAnimTime = 0.f;
+
+ m_pTourProgress = new EditablePanel( this, "TourProgress" );
+ m_pProgressBarBG = new EditablePanel( m_pTourProgress, "LevelProgressBarBG" );
+ m_pProgressBarFGAnim = new EditablePanel( m_pProgressBarBG, "LevelProgressBarFGAnim" );
+ m_pProgressBarFGStatic = new EditablePanel( m_pProgressBarBG, "LevelProgressBarFGStatic" );
+
+ m_pProgressCheckOnBackground = new EditablePanel( this, "MannUpTicketBackground" );
+ m_pProgressCheckOn = new vgui::ImagePanel( m_pProgressCheckOnBackground, "CompletedCheckOn" );
+ m_pSquadSurplusBackground = new EditablePanel( this, "SquadSurplusTicketBackground" );
+ m_pSquadSurplus = new vgui::ImagePanel( m_pSquadSurplusBackground, "SquadSurplus" );
+
+ m_pMissingVoucher = new vgui::Label( this, "MissingVoucher", "" );
+
+#ifdef USE_MVM_TOUR
+ m_nChallengeCount = 1;
+#else // new mm
+ m_nMissionIndex = -1;
+#endif // USE_MVM_TOUR
+
+ m_nItemColumns = 1;
+ m_nItemXSpacing = 100;
+ m_nItemYSpacing = 100;
+
+ m_pItemModelPanelKVs = NULL;
+ m_pRowKVs = NULL;
+ m_pUnopenedLootKVs = NULL;
+
+ m_pListPanel = new vgui::PanelListPanel( this, "PanelListPanel" );
+ m_pListPanel->SetVerticalBufferPixels( 0 );
+ m_pListPanel->SetFirstColumnWidth( 0 );
+
+ m_pPlayerModelPanel = new CTFPlayerModelPanel( this, "playermodelpanel" );
+
+ m_LootLables.Purge();
+ m_LootLables.Insert( CMsgMvMVictoryInfo_GrantReason_BADGE_LEVELED, new CExLabel( this, "TourOfDutyLabel", "" ) );
+ m_LootLables.Insert( CMsgMvMVictoryInfo_GrantReason_MANN_UP, new CExLabel( this, "MannUpLabel", "" ) );
+ m_LootLables.Insert( CMsgMvMVictoryInfo_GrantReason_SQUAD_SURPLUS, new CExLabel( this, "SquadSurplusLabel", "" ) );
+ m_LootLables.Insert( CMsgMvMVictoryInfo_GrantReason_HELP_A_NOOB, new CExLabel( this, "VeteranBonusLabel", "" ) );
+
+ m_pBehindItemParticlePanel = new CTFParticlePanel( this, "BehindItemParticlePanel" );
+}
+
+CMvMVictoryMannUpEntry::~CMvMVictoryMannUpEntry()
+{
+ // Dont let the list panel delete everything it owns. The labels and dividers
+ // technically belong to this panel's buildgroup, which would cause a double free.
+ m_pListPanel->RemoveAll();
+
+ ClearPlayerData();
+
+ if ( m_pItemModelPanelKVs )
+ {
+ m_pItemModelPanelKVs->deleteThis();
+ m_pItemModelPanelKVs = NULL;
+ }
+
+ if ( m_pRowKVs )
+ {
+ m_pRowKVs->deleteThis();
+ m_pRowKVs = NULL;
+ }
+
+ if ( m_pUnopenedLootKVs )
+ {
+ m_pUnopenedLootKVs->deleteThis();
+ m_pUnopenedLootKVs = NULL;
+ }
+}
+
+void CMvMVictoryMannUpEntry::ApplySettings( KeyValues *inResourceData )
+{
+ BaseClass::ApplySettings( inResourceData );
+
+ KeyValues *pItemKV = inResourceData->FindKey( "modelpanels_kv" );
+ if ( pItemKV )
+ {
+ if ( m_pItemModelPanelKVs )
+ {
+ m_pItemModelPanelKVs->deleteThis();
+ }
+ m_pItemModelPanelKVs = new KeyValues( "modelpanels_kv" );
+ pItemKV->CopySubkeys( m_pItemModelPanelKVs );
+ }
+
+ KeyValues *pRowKV = inResourceData->FindKey( "rowpanel_kvs" );
+ if ( pRowKV )
+ {
+ if ( m_pRowKVs )
+ {
+ m_pRowKVs->deleteThis();
+ }
+ m_pRowKVs = new KeyValues( "rowpanel_kvs" );
+ pRowKV->CopySubkeys( m_pRowKVs );
+ }
+
+ KeyValues *pUnopenedKV = inResourceData->FindKey( "unopenedPanel_kvs" );
+ if ( pUnopenedKV )
+ {
+ if ( m_pUnopenedLootKVs )
+ {
+ m_pUnopenedLootKVs->deleteThis();
+ }
+ m_pUnopenedLootKVs = new KeyValues( "unopenedPanel_kvs" );
+ pUnopenedKV->CopySubkeys( m_pUnopenedLootKVs );
+ }
+
+ m_nItemColumns = inResourceData->GetInt( "items_columns", 1 );
+ m_nItemXSpacing = inResourceData->GetInt( "items_xspacing", 100 );
+ m_nItemYSpacing = inResourceData->GetInt( "items_yspacing", 100 );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ // load control settings...
+ LoadControlSettings( "resource/UI/MvMVictoryMannUpEntry.res" );
+
+ UpdatePlayerData();
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::SetItemsToolTip( CItemModelPanelToolTip *pToolTip )
+{
+ FOR_EACH_VEC( m_vecLootPanels, i )
+ {
+ m_vecLootPanels[i]->SetTooltip( pToolTip, "" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::ClearPlayerData ( )
+{
+ SetDialogVariable( "name", "");
+
+ if ( m_pSquadSurplus )
+ m_pSquadSurplus->SetVisible( false );
+
+ if ( m_pProgressCheckOn )
+ m_pProgressCheckOn->SetVisible( false );
+
+ m_pProgressBarBG->SetVisible( false );
+ m_pProgressBarFGAnim->SetVisible( false );
+ m_pProgressBarFGStatic->SetVisible( false );
+
+ m_pMissingVoucher->SetVisible( false );
+ ClearEconItems();
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::UpdatePlayerData()
+{
+ if ( !m_bHasData )
+ return;
+
+ if ( steamapicontext == NULL )
+ return;
+
+ m_pListPanel->RemoveAll();
+ CSteamID steamID = CSteamID( m_playerData.steam_id() );
+
+ m_hPlayer = GetPlayerBySteamID( steamID );
+ // Setup our model panel
+ SetModelPanelInfo( ToTFPlayer( m_hPlayer ) );
+
+ SetDialogVariable( "name", steamapicontext->SteamFriends()->GetFriendPersonaName( steamID ) );
+
+ // Reset
+ m_pProgressBarBG->SetVisible( true );
+ m_pProgressBarFGAnim->SetVisible( true );
+ m_pProgressBarFGStatic->SetVisible( true );
+
+ CheckBadgeLevel( m_playerData );
+
+ // Check Squad Surplus for this player
+ CTFGSLobby *pLobby = GTFGCClientSystem()->GetLobby();
+ if ( pLobby )
+ {
+ const CTFLobbyMember *pMember = pLobby->GetMemberDetails( steamID );
+ if ( pMember )
+ {
+ m_pSquadSurplus->SetVisible( pMember->squad_surplus() );
+ }
+ }
+
+#ifdef STAGING_ONLY
+ if ( tf_mvm_fake_loot.GetBool() )
+ {
+ m_pSquadSurplus->SetVisible( true );
+ }
+#endif
+
+ // Loot
+ ClearEconItems();
+ for( int i = 0; i < m_playerData.items_size(); ++i )
+ {
+ m_vecLootPanels[ m_vecLootPanels.AddToTail() ] = new CMvMLootItem( this, VarArgs( "modelpanel%d", i ) );
+ }
+
+#ifdef STAGING_ONLY
+ if ( tf_mvm_fake_loot.GetBool() )
+ {
+ CPlayerInventory *pInventory = InventoryManager()->GetLocalInventory();
+ if ( !pInventory )
+ return;
+
+ int nRandom = RandomInt(5,10);
+ for( int i = 0; i < nRandom; ++i )
+ {
+ m_vecLootPanels[ m_vecLootPanels.AddToTail() ] = new CMvMLootItem( this, VarArgs( "modelpanel%d", i ) );
+ CMvMLootItem* pLootItem = m_vecLootPanels.Tail();
+ pLootItem->m_eReason = (CMsgMvMVictoryInfo_GrantReason)RandomInt(1,3);
+
+ CEconItemView *pItemView = pInventory->GetItem(i);
+ CEconItem* econItem = new CEconItem();
+ econItem = pItemView->GetSOCData();
+
+ pLootItem->SetEconItem( econItem );
+ }
+ }
+#endif
+
+ for ( int iItem = 0; iItem < m_playerData.items_size(); ++iItem )
+ {
+ const CMsgMvMVictoryInfo_Item& item = m_playerData.items( iItem );
+ CEconItem *pEconItem = new CEconItem();
+ m_MannUpEconItems.AddToTail( pEconItem );
+
+ if ( pEconItem->BParseFromMessage( item.item_data() ) )
+ {
+ CMvMLootItem *pLootItem = m_vecLootPanels[ iItem ];
+ pLootItem->SetVisible( false );
+ pLootItem->SetEconItem( pEconItem );
+ pLootItem->m_eReason = item.grant_reason();
+ }
+ else
+ {
+ delete pEconItem;
+ }
+ }
+
+ // Put the items into a map for ordering them later on
+ CUtlMap< int, CCopyableUtlVector<CMvMLootItem*> > mapItems( DefLessFunc(int) );
+ FOR_EACH_VEC( m_vecLootPanels, i )
+ {
+ int nIndex = mapItems.Find( m_vecLootPanels[i]->m_eReason );
+ if ( mapItems.InvalidIndex() == nIndex )
+ {
+ nIndex = mapItems.Insert( m_vecLootPanels[i]->m_eReason );
+ }
+
+ mapItems[ nIndex ].AddToTail( m_vecLootPanels[i] );
+ }
+
+ bool bAnyThisRow = true;
+ vgui::EditablePanel* pItemPanelRow = NULL;
+
+ // The order of the categories
+ int nCategories[] = { CMsgMvMVictoryInfo_GrantReason_MANN_UP
+ , CMsgMvMVictoryInfo_GrantReason_SQUAD_SURPLUS
+ , CMsgMvMVictoryInfo_GrantReason_BADGE_LEVELED };
+
+ // Put the panels into rows in the scrollable panel
+ for( int nRow = 0; bAnyThisRow; ++nRow )
+ {
+ bAnyThisRow = false;
+ pItemPanelRow = NULL;
+
+ for( int i = 0; i < ARRAYSIZE( nCategories ); i++ )
+ {
+ int nMapKey = mapItems.Find( nCategories[i] );
+ if ( nMapKey == mapItems.InvalidIndex() )
+ continue;
+
+ for( int nColumn = 0; nColumn < m_nItemColumns; ++nColumn )
+ {
+ int nIndex = ( nRow * m_nItemColumns ) + nColumn;
+ if ( nIndex < mapItems[ nMapKey ].Count() )
+ {
+ bAnyThisRow = true;
+
+ CMvMLootItem *pLootItem = mapItems[ nMapKey ][ nIndex ];
+
+ // Create a row if we need to
+ if ( pItemPanelRow == NULL )
+ {
+ pItemPanelRow = AddLootRow();
+ }
+
+ Assert( pItemPanelRow );
+
+ pLootItem->SetParent( pItemPanelRow );
+ pLootItem->m_pUnopenedPanel->SetParent( pItemPanelRow );
+ pLootItem->m_nIndex = ( i * m_nItemColumns ) + nColumn;
+ }
+ }
+ }
+ }
+
+ // Put all the items into our list in the order that we want to reveal them
+ m_vecLootPanels.Purge();
+ for( int i = 0; i < ARRAYSIZE( nCategories ); i++ )
+ {
+ int nMapKey = mapItems.Find( nCategories[i] );
+ if ( nMapKey == mapItems.InvalidIndex() )
+ continue;
+
+ FOR_EACH_VEC( mapItems[ nMapKey ], j )
+ {
+ m_vecLootPanels.AddToTail( mapItems[ nMapKey ][ j ] );
+ }
+ }
+
+ // We want at least 5 rows just to fill the space
+ while( m_vecRows.Count() < 5 )
+ {
+ AddLootRow();
+ }
+
+ // If player's voucher has gone missing, indicate it
+ m_pMissingVoucher->SetVisible( m_playerData.voucher_missing() );
+
+ // Lots of stuff changed
+ InvalidateLayout();
+}
+
+#ifdef USE_MVM_TOUR
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::SetPlayerData( const CMsgMvMVictoryInfo_Player& player, int nMissionCount )
+{
+ m_nChallengeCount = nMissionCount;
+ m_playerData = player;
+ m_bHasData = true;
+
+ UpdatePlayerData();
+}
+#else // new mm
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::SetPlayerData( const CMsgMvMVictoryInfo_Player& player, int nMissionIndex )
+{
+ m_nMissionIndex = nMissionIndex;
+ m_playerData = player;
+ m_bHasData = true;
+
+ UpdatePlayerData();
+}
+#endif // USE_MVM_TOUR
+
+vgui::EditablePanel* CMvMVictoryMannUpEntry::AddLootRow()
+{
+ vgui::EditablePanel* pItemPanelRow = new vgui::EditablePanel( m_pListPanel, "itemsrow" ) ;
+ m_pListPanel->AddItem( NULL, pItemPanelRow );
+ m_vecRows.AddToTail( pItemPanelRow );
+
+ return pItemPanelRow;
+}
+
+
+static const float PROGRESS_ANIM_TIME = 2.0f;
+//-----------------------------------------------------------------------------
+bool CMvMVictoryMannUpEntry::AnimateProgressBar( void )
+{
+ if ( IsVisible() == false || m_bBadgeUpdated == false )
+ {
+ m_pProgressBarFGAnim->SetWide( m_iProgressWidthEnd );
+ return true;
+ }
+
+ if ( m_flPBarCurrTime > PROGRESS_ANIM_TIME )
+ {
+ if ( m_bBadgeUpdated == true && m_iProgressWidthEnd == m_pProgressBarBG->GetWide() )
+ {
+ wchar_t wszTourUp[ 256 ];
+ wchar_t wszTourLevel[ 10 ];
+
+ m_pTourProgress->SetDialogVariable( "level", g_pVGuiLocalize->Find( "#TF_MVM_Victory_TourComplete" ) );
+ _snwprintf( wszTourLevel, ARRAYSIZE(wszTourLevel) - 1, L"%d", m_nBadgeLevel );
+
+ wszTourLevel[ ARRAYSIZE(wszTourLevel)-1 ] = '\0';
+ g_pVGuiLocalize->ConstructString_safe( wszTourUp, g_pVGuiLocalize->Find( "#TF_MvM_TourCount" ), 1, wszTourLevel );
+ m_pTourProgress->SetDialogVariable( "level", wszTourUp);
+ }
+
+ return true;
+ }
+
+ if ( m_flPBarPreviousTime == 0 )
+ {
+ m_flPBarPreviousTime = gpGlobals->curtime;
+ }
+
+ m_flPBarCurrTime += gpGlobals->curtime - m_flPBarPreviousTime;
+ m_flPBarPreviousTime = gpGlobals->curtime;
+
+ float flRatio = m_flPBarCurrTime / PROGRESS_ANIM_TIME;
+ SetBadgeProgressBarProgress( flRatio );
+
+ return false;
+}
+
+
+void CMvMVictoryMannUpEntry::SetBadgeProgressBarProgress( float flPercent )
+{
+ int nWidth = m_iProgressWidthStart;
+ nWidth += ((float)m_iProgressWidthEnd - (float)m_iProgressWidthStart) * flPercent;
+ m_pProgressBarFGAnim->SetWide(nWidth);
+}
+
+
+void CMvMVictoryMannUpEntry::ForceFinishAllAnimation()
+{
+ // Badge progress bar
+ m_flPBarCurrTime = PROGRESS_ANIM_TIME;
+ SetBadgeProgressBarProgress( 1.f );
+
+ // Loot
+ FOR_EACH_VEC( m_vecLootPanels, i )
+ {
+ CMvMLootItem* pLootPanel = m_vecLootPanels[ i ];
+ pLootPanel->SetVisible( true );
+ pLootPanel->m_pUnopenedPanel->SetVisible( false );
+ }
+}
+
+void CMvMVictoryMannUpEntry::SetLootAnimationPause( float flPause )
+{
+ m_flLootAnimTime = gpGlobals->curtime + flPause;
+ m_flLastLootAnimTime = gpGlobals->curtime + flPause;
+}
+
+void CMvMVictoryMannUpEntry::SetActive( bool bActive )
+{
+ SetVisible( bActive );
+
+ if ( bActive )
+ {
+ PlayVCD( "class_select" );
+ }
+}
+
+void CMvMVictoryMannUpEntry::PerformLayout()
+{
+ BaseClass::PerformLayout();
+
+ FOR_EACH_VEC( m_vecRows, i )
+ {
+ if ( m_pRowKVs )
+ {
+ m_vecRows[i]->ApplySettings( m_pRowKVs );
+ m_vecRows[i]->SetVisible( true );
+ m_vecRows[i]->InvalidateLayout( true, true );
+ }
+ }
+
+ FOR_EACH_VEC( m_vecLootPanels, i )
+ {
+ CMvMLootItem* pItemPanel = m_vecLootPanels[i];
+ if ( m_pItemModelPanelKVs )
+ {
+ pItemPanel->ApplySettings( m_pItemModelPanelKVs );
+ pItemPanel->InvalidateLayout( true );
+
+ if ( pItemPanel->GetParent() )
+ {
+ vgui::EditablePanel* pBackground = dynamic_cast<vgui::EditablePanel*>( pItemPanel->GetParent()->FindChildByName( VarArgs( "ItemBackground%d", pItemPanel->m_nIndex + 1 ), true ) );
+ if ( pBackground )
+ {
+ int x,y;
+ pBackground->GetPos(x,y);
+ pItemPanel->SetPos( x - 5, 2 );
+
+ if ( m_pUnopenedLootKVs )
+ {
+ pItemPanel->m_pUnopenedPanel->ApplySettings( m_pUnopenedLootKVs );
+ pItemPanel->m_pUnopenedPanel->SetVisible( true );
+ }
+
+ // The unopened panel is in the same position
+ int nXoffset = ( pItemPanel->m_pUnopenedPanel->GetWide() - pItemPanel->GetWide() ) / 2;
+ int nYoffset = ( pItemPanel->m_pUnopenedPanel->GetTall() - pItemPanel->GetTall() ) / 2;
+ pItemPanel->GetPos( x, y );
+ pItemPanel->m_pUnopenedPanel->SetPos( x - nXoffset, y - nYoffset );
+
+
+ // Update unopened panel's image
+ pItemPanel->m_pUnopenedPanel->SetImage( CFmtStr( "../backpack/player/items/crafting/prize_crate_%d", RandomInt(1,5) ) );
+
+ }
+ }
+ }
+ }
+
+ m_pListPanel->InvalidateLayout( true, false );
+}
+
+//-----------------------------------------------------------------------------
+// PRIVATE
+//-----------------------------------------------------------------------------
+
+bool CMvMVictoryMannUpEntry::AnimTimePassed( float flTime ) const
+{
+ float flCurTime = gpGlobals->curtime - m_flLootAnimTime;
+ float flLastTime = m_flLastLootAnimTime - m_flLootAnimTime;
+
+ return ( flCurTime >= flTime && flLastTime < flTime );
+}
+
+bool CMvMVictoryMannUpEntry::AnimateLoot( CTFParticlePanel* pParticlePanel )
+{
+ bool bDone = AnimateLoot_Internal( pParticlePanel );
+ m_flLastLootAnimTime = gpGlobals->curtime;
+
+ return bDone;
+}
+
+//-----------------------------------------------------------------------------
+bool CMvMVictoryMannUpEntry::AnimateLoot_Internal( CTFParticlePanel *pParticlePanel )
+{
+ if ( m_vecLootPanels.Count() == 0 )
+ return true;
+
+ if ( m_iLootAnimIndex >= m_vecLootPanels.Count() )
+ {
+ m_iLootAnimIndex = 0;
+ return true;
+ }
+
+ // Get the loot panel
+ CMvMLootItem* pLootPanel = m_vecLootPanels[ m_iLootAnimIndex ];
+
+ if ( pLootPanel == NULL )
+ {
+ m_iLootAnimIndex++;
+ m_flLootAnimTime = gpGlobals->curtime;
+ m_flLastLootAnimTime = gpGlobals->curtime;
+
+ return false;
+ }
+
+ if ( AnimTimePassed( 0.1f ) )
+ {
+ // Scroll to it. We want a little pause in here.
+ for( int itemID = m_pListPanel->FirstItem(); itemID != m_pListPanel->InvalidItemID(); itemID = m_pListPanel->NextItem( itemID ) )
+ {
+ if ( m_pListPanel->GetItemPanel( itemID ) == pLootPanel->GetParent() )
+ {
+ m_pListPanel->ScrollToItem( itemID );
+ }
+ }
+ }
+
+ // Get loot rarity
+ uint32 nRarity = 0;
+ static CSchemaAttributeDefHandle pAttrDef_LootRarity( "loot rarity" );
+ uint32 nAttribVal = 0;
+ if ( pLootPanel->GetItem()->FindAttribute( pAttrDef_LootRarity, &nAttribVal ) )
+ {
+ nRarity = (int)((float&)nAttribVal);
+ }
+ Assert( nRarity >= 0 && nRarity <= 2 );
+ nRarity = clamp( nRarity, 0, 2 );
+
+#ifdef STAGING_ONLY
+ if ( tf_mvm_fake_loot.GetBool() )
+ {
+ int randomInt = pLootPanel->GetItem()->GetID() % 10;
+ nRarity = randomInt % 7 == 0 ? 2 : ( randomInt % 3 == 0 ? 1 : 0 );
+ }
+#endif
+
+ int nPanelXPos, nPanelYPos;
+ pLootPanel->GetPos( nPanelXPos, nPanelYPos );
+
+ int nPanelCenterX = nPanelXPos + (pLootPanel->GetWide() / 2);
+ int nPanelCenterY = nPanelYPos + (pLootPanel->GetTall() / 2);
+
+ int iItemAbsX, iItemAbsY;
+ vgui::ipanel()->GetAbsPos( pLootPanel->GetParent()->GetVPanel(), iItemAbsX, iItemAbsY );
+
+ int x = iItemAbsX + nPanelCenterX;
+ int y = iItemAbsY + nPanelCenterY;
+
+ C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
+
+ static const char* pszParticles [] =
+ {
+ "mvm_pow_bam",
+ "mvm_pow_boing",
+ "mvm_pow_crack",
+ "mvm_pow_crash",
+ "mvm_pow_crit",
+ "mvm_pow_poof",
+ "mvm_pow_pow",
+ "mvm_pow_punch",
+ "mvm_pow_smash",
+ "mvm_pow_banana",
+ "mvm_pow_boot",
+ "mvm_pow_loot",
+ "mvm_pow_mmph",
+ "mvm_pow_caber"
+ };
+
+ switch( nRarity )
+ {
+ case 0:
+ {
+ if( AnimTimePassed( 0.1f ) )
+ {
+ if ( pParticlePanel )
+ {
+ pParticlePanel->FireParticleEffect( pszParticles[ RandomInt(0,ARRAYSIZE(pszParticles)-1)], x, y, 1.25f, false );
+ }
+ }
+
+ if ( AnimTimePassed( 0.3f ) )
+ {
+ // Show it
+ pLootPanel->SetVisible( true );
+ pLootPanel->m_pUnopenedPanel->SetVisible( false );
+
+ if ( pLocalPlayer )
+ {
+ pLocalPlayer->EmitSound( "ui.cratesmash_common" );
+ }
+
+ if ( pLocalPlayer == m_hPlayer )
+ {
+ engine->ServerCmd( "loot_response common" );
+ }
+
+ if ( pParticlePanel )
+ {
+ pParticlePanel->FireParticleEffect( "mvm_loot_explosion", x, y, 0.4f, false );
+ }
+ }
+
+ break;
+ }
+ case 1:
+ {
+ if ( AnimTimePassed( 0.1f ) )
+ {
+ if ( pParticlePanel )
+ {
+ pParticlePanel->FireParticleEffect( "mvm_pow_fuse_movement", x, y, 5.f, false, 5.f );
+ }
+
+ if ( pLocalPlayer )
+ {
+ pLocalPlayer->EmitSound( "ui.cratesmash_rare_long" );
+ }
+ }
+
+ if ( AnimTimePassed( 2.0f ) )
+ {
+ // Show it
+ pLootPanel->SetVisible( true );
+ pLootPanel->m_pUnopenedPanel->SetVisible( false );
+
+ if ( pParticlePanel )
+ {
+ pParticlePanel->FireParticleEffect( "mvm_pow_gold_seq_firework_mid", x, y, 0.8f, false );
+ pParticlePanel->FireParticleEffect( "mvm_loot_explosion", x, y, 0.4f, false );
+ }
+
+ if ( pLocalPlayer == m_hPlayer )
+ {
+ engine->ServerCmd( "loot_response rare" );
+ }
+ }
+
+ break;
+ }
+ case 2:
+ default: // Above level 2? Do the super-cool effects
+ {
+ if ( AnimTimePassed( 0.3f ) )
+ {
+ if ( pLocalPlayer )
+ {
+ pLocalPlayer->EmitSound( "ui.cratesmash_ultrarare_long_fireworks" );
+ }
+
+ if ( pParticlePanel )
+ {
+ pParticlePanel->FireParticleEffect( "mvm_pow_gold_seq", x, y, 0.8f, false );
+ }
+ }
+
+ if ( AnimTimePassed( 3.3f ) )
+ {
+ // Show it
+ pLootPanel->SetVisible( true );
+ pLootPanel->m_pUnopenedPanel->SetVisible( false );
+
+ if ( pParticlePanel )
+ {
+ pParticlePanel->FireParticleEffect( "mvm_loot_explosion", x, y, 0.6f, false );
+ }
+
+ if ( m_pBehindItemParticlePanel )
+ {
+ m_pBehindItemParticlePanel->FireParticleEffect( "mvm_item_godrays_glow", x, y, 5.f, false );
+ }
+
+ if ( pLocalPlayer == m_hPlayer )
+ {
+ engine->ServerCmd( "loot_response ultra_rare" );
+ }
+ }
+ break;
+ }
+ }
+
+ float flTotalTime[] = { 0.3f, 3.f, 17.f };
+ float flEndTime = flTotalTime[nRarity];
+
+ // Add in a pause on the last item if we're not already giving some grand pause
+ if ( m_iLootAnimIndex == ( m_vecLootPanels.Count() - 1 ) && ( flEndTime - gpGlobals->curtime ) < 1.f)
+ {
+ flEndTime += 3.f;
+ }
+
+ if ( AnimTimePassed( flEndTime ) )
+ {
+ // Prime ourselves for the next one
+ m_iLootAnimIndex++;
+ m_flLootAnimTime = gpGlobals->curtime;
+ m_flLastLootAnimTime = gpGlobals->curtime;
+ }
+
+ return false;
+}
+
+#ifdef USE_MVM_TOUR
+//-----------------------------------------------------------------------------
+int CMvMVictoryMannUpEntry::GetBadgeCompletionCount ( uint32 iProgressBits )
+{
+ int nCompleteCount = 0;
+ for (int i = 0; i < 32; i++ )
+ {
+ nCompleteCount += iProgressBits & 1;
+ iProgressBits = iProgressBits >> 1;
+
+ if ( iProgressBits == 0 )
+ {
+ break;
+ }
+ }
+
+ nCompleteCount = MIN( nCompleteCount, m_nChallengeCount );
+
+ return nCompleteCount;
+}
+#endif // USE_MVM_TOUR
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::CheckBadgeLevel( const CMsgMvMVictoryInfo_Player& player )
+{
+ wchar_t wszTourUp[ 256 ];
+ wchar_t wszTourLevel[ 10 ];
+
+ m_nBadgeLevel = player.badge_level();
+ int nBadgeOffset = player.badge_leveled() ? 1 : 0;
+ _snwprintf( wszTourLevel, ARRAYSIZE(wszTourLevel) - 1, L"%d", m_nBadgeLevel - nBadgeOffset );
+
+#ifdef USE_MVM_TOUR
+ int count = GetBadgeCompletionCount( player.badge_progress_bits() );
+
+ if ( player.badge_progress_updated() )
+ {
+ m_bBadgeUpdated = true;
+ m_flPBarCurrTime = 0;
+ m_flPBarPreviousTime = 0;
+
+ if ( player.badge_leveled() )
+ {
+ m_iProgressWidthStart = m_pProgressBarBG->GetWide() * ( (float)(m_nChallengeCount - 1) / (float)m_nChallengeCount );
+ m_iProgressWidthEnd = m_pProgressBarBG->GetWide();
+ }
+ else
+ {
+ m_iProgressWidthStart = m_pProgressBarBG->GetWide() * ( (float)(count - 1) / (float)m_nChallengeCount );
+ m_iProgressWidthEnd = m_pProgressBarBG->GetWide() * ( (float)(count) / (float)m_nChallengeCount );
+ }
+
+ m_pProgressCheckOn->SetVisible( true );
+ m_pProgressBarFGStatic->SetWide( m_iProgressWidthStart );
+ }
+ else
+ {
+ m_iProgressWidthEnd = m_pProgressBarBG->GetWide() * (float)( (float)count / (float)m_nChallengeCount );
+ m_pProgressBarFGStatic->SetWide( m_iProgressWidthEnd );
+
+ m_pProgressCheckOn->SetVisible( false );
+ m_pProgressBarFGAnim->SetVisible( false );
+ }
+#else // new mm
+
+ const MvMMission_t& challenge = GetItemSchema()->GetMvmMissions()[m_nMissionIndex];
+ if ( player.badge_progress_updated() )
+ {
+ m_bBadgeUpdated = true;
+ m_flPBarCurrTime = 0;
+ m_flPBarPreviousTime = 0;
+
+ if ( player.badge_leveled() )
+ {
+ m_iProgressWidthStart = m_pProgressBarBG->GetWide() * ( (float)( player.badge_points() - challenge.m_unMannUpPoints ) / (float)k_unMvMMaxPointsPerBadgeLevel );
+ m_iProgressWidthEnd = m_pProgressBarBG->GetWide();
+ }
+ else
+ {
+ m_iProgressWidthStart = m_pProgressBarBG->GetWide() * ( (float)( player.badge_points() - challenge.m_unMannUpPoints ) / (float)k_unMvMMaxPointsPerBadgeLevel );
+ m_iProgressWidthEnd = m_pProgressBarBG->GetWide() * ( (float)player.badge_points() / (float)k_unMvMMaxPointsPerBadgeLevel );
+ }
+
+ m_pProgressCheckOn->SetVisible( true );
+ m_pProgressBarFGStatic->SetWide( m_iProgressWidthStart );
+ }
+ else
+ {
+ m_iProgressWidthEnd = m_pProgressBarBG->GetWide() * ( (float)player.badge_points() / (float)k_unMvMMaxPointsPerBadgeLevel );
+ m_pProgressBarFGStatic->SetWide( m_iProgressWidthEnd );
+
+ m_pProgressCheckOn->SetVisible( false );
+ m_pProgressBarFGAnim->SetVisible( false );
+ }
+#endif // USE_MVM_TOUR
+
+ wszTourLevel[ ARRAYSIZE(wszTourLevel)-1 ] = '\0';
+ g_pVGuiLocalize->ConstructString_safe( wszTourUp, g_pVGuiLocalize->Find( "#TF_MvM_TourCount" ), 1, wszTourLevel );
+ m_pTourProgress->SetDialogVariable( "level", wszTourUp );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpEntry::ClearEconItems()
+{
+ FOR_EACH_VEC ( m_vecLootPanels, i )
+ {
+ m_vecLootPanels[ i ]->SetItem( NULL );
+ m_vecLootPanels[ i ]->SetVisible( false );
+ }
+
+ m_vecRows.PurgeAndDeleteElements();
+ m_vecLootPanels.Purge();
+
+ // reset
+ m_iLootAnimIndex = 0;
+ SetLootAnimationPause( 2.f ); // + 2 gives us a pause of 2 seconds when the panel first opens
+}
+
+
+void CMvMVictoryMannUpEntry::PlayVCD( const char * pszVCDName )
+{
+ if (m_pPlayerModelPanel)
+ {
+ const int iClass = m_pPlayerModelPanel->GetPlayerClass();
+ m_pPlayerModelPanel->PlayVCD(pszVCDName, NULL, false);
+ // This causes the VCD to be played. Yep.
+ m_pPlayerModelPanel->HoldItemInSlot(g_iLegacyClassSelectWeaponSlots[iClass]);
+ }
+}
+
+
+bool CMvMVictoryMannUpEntry::SetModelPanelInfo( C_TFPlayer* pPlayer )
+{
+ if ( !pPlayer )
+ return false;
+
+ if ( !m_pPlayerModelPanel )
+ {
+ AssertMsg1( 0, "No model panel in %s", __FUNCTION__ );
+ return false;
+ }
+
+ CSteamID steamID;
+ if ( !pPlayer->GetSteamID( &steamID ) )
+ {
+ AssertMsg1( 0, "No steamID for user %s", pPlayer->GetPlayerName() );
+ m_pPlayerModelPanel->SetVisible( false );
+ return false;
+ }
+
+ int nClass = pPlayer->GetPlayerClass()->GetClassIndex();
+ int nTeam = pPlayer->GetTeamNumber();
+ int nLoadoutSlot = g_iLegacyClassSelectWeaponSlots[nClass]; // We want to mirror the class select panel
+ CEconItemView *pWeapon = TFInventoryManager()->GetItemInLoadoutForClass( nClass, nLoadoutSlot, &steamID );
+
+ bool bIsRobot = false;
+ int iRobot = 0;
+ CALL_ATTRIB_HOOK_INT_ON_OTHER( pPlayer, iRobot, appear_as_mvm_robot );
+ bIsRobot = iRobot ? true : false;
+
+ m_pPlayerModelPanel->ClearCarriedItems();
+ m_pPlayerModelPanel->SetToPlayerClass( nClass, bIsRobot, true );
+ m_pPlayerModelPanel->SetTeam( nTeam );
+
+ for ( int wbl = pPlayer->GetNumWearables()-1; wbl >= 0; wbl-- )
+ {
+ C_TFWearable *pItem = dynamic_cast<C_TFWearable*>( pPlayer->GetWearable( wbl ) );
+ if ( !pItem )
+ continue;
+
+ if ( pItem->IsViewModelWearable() )
+ continue;
+
+ CAttributeContainer *pCont = pItem->GetAttributeContainer();
+ CEconItemView *pEconItemView = pCont ? pCont->GetItem() : NULL;
+
+ if ( pEconItemView && pEconItemView->IsValid() )
+ {
+ m_pPlayerModelPanel->AddCarriedItem( pEconItemView );
+ }
+ }
+
+ if ( pWeapon )
+ {
+ m_pPlayerModelPanel->AddCarriedItem( pWeapon );
+ }
+
+ m_pPlayerModelPanel->HoldItemInSlot( nLoadoutSlot );
+ m_pPlayerModelPanel->SetVisible( true );
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// CMvMVictoryMannUpPlayerTab
+//-----------------------------------------------------------------------------
+DECLARE_BUILD_FACTORY( CMvMVictoryMannUpPlayerTab );
+
+CMvMVictoryMannUpPlayerTab::CMvMVictoryMannUpPlayerTab( Panel *parent, const char *pName )
+ : BaseClass( parent, pName )
+ , m_pMouseoverHighlightPanel( NULL )
+ , m_pActiveTab( NULL )
+ , m_bIsActive( false )
+ , m_pAvatarImage( NULL )
+{
+ m_pAvatarImage = new CAvatarImagePanel( this, "PlayerAvatar" );
+ m_pMouseoverHighlightPanel = new vgui::EditablePanel( this, "MouseOverTabPanel" );
+ m_pActiveTab = new vgui::EditablePanel( this, "ActiveTabPanel" );
+}
+
+
+void CMvMVictoryMannUpPlayerTab::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ // load control settings...
+ LoadControlSettings( "resource/UI/MvMVictoryMannUpTab.res" );
+}
+
+
+void CMvMVictoryMannUpPlayerTab::SetPlayer( const CSteamID& steamID )
+{
+ if ( m_pAvatarImage )
+ {
+ m_pAvatarImage->SetShouldDrawFriendIcon( false );
+ m_pAvatarImage->SetPlayer( steamID, k_EAvatarSize64x64 );
+ }
+}
+
+void CMvMVictoryMannUpPlayerTab::SetSelected( bool bState )
+{
+ // Change in state?
+ if ( m_bIsActive != bState )
+ {
+ if ( m_pMouseoverHighlightPanel )
+ {
+ m_pMouseoverHighlightPanel->SetVisible( false );
+ }
+
+ // Becoming the active tab?
+ if ( m_pActiveTab )
+ {
+ m_pActiveTab->SetVisible( bState );
+ }
+ }
+
+ m_bIsActive = bState;
+}
+
+void CMvMVictoryMannUpPlayerTab::OnCommand( const char *command )
+{
+ if ( !Q_stricmp( command, "switch_tab" ) )
+ {
+ Panel* pParent = GetParent();
+ if ( pParent )
+ {
+ pParent->PostActionSignal( new KeyValues( "Command", "command", VarArgs( "%s_pressed", GetName() ) ) );
+ }
+
+ return;
+ }
+ else if ( !Q_stricmp( command, "highlight_on" ) )
+ {
+ // Active tab doesnt highlight
+ if ( m_bIsActive )
+ return;
+
+ if ( m_pMouseoverHighlightPanel )
+ {
+ m_pMouseoverHighlightPanel->SetVisible( true );
+ }
+ }
+ else if ( !Q_stricmp( command, "highlight_off" ) )
+ {
+ // Active tab doesnt highlight
+ if ( m_bIsActive )
+ return;
+
+ if ( m_pMouseoverHighlightPanel )
+ {
+ m_pMouseoverHighlightPanel->SetVisible( false );
+ }
+ }
+
+ BaseClass::OnCommand( command );
+}
+
+
+
+//-----------------------------------------------------------------------------
+// CMvMVictoryMannUpPanel
+//-----------------------------------------------------------------------------
+DECLARE_BUILD_FACTORY( CMvMVictoryMannUpPanel );
+
+CMvMVictoryMannUpPanel::CMvMVictoryMannUpPanel( Panel *parent, const char *pName )
+ : vgui::EditablePanel( parent, pName )
+ , m_pNoItemServerContainer( NULL )
+{
+ SetMouseInputEnabled( true );
+ m_hasData = false;
+
+ m_iMannUpLootIndex = 0;
+ m_flChangeTabPauseTime = FLT_MAX;
+
+ m_pMouseOverItemPanel = vgui::SETUP_PANEL( new CItemModelPanel( this, "mouseoveritempanel" ) );
+ m_pMouseOverTooltip = new CItemModelPanelToolTip( this );
+ m_pMouseOverTooltip->SetupPanels( this, m_pMouseOverItemPanel );
+ m_pMouseOverTooltip->SetPositioningStrategy( IPTTP_BOTTOM_SIDE );
+ m_pMouseOverItemPanel->MoveToFront();
+
+ m_pDoneButton = new CExImageButton( this, "DoneButton", g_pVGuiLocalize->Find( "#DoneButton" ), this );
+
+ for (int i = 0; i < MVM_PLAYER_COUNT; ++i)
+ {
+ m_PlayerEntryPanels.AddToTail(new CMvMVictoryMannUpEntry( this, "mannup_entry" ) );
+ m_PlayerEntryPanels.Tail()->SetVisible( true );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpPanel::ApplySchemeSettings( IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ // load control settings...
+ LoadControlSettings( "resource/UI/MvMVictoryMannUpPanel.res" );
+
+ m_pDoneButton->AddActionSignalTarget( GetParent() );
+
+ vgui::EditablePanel *pContainer = dynamic_cast<vgui::EditablePanel*>( FindChildByName("MainPanelContainer") );
+
+ m_pMouseOverItemPanel->SetBorder( pScheme->GetBorder("LoadoutItemPopupBorder") );
+
+ m_vecTabs.Purge();
+ m_vecTabButtons.Purge();
+ for ( int i = 0; i < MVM_PLAYER_COUNT; ++i )
+ {
+ CMvMVictoryMannUpPlayerTab *pTab = FindControl<CMvMVictoryMannUpPlayerTab>( VarArgs( "PlayerTab%d", i + 1), true );
+ if ( pTab )
+ {
+ pTab->ApplySchemeSettings( pScheme );
+ pTab->SetVisible( false );
+ m_vecTabs.AddToTail( pTab );
+
+ vgui::Button* pButton = pTab->FindControl<vgui::Button>( "TabButton", true );
+ if ( pButton )
+ {
+ pButton->SetCommand( CFmtStr( "switch_tab%d", i + 1 ) );
+ pButton->AddActionSignalTarget( this );
+ m_vecTabButtons.AddToTail( pButton );
+ }
+ }
+ }
+
+ if ( pContainer )
+ {
+ m_pNoItemServerContainer = dynamic_cast<vgui::EditablePanel*>( pContainer->FindChildByName( "NoItemServerContainer" ) );
+ }
+
+ m_pParticlePanel = FindControl<CTFParticlePanel>( "ParticlePanel" );
+
+ LoadVictoryData();
+}
+
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpPanel::OnTick( void )
+{
+ if ( !IsVisible() )
+ {
+ return;
+ }
+
+ UpdateHighlight();
+
+ // Still animating
+ if ( !m_bAnimationComplete )
+ {
+ // If the pause time is set
+ if ( m_flChangeTabPauseTime != FLT_MAX )
+ {
+ // Check if the timeer has passed
+ if ( m_flChangeTabPauseTime < gpGlobals->curtime )
+ {
+ // We're done. Change the tab.
+ m_flChangeTabPauseTime = FLT_MAX;
+ SetTabActive( m_iMannUpLootIndex );
+ m_PlayerEntryPanels[ m_iMannUpLootIndex ]->SetLootAnimationPause( 0.2f );
+ }
+ else
+ {
+ // Has not passed yet. Dont animate anything.
+ return;
+ }
+ }
+
+ bool bBarComplete = false;
+ bool bLootComplete = false;
+
+ // progress bars
+ FOR_EACH_VEC ( m_PlayerEntryPanels, i )
+ {
+ bBarComplete = m_PlayerEntryPanels[i]->AnimateProgressBar();
+ }
+
+ // Animate loot
+ if ( m_iMannUpLootIndex < MVM_PLAYER_COUNT )
+ {
+ if ( m_PlayerEntryPanels[ m_iMannUpLootIndex ]->AnimateLoot( m_pParticlePanel ) )
+ {
+ // This entry is done. Increment the entry index, and set the pause timer.
+ // When the timer goes off it will change to the next tab.
+ ++m_iMannUpLootIndex;
+ if ( m_iMannUpLootIndex < MVM_PLAYER_COUNT && m_vecTabs[m_iMannUpLootIndex]->IsVisible() )
+ {
+ // Slight pause on showing the new tab
+ m_flChangeTabPauseTime = gpGlobals->curtime + 0.2f;
+ }
+ else
+ {
+ // All loot has been animated
+ bLootComplete = true;
+ }
+ }
+ }
+ else
+ {
+ bLootComplete = true;
+ }
+
+ // The bar and the loot must be complete to be considered totally complete
+ m_bAnimationComplete = bBarComplete && bLootComplete;
+ }
+}
+
+void CMvMVictoryMannUpPanel::SetVisible( bool bState )
+{
+ BaseClass::SetVisible( bState );
+
+ //int iRenderGroup = gHUD.LookupRenderGroupIndexByName( "global" );
+
+ if ( bState )
+ {
+ // Hide all other UI
+ //gHUD.LockRenderGroup( iRenderGroup );
+ }
+ else
+ {
+ // Let the other UI elements show again
+ // gHUD.UnlockRenderGroup( iRenderGroup );
+ }
+}
+
+void CMvMVictoryMannUpPanel::UpdateHighlight()
+{
+ vgui::Panel *pMouseOverPanel = vgui::ipanel()->GetPanel( vgui::input()->GetMouseOver(), "ClientDLL" );
+
+#ifdef DEBUG
+ if ( pMouseOverPanel )
+ {
+ const char * pszParentName = pMouseOverPanel->GetParent() ? pMouseOverPanel->GetParent()->GetName() : "";
+ engine->Con_NPrintf( 0, "%s %s", pMouseOverPanel->GetName(), pszParentName );
+ }
+#endif
+
+ // If we're still animating, fake the that they're not highlighting anything
+ if ( !m_bAnimationComplete
+#if defined STAGING_ONLY
+ && !tf_mvm_fake_loot.GetBool()
+#endif
+ )
+ {
+ pMouseOverPanel = NULL;
+ }
+
+ FOR_EACH_VEC ( m_vecTabButtons, i )
+ {
+ bool bOverMe = pMouseOverPanel && pMouseOverPanel == m_vecTabButtons[i];
+ m_vecTabs[i]->OnCommand( bOverMe? "highlight_on" : "highlight_off" );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpPanel::ShowVictoryPanel()
+{
+ SetVisible( true );
+ m_pMouseOverItemPanel->SetVisible( false );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpPanel::ClearData()
+{
+ // Clear the MvM data
+ m_hasData = false;
+ // Clear / Reset All Panels
+ int iPlayer = 0;
+ FOR_EACH_VEC( m_PlayerEntryPanels, i )
+ {
+ m_PlayerEntryPanels[iPlayer]->ClearPlayerData();
+ m_PlayerEntryPanels[iPlayer]->SetVisible( false );
+ }
+
+ m_bAnimationComplete = false;
+ m_iMannUpLootIndex = 0;
+ m_flChangeTabPauseTime = FLT_MAX;
+
+ if ( m_pNoItemServerContainer )
+ {
+ m_pNoItemServerContainer->SetVisible( true );
+ }
+
+ FOR_EACH_VEC( m_vecTabButtons, i )
+ {
+ m_vecTabButtons[i]->SetVisible( false );
+ }
+
+ FOR_EACH_VEC( m_vecTabs, i )
+ {
+ m_vecTabs[i]->SetVisible( false );
+ }
+}
+
+void CMvMVictoryMannUpPanel::LoadVictoryData()
+{
+ if ( !m_hasData )
+ return;
+
+ // get the number of challenges in this mission
+#ifdef USE_MVM_TOUR
+ int nMissionCount = 6; // default value
+ int idxTour = GetItemSchema()->FindMvmTourByName( m_victoryInfo.tour_name().c_str() );
+ if ( idxTour >= 0 )
+ {
+ const MvMTour_t &tour = GetItemSchema()->GetMvmTours()[ idxTour ];
+ nMissionCount = tour.m_vecMissions.Count();
+ }
+#else // new mm
+ int nMissionIndex = GetItemSchema()->FindMvmMissionByName( m_victoryInfo.mission_name().c_str() );
+ Assert( nMissionIndex >= 0 );
+#endif // USE_MVM_TOUR
+
+ // Clear / Reset All Panels
+ int iPlayer = 0;
+ for ( iPlayer = 0; iPlayer < m_victoryInfo.players_size(); ++iPlayer )
+ {
+#ifdef USE_MVM_TOUR
+ m_PlayerEntryPanels[iPlayer]->SetPlayerData( m_victoryInfo.players( iPlayer ), nMissionCount );
+#else // new mm
+ m_PlayerEntryPanels[iPlayer]->SetPlayerData( m_victoryInfo.players( iPlayer ), nMissionIndex );
+#endif // USE_MVM_TOUR
+ m_PlayerEntryPanels[iPlayer]->SetItemsToolTip( m_pMouseOverTooltip );
+ // Show the first player
+ m_PlayerEntryPanels[iPlayer]->SetVisible( iPlayer == 0 );
+ // Setup the tab
+ CSteamID steamID = CSteamID( m_victoryInfo.players( iPlayer ).steam_id() );
+ if ( iPlayer < m_vecTabs.Count() )
+ {
+ m_vecTabs[iPlayer]->SetPlayer( steamID );
+ m_vecTabs[iPlayer]->SetVisible( true );
+ }
+
+ if ( iPlayer < m_vecTabButtons.Count() )
+ {
+ m_vecTabButtons[iPlayer]->SetVisible( true );
+ }
+ }
+
+ for ( int iNoPlayer = iPlayer; iNoPlayer < MVM_PLAYER_COUNT; ++iNoPlayer )
+ {
+ m_PlayerEntryPanels[iNoPlayer]->SetVisible( false );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryMannUpPanel::MannUpServerResponse( CMsgMvMVictoryInfo &pData )
+{
+ ClearData();
+
+ m_victoryInfo = pData;
+ m_hasData = true;
+ m_bAnimationComplete = false;
+
+ LoadVictoryData();
+
+ // Set the first tab active.
+ SetTabActive( 0 );
+
+ m_iMannUpLootIndex = 0;
+
+ if ( m_pNoItemServerContainer )
+ {
+ m_pNoItemServerContainer->SetVisible( false );
+ }
+}
+
+void CMvMVictoryMannUpPanel::ForceFinishAllAnimation()
+{
+ m_bAnimationComplete = true;
+
+ FOR_EACH_VEC( m_PlayerEntryPanels, i )
+ {
+ m_PlayerEntryPanels[i]->ForceFinishAllAnimation();
+ }
+}
+
+
+void CMvMVictoryMannUpPanel::SetTabActive( int nIndex )
+{
+ FOR_EACH_VEC( m_PlayerEntryPanels, i )
+ {
+ m_PlayerEntryPanels[i]->SetActive( i == nIndex );
+
+ if ( i < m_vecTabs.Count() )
+ {
+ m_vecTabs[i]->SetSelected( i == nIndex );
+ }
+ }
+}
+
+void CMvMVictoryMannUpPanel::OnCommand( const char *command )
+{
+ if ( !Q_strncmp( command, "switch_tab", ARRAYSIZE("switch_tab") - 1 ) )
+ {
+ int nIndex = atoi( command + ARRAYSIZE("switch_tab") - 1 ) - 1;
+
+ // Dont allow switching if we're still animating
+ if ( m_bAnimationComplete )
+ {
+ SetTabActive( nIndex );
+ }
+
+ }
+
+ BaseClass::OnCommand( command );
+}
+
+//-----------------------------------------------------------------------------
+// CMvMVictoryPanelContainer
+//-----------------------------------------------------------------------------
+DECLARE_BUILD_FACTORY( CMvMVictoryPanelContainer );
+
+CMvMVictoryPanelContainer::CMvMVictoryPanelContainer( Panel *parent, const char *pName )
+ : vgui::EditablePanel( parent, pName )
+{
+ SetMouseInputEnabled( true );
+
+ m_pVictoryPanelNormal = new CVictoryPanel( this, "VictoryPanelNormal" );
+ m_pVictoryPanelMannUp = new CMvMVictoryMannUpPanel( this, "VictoryPanelMannUp" );
+ m_pVictoryPanelMannUp->ClearData();
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryPanelContainer::ApplySchemeSettings( vgui::IScheme *pScheme )
+{
+ BaseClass::ApplySchemeSettings( pScheme );
+
+ LoadControlSettings( "resource/UI/MvMVictoryContainer.res" );
+
+ m_pVictoryPanelNormal->SetVisible( false );
+ m_pVictoryPanelMannUp->SetVisible( false );
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryPanelContainer::FireGameEvent( IGameEvent * event )
+{
+
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryPanelContainer::OnTick( void )
+{
+ if ( !IsVisible() )
+ return;
+
+ // The objective changed. This means we changedlevel
+ // or went to the main menu. Hide everything!
+ if ( m_pObjective != TFObjectiveResource() )
+ {
+ SetVisible( false );
+ m_pVictoryPanelMannUp->SetVisible( false );
+ m_pVictoryPanelNormal->SetVisible( false );
+ }
+
+ if ( m_pVictoryPanelMannUp->IsVisible() )
+ {
+ m_pVictoryPanelMannUp->OnTick();
+ }
+ if ( m_pVictoryPanelNormal->IsVisible() )
+ {
+ m_pVictoryPanelNormal->OnTick();
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryPanelContainer::OnCommand( const char *command )
+{
+ if ( !Q_stricmp( command, "done" ) )
+ {
+ SetMouseInputEnabled( false );
+ m_pVictoryPanelNormal->SetVisible( false );
+ m_pVictoryPanelMannUp->SetVisible( false );
+ SetVisible( false );
+
+ // Tell the population manager on the server that we're done viewing the panel
+ engine->ServerCmd( "done_viewing_loot" );
+
+ CreateReOpenNotification();
+ }
+}
+
+void CMvMVictoryPanelContainer::OnKeyCodePressed( vgui::KeyCode code )
+{
+ if ( code == STEAMCONTROLLER_A || code == STEAMCONTROLLER_B )
+ {
+ OnCommand( "done" );
+ }
+}
+
+
+void CMvMVictoryPanelContainer::CreateReOpenNotification()
+{
+ // Only do this for Mann-Up
+ CTFGSLobby *pLobby = GTFGCClientSystem()->GetLobby();
+ if ( !pLobby || !IsMannUpGroup( pLobby->GetMatchGroup() ) )
+ {
+ return;
+ }
+
+ int iCount = NotificationQueue_Count( &CShowMannUpLootNotification::IsNotificationType );
+
+ if ( iCount == 0 )
+ {
+ CShowMannUpLootNotification *pNotification = new CShowMannUpLootNotification();
+ pNotification->SetText( "#TF_MVM_Victory_Loot_Notification" );
+ pNotification->SetLifetime( 10000.0f ); // Last for quite a bit
+ NotificationQueue_Add( pNotification );
+ }
+}
+
+//-----------------------------------------------------------------------------
+void CMvMVictoryPanelContainer::ShowVictoryPanel( bool bIsReopening )
+{
+ SetVisible( true );
+ MakePopup();
+ MoveToFront();
+ SetKeyBoardInputEnabled( false );
+ SetMouseInputEnabled( true );
+ m_pObjective = TFObjectiveResource();
+
+ m_pVictoryPanelNormal->ResetVictoryPanel();
+
+ // popfile name
+ m_pVictoryPanelNormal->SetMapAndPopFile();
+
+#ifdef STAGING_ONLY
+ if ( tf_mvm_fake_loot.GetBool() )
+ {
+ m_pVictoryPanelMannUp->ShowVictoryPanel();
+ return;
+ }
+#endif
+
+ // Which Panel to show
+ CTFGSLobby *pLobby = GTFGCClientSystem()->GetLobby();
+ if ( pLobby && IsMannUpGroup( pLobby->GetMatchGroup() ) )
+ {
+ m_pVictoryPanelMannUp->ShowVictoryPanel();
+
+ if ( bIsReopening )
+ {
+ m_pVictoryPanelMannUp->ForceFinishAllAnimation();
+ }
+ }
+ else
+ {
+ m_pVictoryPanelNormal->SetVisible( true );
+ }
+}
+
+#ifdef STAGING_ONLY
+#include "tf_hud_mann_vs_machine_status.h"
+
+static void fake_mvm_victory_f()
+{
+ tf_mvm_fake_loot.SetValue( 1 );
+
+#ifdef USE_MVM_TOUR
+ const MvMTour_t &tour = GetItemSchema()->GetMvmTours()[ 0 ];
+#endif // USE_MVM_TOUR
+ const MvMMission_t &chal = GetItemSchema()->GetMvmMissions()[ 0 ];
+ // We'll send everybody the same summary message describing what everybody got
+ CMsgMvMVictoryInfo msgVictoryInfo;
+#ifdef USE_MVM_TOUR
+ msgVictoryInfo.set_tour_name( tour.m_sTourInternalName.Get() );
+#endif // USE_MVM_TOUR
+ msgVictoryInfo.set_mission_name( chal.m_sPop.Get() );
+ CSteamID steamID;
+
+ int nCount = 0;
+ for ( int i = 1 ; i <= gpGlobals->maxClients ; i++ )
+ {
+ CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
+
+ if ( pPlayer && pPlayer->GetTeamNumber() == TF_TEAM_RED && pPlayer->GetSteamID( &steamID ) )
+ {
+ CMsgMvMVictoryInfo_Player *pVictoryMsgPlayer = msgVictoryInfo.add_players();
+ pVictoryMsgPlayer->set_steam_id( steamID.ConvertToUint64() );
+ pVictoryMsgPlayer->set_badge_leveled( true );
+ pVictoryMsgPlayer->set_badge_progress_updated( true );
+ pVictoryMsgPlayer->set_badge_level( RandomInt(0,5) );
+ pVictoryMsgPlayer->set_badge_progress_bits( RandomInt(1,4) );
+ ++nCount;
+ }
+ }
+
+ if ( C_BasePlayer::GetLocalPlayer()->GetSteamID( &steamID ) )
+ {
+ for ( nCount; nCount < 6; ++nCount )
+ {
+ CMsgMvMVictoryInfo_Player *pVictoryMsgPlayer = msgVictoryInfo.add_players();
+ pVictoryMsgPlayer->set_steam_id(steamID.ConvertToUint64());
+ pVictoryMsgPlayer->set_badge_leveled(true);
+ pVictoryMsgPlayer->set_badge_progress_updated(true);
+ pVictoryMsgPlayer->set_badge_level(RandomInt(0, 5));
+ pVictoryMsgPlayer->set_badge_progress_bits(RandomInt(1, 4));
+ }
+ }
+
+ CTFHudMannVsMachineStatus *pMannVsMachineStatus = GET_HUDELEMENT( CTFHudMannVsMachineStatus );
+ if ( pMannVsMachineStatus )
+ {
+ pMannVsMachineStatus->ForceVictoryRefresh();
+ pMannVsMachineStatus->MVMVictory( false, 9999 );
+ pMannVsMachineStatus->MVMVictoryGCResponse( msgVictoryInfo );
+ }
+}
+
+ConCommand fake_mvm_victory( "fake_mvm_victory", fake_mvm_victory_f );
+#endif