diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_hud_saxxycontest.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/tf/tf_hud_saxxycontest.cpp')
| -rw-r--r-- | game/client/tf/tf_hud_saxxycontest.cpp | 882 |
1 files changed, 882 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_saxxycontest.cpp b/game/client/tf/tf_hud_saxxycontest.cpp new file mode 100644 index 0000000..4f66582 --- /dev/null +++ b/game/client/tf/tf_hud_saxxycontest.cpp @@ -0,0 +1,882 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//=======================================================================================// + +#include "cbase.h" + +#ifdef SAXXYMAINMENU_ENABLED + +#include "tf_hud_saxxycontest.h" +#include "econ_item_inventory.h" +#include "econ/confirm_dialog.h" +#include "econ/econ_controls.h" +#include "vgui/IVGui.h" +#include "vgui/ILocalize.h" +#include "vgui/IInput.h" +#include "vgui/ISurface.h" +#include "vgui_controls/TextEntry.h" +#include "vgui_controls/ComboBox.h" +#include "ienginevgui.h" +#include "replaybrowsermainpanel.h" +#include "gc_clientsystem.h" + +#include "rtime.h" +#include "tf_gcmessages.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +DECLARE_BUILD_FACTORY( CSaxxyAwardsPanel ); + +static void SaxxyAwards_ShowSubmitForm(); + +//----------------------------------------------------------------------------- + +int CSaxxyAwardsPanel::sm_nShowCounter = -1; + +//----------------------------------------------------------------------------- + +#define FOR_EACH_FLASH( i_ ) for ( int i_ = 0; i_ < MAX_FLASHES; ++i_ ) +#define FOR_EACH_GLOW( i_ ) for ( int i_ = 0; i_ < MAX_GLOWS; ++i_ ) +#define FOR_EACH_CLAP( i_ ) for ( int i_ = 0; i_ < MAX_CLAPS; ++i_ ) + +//----------------------------------------------------------------------------- + +#define NUM_FLASH_SOUNDS 11 +#define NUM_FLASH_MATERIALS 3 +#define FREAKOUT_THRESHOLD 0.7f + +//----------------------------------------------------------------------------- + +inline float SCurve( float t ) +{ + t = clamp( t, 0.0f, 1.0f ); + return t * t * (3 - 2*t); +} + +inline float LerpScale( float flIn, float flInMin, float flInMax, float flOutMin, float flOutMax ) +{ + float flDenom = flInMax - flInMin; + if ( flDenom == 0.0f ) + return 0.0f; + + float t = clamp( ( flIn - flInMin ) / flDenom, 0.0f, 1.0f ); + return Lerp( t, flOutMin, flOutMax ); +} + +//----------------------------------------------------------------------------- + +CSaxxyAwardsPanel::CSaxxyAwardsPanel( Panel *pParent, const char *pName ) +: EditablePanel( pParent, pName ), + m_pCameraFlashKv( NULL ) +{ + ivgui()->AddTickSignal( GetVPanel(), 17 ); + + Init(); + + ++sm_nShowCounter; +} + +CSaxxyAwardsPanel::~CSaxxyAwardsPanel() +{ + ivgui()->RemoveTickSignal( GetVPanel() ); +} + +void CSaxxyAwardsPanel::Init() +{ + m_flShowTime = GetCurrentTime(); + + m_vDialogsParent = (VPANEL)-1; + m_nNumTargetFlashes = 0; + m_flLastTickTime = 0.0f; + m_flEarliestNextFlashTime = 0.0f; + m_flGlowFade = 0.0f; + m_flNextPanelTestTime = 0.0f; + m_pBackgroundPanel = NULL; + m_pSaxxyModelPanel = NULL; + m_pStageBgPanel = NULL; + m_pSubmitButton = NULL; + m_pInfoLabel = NULL; + m_pCurtainPanel = NULL; + m_pContestOverLabel = NULL; + m_pSpotlightPanel = NULL; + + m_flCurtainStartAnimTime = -1.0f; + + FOR_EACH_CLAP( i ) + { + m_aClapPlayTimes[i] = 0.0f; + } + + for ( int i = 0; i < 2; ++i ) + { + m_aFilteredMousePos[i][0] = ScreenWidth() / 2; + m_aFilteredMousePos[i][1] = ScreenHeight() / 2; + } + + FOR_EACH_FLASH( i ) + { + CFmtStr fmtPanelName( "FlashPanel_%i", i ); + FlashInfo_t *pCurFlashInfo = &m_aFlashes[ i ]; + pCurFlashInfo->m_pPanel = new ImagePanel( NULL, fmtPanelName.Access() ); + pCurFlashInfo->m_bInUse = false; + } + + m_angModelRot.Init(); + m_vSaxxyDefaultPos.Init(); +} + +void CSaxxyAwardsPanel::ApplySettings( KeyValues *pInResourceData ) +{ + BaseClass::ApplySettings( pInResourceData ); + + // Delete old KeyValues + if ( m_pCameraFlashKv ) + { + m_pCameraFlashKv->deleteThis(); + m_pCameraFlashKv = NULL; + } + + // Copy camera flash keyvalues for creating instances + KeyValues *pCameraFlash = pInResourceData->FindKey( "CameraFlashSettings" ); + Assert( pCameraFlash ); + if ( pCameraFlash ) + { + m_pCameraFlashKv = pCameraFlash->MakeCopy(); + } +} + +bool CSaxxyAwardsPanel::CreateFlash() +{ + if ( GetActiveFlashCount() == MAX_FLASHES ) + return false; + + const int iUnusedSlot = GetUnusedFlashSlot(); Assert( iUnusedSlot >= 0 && iUnusedSlot < MAX_FLASHES ); + + if ( iUnusedSlot < 0 ) + return false; // Should never happen, since GetActiveFlashCount() didn't return 0 + + FlashInfo_t *pFlashInfo = &m_aFlashes[ iUnusedSlot ]; + ImagePanel *pPanel = pFlashInfo->m_pPanel; + + // Apply base settings + if ( !m_pCameraFlashKv ) + return false; + + pPanel->ApplySettings( m_pCameraFlashKv ); + + // Set the image to a random image + const int iImage = 1 + rand() % NUM_FLASH_MATERIALS; + CFmtStr fmtImageName( "../models/effects/camera_flash/camera_flash_%02i", iImage ); + pPanel->SetImage( fmtImageName.Access() ); + + pFlashInfo->m_flStartTime = GetCurrentTime(); + pFlashInfo->m_flLifeLength = FRand( m_flFlashLifeLengthMin, m_flFlashLifeLengthMax ); + pFlashInfo->m_bInUse = true; + + // Put the flash at a random position in the "flash bounds" + pFlashInfo->m_nCenterX = (int)FRand( m_nFlashBoundsX, m_nFlashBoundsX + m_nFlashBoundsW ); + pFlashInfo->m_nCenterY = (int)FRand( m_nFlashBoundsY, m_nFlashBoundsY + m_nFlashBoundsH ); + + pFlashInfo->m_nMinSize = (int)Lerp( FRand( 0.0f, 1.0f ), m_nFlashStartSizeMin, m_nFlashStartSizeMax ); + pFlashInfo->m_nMaxSize = pFlashInfo->m_nMinSize * FRand( .5f * m_flFlashMaxScale, m_flFlashMaxScale ); + + Assert( pFlashInfo->m_nMaxSize > pFlashInfo->m_nMinSize ); + + pFlashInfo->m_nCurW = pFlashInfo->m_nMinSize; + pFlashInfo->m_nCurH = pFlashInfo->m_nMinSize; + + PlaceFlash( pFlashInfo ); + + // Setup visibility + pPanel->SetAlpha( 0 ); + pPanel->SetVisible( true ); + + // Play a random flash sound + int iSound = rand() % NUM_FLASH_SOUNDS + 1; + Assert( iSound >= 1 && iSound <= NUM_FLASH_SOUNDS ); + CFmtStr fmtSoundFilename( "misc/tf_camera_%02i.wav", iSound ); + surface()->PlaySound( fmtSoundFilename.Access() ); + + return true; +} + +void CSaxxyAwardsPanel::PlaceFlash( FlashInfo_t *pFlashInfo ) +{ + pFlashInfo->m_pPanel->SetBounds( + pFlashInfo->m_nCenterX - pFlashInfo->m_nCurW / 2, + pFlashInfo->m_nCenterY - pFlashInfo->m_nCurH / 2, + pFlashInfo->m_nCurW, + pFlashInfo->m_nCurH + ); +} + +void CSaxxyAwardsPanel::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + LoadControlSettings( "resource/UI/MainMenu_SaxxyAwards.res" ); + + SetupContestPanels(); + + m_vDialogsParent = GetDialogsParent(); + + m_pBackgroundPanel = dynamic_cast< EditablePanel * >( FindChildByName( "Background" ) ); + m_pSubmitButton = dynamic_cast< CExButton *>( FindChildByName( "SubmitButton" ) ); + m_pInfoLabel = FindChildByName( "InfoLabel" ); + m_pContestOverLabel = FindChildByName( "ContestOverLabel" ); + m_pSpotlightPanel = dynamic_cast< ImagePanel * >( FindChildByName( "SpotlightPanel" ) ); + + m_pStageBgPanel = dynamic_cast< ImagePanel * >( FindChildByName( "StageBackground" ) ); + m_pCurtainPanel = dynamic_cast< EditablePanel * >( FindChildByName( "CurtainsPanel" ) ); + if ( m_pCurtainPanel ) + { + m_Curtains[0].m_pPanel = dynamic_cast< ImagePanel * >( m_pCurtainPanel->FindChildByName( "CurtainsLeft" ) ); + m_Curtains[1].m_pPanel = dynamic_cast< ImagePanel * >( m_pCurtainPanel->FindChildByName( "CurtainsRight" ) ); + + // Hide curtains if this isn't the first view + if ( sm_nShowCounter > 0 ) + { + for ( int i = 0; i < 2; ++i ) + { + if ( !m_Curtains[i].m_pPanel ) + continue; + m_Curtains[i].m_pPanel->SetVisible( false ); + } + } + + // Set all flash parents to background panel + if ( m_pBackgroundPanel ) + { + FOR_EACH_FLASH( i ) + { + m_aFlashes[ i ].m_pPanel->SetParent( m_pStageBgPanel ); + } + } + + // Setup Saxxy model + m_pSaxxyModelPanel = dynamic_cast< CBaseModelPanel * >( m_pCurtainPanel->FindChildByName( "SaxxyModelPanel" ) ); + if ( m_pSaxxyModelPanel ) + { + MDLHandle_t hModel = mdlcache->FindMDL( "models/effects/saxxy_flash/saxxy_flash.mdl" ); + m_pSaxxyModelPanel->SetMDL( hModel ); + m_pSaxxyModelPanel->SetSequence( ACT_RESET ); + mdlcache->Release( hModel ); // counterbalance addref from within FindMDL + + m_pSaxxyModelPanel->InvalidateLayout( true, true ); // Updates player position + m_vSaxxyDefaultPos = m_pSaxxyModelPanel->GetPlayerPos(); + } + } +} + +void CSaxxyAwardsPanel::PerformLayout() +{ + BaseClass::PerformLayout(); +} + +void CSaxxyAwardsPanel::Refresh() +{ + Init(); + InvalidateLayout( true, true ); +} + +void CSaxxyAwardsPanel::OnCommand( const char *pCommand ) +{ + if ( FStrEq( pCommand, "viewdetails" ) ) + { + if ( steamapicontext && steamapicontext->SteamFriends() ) + { + steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( "http://www.teamfortress.com/saxxyawards/" ); + } + } + else if ( FStrEq( pCommand, "submit" ) ) + { + SaxxyAwards_ShowSubmitForm(); + } + else + { + BaseClass::OnCommand( pCommand ); + } +} + +void CSaxxyAwardsPanel::OnTick() +{ + if ( C_BasePlayer::GetLocalPlayer() ) + return; + + if ( ReplayUI_GetBrowserPanel() && ReplayUI_GetBrowserPanel()->IsVisible() ) + return; + + if ( !IsVisible() ) + return; + + // Calculate elapsed + const float flCurTime = GetCurrentTime(); + const float flElapsed = clamp( flCurTime - m_flLastTickTime, 0, 0.1f ); + m_flLastTickTime = flCurTime; + +// Msg( "initial freakout? %s\n", InInitialFreakoutPeriod() ? "yes" : "no" ); + + const bool bOtherPanelsOpen = AreOtherPanelsOpen( flCurTime ); + + UpdateMousePos( flElapsed ); + CurtainsThink(); + RotateModel( flElapsed ); + FlashThink( bOtherPanelsOpen ); + SpotlightThink(); + ClapsThink( flCurTime, flElapsed, bOtherPanelsOpen ); + + SetupContestPanels(); +} + +bool CSaxxyAwardsPanel::AreOtherPanelsOpen( float flCurTime ) +{ + static bool s_bOtherPanelsOpen = false; + + if ( flCurTime < m_flNextPanelTestTime ) + return s_bOtherPanelsOpen; + + // Setup next think time + m_flNextPanelTestTime = flCurTime + 2.0f; + + // Do tests to see if other panels are open + bool bOtherPanelsOpen = false; + { + const int nNumGameUICarePanels = 4; + const char *pCarePanels[nNumGameUICarePanels] = { "GameConsole", "character_info", "store_panel", "BugUIPanel" }; + bOtherPanelsOpen = bOtherPanelsOpen || AreNonMainMenuPanelsOpen( enginevgui->GetPanel( PANEL_GAMEUIDLL ), pCarePanels, nNumGameUICarePanels ); + } + + // Msg( "-----\n" ); + + if ( m_vDialogsParent != (VPANEL)-1 ) + { + const int nNumCarePanels = 2; + const char *pCarePanels[nNumCarePanels] = { "CServerBrowserDialog", "OptionsDialog" }; + + bOtherPanelsOpen = bOtherPanelsOpen || AreNonMainMenuPanelsOpen( m_vDialogsParent, pCarePanels, nNumCarePanels ); + } + + // Cache so we don't have to think every frame + s_bOtherPanelsOpen = bOtherPanelsOpen; + + return bOtherPanelsOpen; +} + +void CSaxxyAwardsPanel::PaintBackground() +{ + BaseClass::PaintBackground(); +} + +void CSaxxyAwardsPanel::UpdateMousePos( float flElapsed ) +{ + // Set target mouse pos + int x, y; + input()->GetCursorPos( x, y ); + m_aFilteredMousePos[1][0] = x; + m_aFilteredMousePos[1][1] = y; + + // Move towards target + const float t = flElapsed * 1.5f; + m_aFilteredMousePos[0][0] = Lerp( t, m_aFilteredMousePos[0][0], m_aFilteredMousePos[1][0] ); + m_aFilteredMousePos[0][1] = Lerp( t, m_aFilteredMousePos[0][1], m_aFilteredMousePos[1][1] ); + +// Msg( "mouse pos: current=(%f %f) target=(%f %f)\n", m_aFilteredMousePos[0][0], m_aFilteredMousePos[0][1], +// m_aFilteredMousePos[1][0], m_aFilteredMousePos[1][1] ); +} + +void CSaxxyAwardsPanel::CurtainsThink() +{ + if ( !m_Curtains[0].m_pPanel || !m_Curtains[1].m_pPanel ) + return; + + // Has enough time passed? Only open the curtains m_flOpenCurtainsTime seconds after m_flShowTime. + const float flElapsedSinceShowTime = GetCurrentTime() - m_flShowTime; + if ( flElapsedSinceShowTime < m_flOpenCurtainsTime ) + return; + + // Start animating now? + if ( CurtainsClosed() ) + { + m_flCurtainStartAnimTime = GetCurrentTime(); + + // Play crowd the first time the menu is shown + if ( sm_nShowCounter == 0 ) + { + surface()->PlaySound( "misc/boring_applause_1.wav" ); + } + + // Init positions to those set in res file + for ( int i = 0; i < 2; ++i ) + { + m_Curtains[i].m_pPanel->GetPos( m_Curtains[i].m_aInitialPos[0], m_Curtains[i].m_aInitialPos[1] ); + } + } + else // Already animating? + { + // Set updated positions for both curtains + const float flCurTime = GetCurrentTime(); + for ( int i = 0; i < 2; ++i ) + { + CurtainInfo_t *pCurCurtain = &m_Curtains[i]; + Panel *pPanel = pCurCurtain->m_pPanel; + + const int nSign = i == 0 ? -1 : 1; + const float t = SCurve( clamp( ( flCurTime - m_flCurtainStartAnimTime ) / m_flCurtainAnimDuration, 0.0f, 1.0f ) ); + int aCurPos[2] = { + Lerp( t, pCurCurtain->m_aInitialPos[0], pCurCurtain->m_aInitialPos[0] + nSign * pPanel->GetWide() ), + pCurCurtain->m_aInitialPos[1] + }; + m_Curtains[i].m_pPanel->SetPos( aCurPos[0], aCurPos[1] ); + } + } +} + +void CSaxxyAwardsPanel::RotateModel( float flElapsed ) +{ + if ( m_pSaxxyModelPanel ) + { + const float flOsc = .28f * sinf( .5f * GetCurrentTime() ); + const Vector vCurPos( + Lerp( m_flGlowFade, m_vSaxxyDefaultPos.x, m_vSaxxyDefaultPos.x - 8.0f ), + m_vSaxxyDefaultPos.y, + Lerp( m_flGlowFade, m_vSaxxyDefaultPos.z, m_vSaxxyDefaultPos.z - 3.0f ) + flOsc + ); + m_angModelRot.y += flElapsed * 45 * 0.5f * Lerp( m_flGlowFade, 0.5f, 1.0f ); + m_pSaxxyModelPanel->SetModelAnglesAndPosition( m_angModelRot, vCurPos ); + } +} + +void CSaxxyAwardsPanel::FlashThink( bool bOtherPanelsOpen ) +{ + if ( !m_pSaxxyModelPanel ) + return; + + // Set the target number of flashes based on how far the mouse is from the saxxy + int aModelBounds[4]; + m_pSaxxyModelPanel->GetSize( aModelBounds[2], aModelBounds[3] ); + ipanel()->GetAbsPos( m_pSaxxyModelPanel->GetVPanel(), aModelBounds[0], aModelBounds[1] ); + const float flDistX = aModelBounds[0] + aModelBounds[2]/2.0f - m_aFilteredMousePos[0][0]; + const float flDistY = aModelBounds[1] + aModelBounds[3]/2.0f - m_aFilteredMousePos[0][1]; + const float flDistanceToSaxxy = sqrtf( flDistX * flDistX + flDistY * flDistY ); +// Msg( "xdist: %f ydist: %f distance: %f\n", flDistX, flDistY, flDistanceToSaxxy ); + + const float flMaxDistance = 750.0f; + m_flGlowFade = clamp( 1.0f - clamp( flDistanceToSaxxy / flMaxDistance, 0.0f, 1.0f ), 0.0f, 1.0f ); +// Msg( "glow fade: %f\n", m_flGlowFade ); + + const float flCurTime = GetCurrentTime(); + + // Set alpha for active flashes, kill any that are done animating, update positions of actives + FOR_EACH_FLASH( i ) + { + FlashInfo_t *pCurFlashInfo = &m_aFlashes[ i ]; + if ( !pCurFlashInfo->m_bInUse ) + continue; + + const float t = ( flCurTime - pCurFlashInfo->m_flStartTime ) / pCurFlashInfo->m_flLifeLength; + if ( t >= 1.0f ) + { + ClearFlash( pCurFlashInfo ); + } + else + { + // Set opacity + const float flPhase = M_PI * t; + const float flFade = clamp( sinf( flPhase ), 0.0f, 1.0f ); + pCurFlashInfo->m_pPanel->SetAlpha( 255 * flFade ); + + // Update size + pCurFlashInfo->m_nCurW = (int)Lerp( flFade, pCurFlashInfo->m_nMinSize, pCurFlashInfo->m_nMaxSize ); + pCurFlashInfo->m_nCurH = pCurFlashInfo->m_nCurW; + + // Update position/size + PlaceFlash( pCurFlashInfo ); + } + } + + // Create new flashes / freak out + const bool bEnoughTimeHasPassed = flCurTime >= m_flEarliestNextFlashTime; + if ( !bOtherPanelsOpen && bEnoughTimeHasPassed && FlashingStartTimePassed() && GetUnusedFlashCount() ) + { + CreateFlash(); + + const bool bFreakout = InInitialFreakoutPeriod() || InFreakoutMode(); + const float flOffset = bFreakout ? FRand( .1f, .2f ) : FRand( 2.0f, 5.0f ); + m_flEarliestNextFlashTime = flCurTime + flOffset; + } +} + +VPANEL CSaxxyAwardsPanel::GetDialogsParent() +{ + VPANEL vGameUI = enginevgui->GetPanel( PANEL_GAMEUIDLL ); + const int nNumChildren = ipanel()->GetChildCount( vGameUI ); + + for ( int i = 0; i < nNumChildren; ++i ) + { + VPANEL vChild = ipanel()->GetChild( vGameUI, i ); + const char *pDlgName = ipanel()->GetName( vChild ); + if ( FStrEq( pDlgName, "BaseGameUIPanel" ) ) + { + return vChild; + } + } + + return (VPANEL)-1; +} + +bool CSaxxyAwardsPanel::AreNonMainMenuPanelsOpen( VPANEL vRoot, const char **pCarePanels, int nNumCarePanels ) +{ + int nNumChildren = ipanel()->GetChildCount( vRoot ); + for ( int i = 0; i < nNumChildren; ++i ) + { + VPANEL vChild = ipanel()->GetChild( vRoot, i ); + const char *pDlgName = ipanel()->GetName( vChild ); + bool bCare = false; + for ( int j = 0; j < nNumCarePanels; ++j ) + { + if ( FStrEq( pCarePanels[j], pDlgName ) ) + { +// Msg( "CARE: %s\n", pDlgName ); + bCare = true; + break; + } + } + if ( !bCare ) + { +// Msg( "DONT CARE: %s\n", pDlgName ); + continue; + } + + if ( ipanel()->IsVisible( vChild ) ) + return true; + } + + return false; +} + +void CSaxxyAwardsPanel::SpotlightThink() +{ + if ( !m_pSpotlightPanel ) + return; + + const float flOscillateAmount = 0.10f; + const float flSpeed = 0.7f; + const float flFade = .1f + flOscillateAmount * ( .5f + .5f * cosf( flSpeed * GetCurrentTime() ) ); + m_pSpotlightPanel->SetAlpha( 255 * flFade ); +} + +void CSaxxyAwardsPanel::PlaySomeClaps() +{ + // Play each clap offset by a bit + const float flCurTime = GetCurrentTime(); + FOR_EACH_CLAP( i ) + { + // If this sound is already playing, continue + float &flCurClapPlayTime = m_aClapPlayTimes[i]; + + const bool bAlreadyPlaying = flCurClapPlayTime != 0.0f; + if ( bAlreadyPlaying ) + continue; + + // Some chance that not all claps will be played + if ( rand() % 100 < 30 ) + { + SetNextPossibleClapTime( &flCurClapPlayTime ); + continue; + } + + flCurClapPlayTime = flCurTime + LerpScale( FRand( 0.0f, 1.0f ), 0.0f, 1.0f, .3f, 1.5f ); + } +} + +void CSaxxyAwardsPanel::ClapsThink( float flCurTime, float flElapsed, bool bOtherPanelsOpen ) +{ + if ( !bOtherPanelsOpen && InFreakoutMode() && !InInitialFreakoutPeriod() ) + { + PlaySomeClaps(); + } + + FOR_EACH_CLAP( i ) + { + float &flCurClapTime = m_aClapPlayTimes[i]; +// Msg( "clap %i: %f\n", i, flCurClapTime ); + + if ( flCurClapTime < 0.0f ) + { + // Once enough time has elapsed, this slot will be > 0 and available again. + flCurClapTime = MIN( flCurClapTime + flElapsed, 0.0f ); + continue; + } + + // Start playing now? + if ( flCurClapTime <= flCurTime && flCurClapTime != 0.0f ) + { + // Play. + CFmtStr fmtSound( "misc/clap_single_%i.wav", i + 1 ); + surface()->PlaySound( fmtSound.Access() ); + + SetNextPossibleClapTime( &flCurClapTime ); + } + } +} + +void CSaxxyAwardsPanel::SetNextPossibleClapTime( float *pClapTime ) +{ + // Set the next possible time to the duration of the sound + some randomn offset + const float flExtraOffset = LerpScale( FRand( 0.0f, 1.0f ), 0.0f, 1.0f, 1.0f, 5.0f ); + *pClapTime = -( m_flClapSoundDuration + flExtraOffset ); +} + +void CSaxxyAwardsPanel::ClearFlash( FlashInfo_t *pFlashInfo ) +{ + pFlashInfo->m_bInUse = false; + pFlashInfo->m_pPanel->SetAlpha( 0 ); + pFlashInfo->m_pPanel->SetVisible( false ); +} + +void CSaxxyAwardsPanel::ClearFlashes() +{ + FOR_EACH_FLASH( i ) + { + ClearFlash( &m_aFlashes[i] ); + } +} + +int CSaxxyAwardsPanel::GetActiveFlashCount() const +{ + int nResult = 0; + FOR_EACH_FLASH( i ) + { + if ( m_aFlashes[ i ].m_bInUse ) + ++nResult; + } + return nResult; +} + +int CSaxxyAwardsPanel::GetUnusedFlashCount() const +{ + return MAX_FLASHES - GetActiveFlashCount(); +} + +int CSaxxyAwardsPanel::GetUnusedFlashSlot() const +{ + FOR_EACH_FLASH( i ) + { + if ( !m_aFlashes[ i ].m_bInUse ) + return i; + } + return -1; +} + +float CSaxxyAwardsPanel::GetCurrentTime() const +{ + return gpGlobals->curtime; +} + +bool CSaxxyAwardsPanel::InInitialFreakoutPeriod() const +{ + return ( GetCurrentTime() - m_flShowTime ) <= m_flInitialFreakoutDuration; +} + +bool CSaxxyAwardsPanel::InFreakoutMode() const +{ + return m_flGlowFade > FREAKOUT_THRESHOLD; +} + +bool CSaxxyAwardsPanel::CurtainsClosed() const +{ + return m_flCurtainStartAnimTime < 0.0f; +} + +bool CSaxxyAwardsPanel::FlashingStartTimePassed() const +{ + return ( GetCurrentTime() - m_flShowTime ) >= m_flFlashStartTime; +} + +void CSaxxyAwardsPanel::SetupContestPanels() +{ + CRTime now; + now.SetToCurrentTime(); + now.SetToGMT( true ); + + CRTime deadline = CRTime::RTime32FromString( "2011-05-21 00:00:00" ); + deadline.SetToGMT( true ); + + if ( now > deadline ) + { + if ( m_pInfoLabel && m_pInfoLabel->IsVisible() ) + { + m_pInfoLabel->SetVisible( false ); + } + if ( m_pSubmitButton && m_pSubmitButton->IsVisible() ) + { + m_pSubmitButton->SetVisible( false ); + } + if ( m_pContestOverLabel && !m_pContestOverLabel->IsVisible() ) + { + m_pContestOverLabel->SetVisible( true ); + } + } +} + +CSaxxyAwardsSubmitForm::CSaxxyAwardsSubmitForm( Panel *pParent ) +: BaseClass( pParent, "SaxxySubmitForm" ), + m_pURLInput( NULL ), + m_pCategoryCombo( NULL ) +{ +} + +void CSaxxyAwardsSubmitForm::ApplySchemeSettings( IScheme *pScheme ) +{ + // Link in TF scheme + extern IEngineVGui *enginevgui; + vgui::HScheme pTFScheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme" ); + SetScheme( pTFScheme ); + SetProportional( true ); + + BaseClass::ApplySchemeSettings( vgui::scheme()->GetIScheme( pTFScheme ) ); + + LoadControlSettings( "resource/UI/SaxxyAwards_SubmitForm.res" ); + + m_pURLInput = dynamic_cast< TextEntry * >( FindChildByName( "URLInput" ) ); + if ( m_pURLInput ) + { + m_pURLInput->SetText( "#Replay_YouTubeURL" ); + } + + m_pCategoryCombo = dynamic_cast< ComboBox * >( FindChildByName( "CategoryCombo" ) ); + if ( m_pCategoryCombo ) + { + // Add "Categories" text + const int nDefaultItemID = m_pCategoryCombo->AddItem( "#Replay_Category", NULL ); + m_pCategoryCombo->ActivateItem( nDefaultItemID ); + + // Add all categories + const wchar_t *pCategoryText = L""; + int i = 0; + while ( true ) + { + CFmtStr fmtCategoryToken( "#Replay_Contest_Category%i", i++ ); + pCategoryText = g_pVGuiLocalize->Find( fmtCategoryToken.Access() ); + if ( !pCategoryText || !pCategoryText[0] ) + break; + m_pCategoryCombo->AddItem( pCategoryText, NULL ); + } + + m_pCategoryCombo->SetNumberOfEditLines( i ); + } +} + +void CSaxxyAwardsSubmitForm::PerformLayout() +{ + BaseClass::PerformLayout(); +} + +void CSaxxyAwardsSubmitForm::OnCommand( const char *pCommand ) +{ + if ( FStrEq( pCommand, "submit" ) ) + { + // need a category + if ( m_pCategoryCombo->GetActiveItem() == 0 ) + { + ShowMessageBox( "#Replay_Contest_StatusTitle", "#Replay_Contest_ChooseCategory", "#GameUI_OK" ); + return; + } + + // need a non-empty string + char szText[256]; + m_pURLInput->GetText( szText, sizeof( szText ) ); + if ( Q_strlen( szText ) == 0 ) + { + ShowMessageBox( "#Replay_Contest_StatusTitle", "#Replay_Contest_EnterURL", "#GameUI_OK" ); + return; + } + + // waiting dialog + ShowWaitingDialog( new CGenericWaitingDialog( this ), "#Replay_Contest_Waiting", true, true, 30.0f ); + + // send the url + GCSDK::CProtoBufMsg< CMsgReplaySubmitContestEntry > msg( k_EMsgGCReplay_SubmitContestEntry ); + msg.Body().set_youtube_url( szText ); + msg.Body().set_category( m_pCategoryCombo->GetActiveItem() - 1 ); + GCClientSystem()->GetGCClient()->BSendMessage( msg ); + + // close the submit dialog + Close(); + } + else if ( FStrEq( pCommand, "cancel" ) ) + { + Close(); + } + else if ( FStrEq( pCommand, "rules" ) ) + { + if ( steamapicontext && steamapicontext->SteamFriends() ) + { + steamapicontext->SteamFriends()->ActivateGameOverlayToWebPage( "http://www.teamfortress.com/saxxyawards/#rules" ); + } + } + else + { + BaseClass::OnCommand( pCommand ); + } +} + +void CSaxxyAwardsSubmitForm::Close() +{ + TFModalStack()->PopModal( this ); + MarkForDeletion(); +} + +void CSaxxyAwardsSubmitForm::OnKeyCodeTyped( vgui::KeyCode nCode ) +{ + if ( nCode == KEY_ESCAPE ) + { + Close(); + } + else + { + BaseClass::OnKeyCodeTyped( nCode ); + } +} + +static void SaxxyAwards_ShowSubmitForm() +{ + CSaxxyAwardsSubmitForm *pSubmitDialog = vgui::SETUP_PANEL( new CSaxxyAwardsSubmitForm( NULL ) ); + + pSubmitDialog->SetVisible( true ); + pSubmitDialog->MakePopup(); + pSubmitDialog->MoveToFront(); + pSubmitDialog->SetKeyBoardInputEnabled( true ); + pSubmitDialog->SetMouseInputEnabled( true ); + TFModalStack()->PushModal( pSubmitDialog ); +} + +//----------------------------------------------------------------------------- +// Purpose: Refresh the saxxy awards portion of the main menu +//----------------------------------------------------------------------------- +class CGC_Replay_SubmitContestEntryResponse_Status : public GCSDK::CGCClientJob +{ +public: + CGC_Replay_SubmitContestEntryResponse_Status( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} + virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) + { + GCSDK::CProtoBufMsg< CMsgReplaySubmitContestEntryResponse > msg( pNetPacket ); + + CloseWaitingDialog(); + + if ( msg.Body().success() ) + { + ShowMessageBox( "#Replay_Contest_StatusTitle", "#Replay_Contest_StatusSuccess", "#GameUI_OK" ); + } + else + { + ShowMessageBox( "#Replay_Contest_StatusTitle", "#Replay_Contest_StatusFailure", "#GameUI_OK" ); + } + + return true; + } +protected: +}; +GC_REG_JOB( GCSDK::CGCClient, CGC_Replay_SubmitContestEntryResponse_Status, "CGC_Replay_SubmitContestEntryResponse_Status", k_EMsgGCReplay_SubmitContestEntryResponse, GCSDK::k_EServerTypeGCClient ); +#endif // #ifdef SAXXYMAINMENU_ENABLED
\ No newline at end of file |