This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View File

@@ -0,0 +1,338 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD element to show we are having connectivity trouble
//
//=====================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhud_autodisconnect.h"
#include "hud_macros.h"
#include "view.h"
#include "inetchannelinfo.h"
#include "c_cs_playerresource.h"
#include "c_cs_player.h"
#include "cs_gamerules.h"
#include "cs_client_gamestats.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudAutodisconnect );
SFUI_BEGIN_GAME_API_DEF
SFUI_END_GAME_API_DEF( SFHudAutodisconnect, Autodisconnect );
SFHudAutodisconnect::SFHudAutodisconnect( const char *value ) : SFHudFlashInterface( value ),
m_sfuiControlBg( NULL ), m_sfuiControlTopLabel( NULL ), m_sfuiControlBottomLabel( NULL ), m_sfuiControlTimerLabel( NULL ), m_sfuiControlTimerIcon( NULL )
{
// This HUD element should never be hidden, so do not call SetHiddenBits
}
SFHudAutodisconnect::~SFHudAutodisconnect()
{
}
void SFHudAutodisconnect::ShowPanel( bool bShow )
{
if ( m_FlashAPI )
{
WITH_SLOT_LOCKED
{
if ( bShow )
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowPanel", NULL, 0 );
else
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "HidePanel", NULL, 0 );
}
}
}
ConVar cl_connection_trouble_show( "cl_connection_trouble_show", "0", FCVAR_RELEASE, "Show connection trouble HUD warnings" );
DEVELOPMENT_ONLY_CONVAR( cl_connection_trouble_force, 0 );
static bool Helper_ShouldInformPlayerAboutConnectionLossChoke()
{
static ConVarRef cl_connection_trouble_info( "cl_connection_trouble_info" );
if ( !cl_connection_trouble_info.IsValid() )
return false;
// No error - nothing to show
if ( !cl_connection_trouble_info.GetString()[ 0 ] )
return false;
// Not a transient error - always show
if ( cl_connection_trouble_info.GetString()[ 0 ] != '@' )
return true;
// UI debugging feature
if ( cl_connection_trouble_force.GetInt() == 1 ) // Allow to always show for testing
return true;
// Don't care when playing demos or GOTV or on listen server
if ( g_bEngineIsHLTV || engine->IsClientLocalToActiveServer() )
return false;
// Not when loading
if ( engine->IsDrawingLoadingImage() )
return false;
// No local player - don't show
C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
if ( !pLocalPlayer )
return false;
// Show only when on active team
switch ( pLocalPlayer->GetTeamNumber() )
{
case TEAM_TERRORIST:
case TEAM_CT:
break;
default:
return false;
}
if ( !pLocalPlayer->IsAlive() )
return false;
// Need game rules
if ( !CSGameRules() )
return false;
// If the round is already won, then don't show warnings (things will start resetting and cause a spike)
if ( CSGameRules()->IsRoundOver() )
return false;
// Don't show warnings during freeze period or warmup (that's when players are joining)
if ( CSGameRules()->IsFreezePeriod() || CSGameRules()->IsWarmupPeriod() )
return false;
// Don't show warning for 3 seconds after freezetime ended (need to accumulate choke/loss)
if ( gpGlobals->curtime < CSGameRules()->GetRoundStartTime() + 3.0f )
return false;
// Don't show warnings if local player just spawned or respawned (AR / DM / etc.)
if ( pLocalPlayer->m_flLastSpawnTimeIndex > gpGlobals->curtime - 3.0f )
return false;
//
// OGS recording
//
static double s_dTimeLastOgsRecordWritten = 0;
static double s_dTimeTrackingPeakStarted = 0;
static float s_flTrackedPeakValue = 0;
static CSClientCsgoGameEventType_t s_chTypeTrackingPeak = k_CSClientCsgoGameEventType_ConnectionProblem_Generic;
double dTimeNow = Plat_FloatTime();
if ( dTimeNow > s_dTimeLastOgsRecordWritten + 60 )
{
bool bRecordNow = false;
CSClientCsgoGameEventType_t chType = k_CSClientCsgoGameEventType_ConnectionProblem_Generic;
float flCurrentValue = 0;
if ( INetChannelInfo *pChannelInfo = engine->GetNetChannelInfo() )
{
float flPacketLoss = pChannelInfo->GetAvgLoss( FLOW_INCOMING );
float flPacketChoke = pChannelInfo->GetAvgChoke( FLOW_INCOMING );
if ( flPacketLoss > 0 )
{
chType = k_CSClientCsgoGameEventType_ConnectionProblem_Loss;
flCurrentValue = flPacketLoss;
}
else if ( flPacketChoke > 0 )
{
chType = k_CSClientCsgoGameEventType_ConnectionProblem_Choke;
flCurrentValue = flPacketChoke;
}
}
if ( ( chType != s_chTypeTrackingPeak ) || ( dTimeNow > s_dTimeTrackingPeakStarted + 0.75 ) )
{ // Start tracking this problem type (or weren't tracking for some time?)
s_chTypeTrackingPeak = chType;
s_dTimeTrackingPeakStarted = dTimeNow;
s_flTrackedPeakValue = 0;
}
else if ( dTimeNow > s_dTimeTrackingPeakStarted + 0.25 )
{ // Have been tracking for 0.25 seconds: time to record
bRecordNow = true;
}
// Track max value over the period
s_flTrackedPeakValue = MAX( s_flTrackedPeakValue, flCurrentValue );
if ( bRecordNow )
{
s_dTimeLastOgsRecordWritten = dTimeNow;
uint64 ullData = int(s_flTrackedPeakValue * 1000);
g_CSClientGameStats.AddClientCSGOGameEvent( chType, pLocalPlayer->GetAbsOrigin(), pLocalPlayer->EyeAngles(), ullData );
DevMsg( "%s (peak at %.1f%%)\n", cl_connection_trouble_info.GetString(), s_flTrackedPeakValue*100 );
// Reset the data
s_chTypeTrackingPeak = k_CSClientCsgoGameEventType_ConnectionProblem_Generic;
s_flTrackedPeakValue = 0;
}
}
if ( !cl_connection_trouble_show.GetBool() ) // Allow to always hide transient errors (data collection only)
return false;
// Does not hide with the rest of the HUD
return true;
}
void SFHudAutodisconnect::ProcessInput( void )
{
static ConVarRef cl_connection_trouble_info( "cl_connection_trouble_info" );
if ( FlashAPIIsValid() && m_bActive && cl_connection_trouble_info.IsValid() && cl_connection_trouble_info.GetString()[0] )
{
//
// See cl_main.cpp CL_Move
// bool hasProblem = cl.m_NetChannel->IsTimingOut() && !demoplayer->IsPlayingBack() && cl.IsActive();
//
// Check for disconnect?
float TimeoutValue = -1.0f, Percentage = -1.0f;
if ( 1 == sscanf( cl_connection_trouble_info.GetString(), "disconnect(%f)", &TimeoutValue ) )
{
if ( TimeoutValue < 0 )
TimeoutValue = 0;
char cTimerStr[ 128 ];
V_snprintf( cTimerStr, sizeof(cTimerStr), "%02d:%02d", Floor2Int( TimeoutValue / 60.f ), ( Floor2Int(TimeoutValue) % 60 ) );
WITH_SLOT_LOCKED
{
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_HEADER" );
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlBottomLabel, "#SFUI_CONNWARNING_BODY" );
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTimerLabel, cTimerStr );
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, true );
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, true );
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, true );
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, true );
}
}
else if ( 2 == sscanf( cl_connection_trouble_info.GetString(), "@%f:loss(%f)", &TimeoutValue, &Percentage ) )
{
WITH_SLOT_LOCKED
{
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_Bandwidth_PacketLoss" );
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, false );
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, false );
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, false );
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, false );
}
}
else if ( 2 == sscanf( cl_connection_trouble_info.GetString(), "@%f:choke(%f)", &TimeoutValue, &Percentage ) )
{
WITH_SLOT_LOCKED
{
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_Bandwidth_Choking" );
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, false );
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, false );
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, false );
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, false );
}
}
else
{
WITH_SLOT_LOCKED
{
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_HEADER" );
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, false );
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, false );
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, false );
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, false );
}
}
}
}
void SFHudAutodisconnect::FlashReady( void )
{
// Grab a pointer to the timeout text box
if ( SFVALUE panelRoot = m_pScaleformUI->Value_GetMember( m_FlashAPI, "Panel" ) )
{
if ( SFVALUE panelAnim = m_pScaleformUI->Value_GetMember( panelRoot, "PanelAnim" ) )
{
m_sfuiControlBg = m_pScaleformUI->Value_GetMember( panelAnim, "AutoDisconnectBg" );
if ( SFVALUE text = m_pScaleformUI->Value_GetMember( panelAnim, "Text" ) )
{
m_sfuiControlTopLabel = m_pScaleformUI->Value_GetMember( text, "AutoDisconnectText1" );
m_sfuiControlBottomLabel = m_pScaleformUI->Value_GetMember( text, "AutoDisconnectText2" );
m_sfuiControlTimerLabel = m_pScaleformUI->Value_GetMember( text, "TimerText" );
m_sfuiControlTimerIcon = m_pScaleformUI->Value_GetMember( text, "TimerIcon" );
SafeReleaseSFVALUE( text );
}
SafeReleaseSFVALUE( panelAnim );
}
SafeReleaseSFVALUE( panelRoot );
}
}
bool SFHudAutodisconnect::PreUnloadFlash( void )
{
SafeReleaseSFVALUE( m_sfuiControlBg );
SafeReleaseSFVALUE( m_sfuiControlTopLabel );
SafeReleaseSFVALUE( m_sfuiControlBottomLabel );
SafeReleaseSFVALUE( m_sfuiControlTimerLabel );
SafeReleaseSFVALUE( m_sfuiControlTimerIcon );
return true;
}
void SFHudAutodisconnect::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
// We assume we are offline-only for splitscreen multiplayer, so we allow this to be displayed in the split screen slot like
// the rest of the HUD is. If we support splitscreen online down the road, this should be moved into the fullscreen slot.
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudAutodisconnect, this, Autodisconnect );
}
// When initially loaded, hide any previous message
ShowPanel( false );
m_bActive = false;
}
void SFHudAutodisconnect::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
void SFHudAutodisconnect::Reset( void )
{
ShowPanel( false );
}
bool SFHudAutodisconnect::ShouldDraw( void )
{
return Helper_ShouldInformPlayerAboutConnectionLossChoke();
}
void SFHudAutodisconnect::SetActive( bool bActive )
{
if ( m_bActive != bActive )
{
ShowPanel( bActive );
}
CHudElement::SetActive( bActive );
}

View File

@@ -0,0 +1,41 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD element to show we are having connectivity trouble
//
//=====================================================================================//
#ifndef SFHUDAUTODISCONNECT_H_
#define SFHUDAUTODISCONNECT_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
class SFHudAutodisconnect : public SFHudFlashInterface
{
public:
explicit SFHudAutodisconnect( const char *value );
virtual ~SFHudAutodisconnect();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual bool ShouldDraw( void );
virtual void SetActive( bool bActive );
virtual void Reset( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
protected:
void ShowPanel( bool bShow );
protected:
SFVALUE m_sfuiControlBg, m_sfuiControlTopLabel, m_sfuiControlBottomLabel, m_sfuiControlTimerLabel, m_sfuiControlTimerIcon;
};
#endif /* SFHUDAUTODISCONNECT_H_ */

View File

@@ -0,0 +1,276 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: [jpaquin] The text chat widget ("say all" or "say team")
//
//=============================================================================//
#include "cbase.h"
#include "basepanel.h"
#include "scaleformui/scaleformui.h"
#include "iclientmode.h"
#include "clientmode_csnormal.h"
#include "sfhudflashinterface.h"
#include "vgui/ILocalize.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "sfhud_chat.h"
#include "sfhudfreezepanel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudChat );
SFUI_BEGIN_GAME_API_DEF
SFUI_DECL_METHOD( OnCancel ),
SFUI_DECL_METHOD( OnOK ),
SFUI_END_GAME_API_DEF( SFHudChat, Chat );
// Max number of characters in chat history
#define HISTORY_LENGTH_MAX 10 * 1024
// Number of character to delete if chat buffer is full
#define HISTORY_LENGTH_PURGE 1 * 1024
extern ConVar cl_draw_only_deathnotices;
SFHudChat::SFHudChat( const char *value ) : SFHudFlashInterface( value ),
m_bVisible( false ),
m_iMode( MM_NONE )
{
m_pHistoryString = new wchar_t[ HISTORY_LENGTH_MAX ];
SetHiddenBits( /* HIDEHUD_MISCSTATUS */ 0 );
}
SFHudChat::~SFHudChat()
{
if ( m_pHistoryString )
{
delete [] m_pHistoryString;
}
}
void SFHudChat::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
m_fLastShowTime = 0.0f;
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudChat, this, Chat );
}
}
void SFHudChat::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
m_iMode = MM_NONE;
RemoveFlashElement();
}
}
void SFHudChat::SetActive( bool bActive )
{
ShowPanel( bActive, false );
CHudElement::SetActive( bActive );
}
// exposed here as non-constant so CEG can populate the value at DLL init time
static DWORD CEG_ALLOW_TEXTCHAT = 0x01B3; // will override
CEG_NOINLINE DWORD InitHudAllowTextChatFlag( void )
{
CEG_GCV_PRE();
CEG_ALLOW_TEXTCHAT = CEG_GET_CONSTANT_VALUE( HudAllowTextChatFlag );
CEG_GCV_POST();
return CEG_ALLOW_TEXTCHAT;
}
bool SFHudChat::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() || (CSGameRules() && CSGameRules()->IsPlayingTraining()) )
return false;
const float kCloseAnimTime = 0.6f;
if ( m_bVisible )
{
m_fLastShowTime = gpGlobals->curtime;
}
else if ( gpGlobals->curtime < ( m_fLastShowTime + kCloseAnimTime ) )
{
// Prevent the panel being raised again while it is already being lowered
return false;
}
// disallow text chat when CEG fails
if ( CEG_ALLOW_TEXTCHAT & ~ALLOW_TEXTCHAT_FLAG )
return false;
bool result = cl_drawhud.GetBool();
return result && ( m_iMode != MM_NONE ) && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
}
void SFHudChat::OnOK( SCALEFORM_CALLBACK_ARGS_DECL )
{
m_iMode = MM_NONE;
}
void SFHudChat::OnCancel( SCALEFORM_CALLBACK_ARGS_DECL )
{
m_iMode = MM_NONE;
}
// these overload the ScaleformFlashInterfaceMixin class
void SFHudChat::FlashReady( void )
{
ShowPanel( m_bVisible, true );
memset( m_pHistoryString, 0, HISTORY_LENGTH_MAX * sizeof( wchar_t ) );
}
void SFHudChat::StartMessageMode( int mode )
{
if ( !ChatRaised() && FlashAPIIsValid() )
{
if ( !GetHud().HudDisabled() )
{
m_iMode = mode;
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, mode );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "SetMode", args, 1 );
}
}
}
}
bool SFHudChat::ChatRaised( void )
{
return m_iMode != MM_NONE;
}
void SFHudChat::ShowPanel( bool bShow, bool force )
{
if ( ( bShow != m_bVisible ) || force )
{
m_bVisible = bShow;
if ( m_FlashAPI )
{
if ( m_bVisible )
{
g_pScaleformUI->SetIMEFocus( SF_SS_SLOT( 0 ) );
g_pScaleformUI->SetIMEEnabled( true );
ListenForGameEvent( "cs_handle_ime_event" );
UpdateHistory();
WITH_SLOT_LOCKED
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowPanel", NULL, 0 );
}
else
{
g_pScaleformUI->SetIMEEnabled( false );
StopListeningForAllEvents();
WITH_SLOT_LOCKED
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "HidePanel", NULL, 0 );
}
}
}
}
void SFHudChat::AddStringToHistory( const wchar_t *string )
{
const int nMaxLengthInBytes = HISTORY_LENGTH_MAX * sizeof( wchar_t );
int stringLen = V_wcslen( string );
int historyLen = V_wcslen( m_pHistoryString );
if ( ( historyLen + stringLen + 2 ) > HISTORY_LENGTH_MAX )
{
// m_pHistoryStrig buffer is full. Delete lines at the start of the buffer
if ( historyLen > HISTORY_LENGTH_PURGE )
{
const wchar_t *nextreturn = wcsstr( &m_pHistoryString[HISTORY_LENGTH_PURGE], L"\n" );
if ( nextreturn != NULL )
{
memmove( m_pHistoryString, nextreturn, ( V_wcslen( nextreturn ) + 1 ) * sizeof( wchar_t ) );
}
else
{
memset( m_pHistoryString, 0, nMaxLengthInBytes );
}
}
else
{
memset( m_pHistoryString, 0, nMaxLengthInBytes );
}
}
// Add new line
V_wcsncat( m_pHistoryString, string, nMaxLengthInBytes, COPY_ALL_CHARACTERS );
V_wcsncat( m_pHistoryString, L"\n", nMaxLengthInBytes, COPY_ALL_CHARACTERS );
if ( m_bVisible )
{
// Only update actionscript side if the chat panel is visible
UpdateHistory();
}
}
void SFHudChat::ClearHistory()
{
memset( m_pHistoryString, 0, HISTORY_LENGTH_MAX * sizeof( wchar_t ) );
UpdateHistory();
}
// Update actionscript side
void SFHudChat::UpdateHistory()
{
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_SetMember( m_FlashAPI, "historyString", m_pHistoryString );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "UpdateHistory", NULL, 0 );
}
}
void SFHudChat::FireGameEvent( IGameEvent *event )
{
const char *type = event->GetName();
if ( !V_strcmp( type, "cs_handle_ime_event" ) )
{
type = event->GetString( "eventtype" );
const wchar_t* data = event->GetWString( "eventdata" );
if ( !V_strcmp( type, "addchars" ) )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, data );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "AddIMEChar", args, 1 );
}
}
else if ( !V_strcmp( type, "setcomposition" ) )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, data );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "SetIMECompositionString", args, 1 );
}
}
else if ( !V_strcmp( type, "cancelcomposition" ) )
{
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "CancelIMEComposition", NULL, 0 );
}
}
}
}

View File

@@ -0,0 +1,62 @@
#ifndef SFHUDCHAT_H
#define SFHUDCHAT_H
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include "weapon_csbase.h"
#include "takedamageinfo.h"
#include "weapon_csbase.h"
#include "ammodef.h"
#include "iclientmode.h"
class SFHudChat : public SFHudFlashInterface
{
public:
explicit SFHudChat( const char *value );
virtual ~SFHudChat();
//void ProcessInput( void );
void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
void StartMessageMode( int mode );
void OnOK( SCALEFORM_CALLBACK_ARGS_DECL );
void OnCancel( SCALEFORM_CALLBACK_ARGS_DECL );
bool ChatRaised( void );
void AddStringToHistory( const wchar_t *string );
void ClearHistory();
// overloads for the CGameEventListener class
virtual void FireGameEvent( IGameEvent *event );
protected:
void ShowPanel( bool bShow, bool force );
void UpdateHistory( void );
protected:
bool m_bVisible;
int m_iMode;
float m_fLastShowTime;
wchar_t* m_pHistoryString;
};
#endif

View File

@@ -0,0 +1,729 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#if defined( INCLUDE_SCALEFORM )
#include "scaleformui/scaleformui.h"
#include "sfhud_deathnotice.h"
#include "c_cs_playerresource.h"
#include "c_cs_player.h"
#include "utlvector.h"
#include "vgui/ILocalize.h"
#include "vstdlib/vstrtools.h"
#include "sfhudfreezepanel.h"
#include "strtools.h"
#include "c_cs_team.h"
#include <engine/IEngineSound.h>
#include "hltvreplaysystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudDeathNoticeAndBotStatus );
//
SFUI_BEGIN_GAME_API_DEF
SFUI_DECL_METHOD( SetConfig ),
SFUI_END_GAME_API_DEF( SFHudDeathNoticeAndBotStatus, DeathNotice );
static const float NOTICE_UPDATE_INTERVAL = 0.05f;
static const float EXTRA_NOTICE_PADDING = 0.0f;
extern ConVar mp_display_kill_assists;
extern ConVar cl_show_clan_in_death_notice;
SFHudDeathNoticeAndBotStatus::SFHudDeathNoticeAndBotStatus( const char *value ) : SFHudFlashInterface( value ),
m_nNotificationDisplayMax( 0 ),
m_fNotificationLifetime( 0.0f ),
m_fNotificationFadeLength( 0.0f ),
m_fNotificationScrollLength( 0.0f ),
m_fLocalPlayerLifetimeMod( 0.f ),
m_bVisible( false )
{
m_wCTColor[0] = 0x0;
m_wTColor[0] = 0x0;
m_vecNoticeText.EnsureCapacity( engine->GetMaxClients() );
SetHiddenBits( HIDEHUD_MISCSTATUS );
m_vecNoticeText.EnsureCapacity( 16 );
m_vecPendingNoticeText.EnsureCapacity( 16 );
m_vecNoticeHandleCache.EnsureCapacity( 16 );
}
SFHudDeathNoticeAndBotStatus::~SFHudDeathNoticeAndBotStatus()
{
}
void SFHudDeathNoticeAndBotStatus::FlashReady( void )
{
if ( m_FlashAPI && m_pScaleformUI )
{
ListenForGameEvent( "player_death" );
ShowPanel( false );
// Populate cache
WITH_SLOT_LOCKED
{
for ( int i = 0; i < 16; ++i )
{
SFVALUE result = m_pScaleformUI->Value_Invoke( m_FlashAPI, "AddPanel", NULL, 0 );
IScaleformUI::_ValueType resultType = m_pScaleformUI->Value_GetType( result );
if ( resultType == IScaleformUI::VT_DisplayObject )
{
m_vecNoticeHandleCache.AddToTail( result );
}
else
{
SafeReleaseSFVALUE( result );
Assert( false && "AddPanel failed. Probably referencing a bad name." );
}
}
}
}
}
bool SFHudDeathNoticeAndBotStatus::PreUnloadFlash( void )
{
// cleanup
StopListeningForAllEvents();
for ( int nPos = 0; nPos < m_vecNoticeText.Count(); nPos++ )
{
SafeReleaseSFVALUE( m_vecNoticeText[nPos].m_pPanel );
}
for ( int nPos = 0; nPos < m_vecPendingNoticeText.Count(); nPos++ )
{
SafeReleaseSFVALUE( m_vecPendingNoticeText[nPos].m_pPanel );
}
for ( int nPos = 0; nPos < m_vecNoticeHandleCache.Count(); nPos++ )
{
SafeReleaseSFVALUE( m_vecNoticeHandleCache[nPos] );
}
m_vecNoticeText.Purge();
m_vecPendingNoticeText.Purge();
m_vecNoticeHandleCache.Purge();
return true;
}
void SFHudDeathNoticeAndBotStatus::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudDeathNoticeAndBotStatus, this, DeathNotice );
}
}
void SFHudDeathNoticeAndBotStatus::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
void SFHudDeathNoticeAndBotStatus::ShowPanel( const bool bShow )
{
if ( m_FlashAPI )
{
if ( bShow )
{
Show();
}
else
{
Hide();
}
}
}
ConVar cl_drawhud_force_deathnotices( "cl_drawhud_force_deathnotices", "0", FCVAR_RELEASE, "0: default; 1: draw deathnotices even if hud disabled; -1: force no deathnotices" );
bool SFHudDeathNoticeAndBotStatus::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() )
return false;
return ( cl_drawhud_force_deathnotices.GetInt() >= 0 ) && (
( cl_drawhud_force_deathnotices.GetInt() > 0 ) ||
cl_drawhud.GetBool()
) && CHudElement::ShouldDraw();
}
void SFHudDeathNoticeAndBotStatus::SetActive( bool bActive )
{
if ( FlashAPIIsValid() )
{
if ( bActive != m_bVisible )
{
ShowPanel( bActive );
}
}
if ( bActive == false && m_bActive == true )
{
// We want to continue to run ProcessInput while the HUD element is hidden
// so that the notifications continue advancing down the screen
return;
}
CHudElement::SetActive( bActive );
}
void SFHudDeathNoticeAndBotStatus::FireGameEvent( IGameEvent *event )
{
if ( FlashAPIIsValid() )
{
const char *type = event->GetName();
if ( !V_strcmp( type, "player_death" ) )
{
if ( !g_HltvReplaySystem.GetHltvReplayDelay() || event->GetBool( "realtime_passthrough" ) )
OnPlayerDeath( event );
}
}
}
void SFHudDeathNoticeAndBotStatus::OnPlayerDeath( IGameEvent * event )
{
C_CS_PlayerResource *cs_PR = dynamic_cast<C_CS_PlayerResource *>( g_PR );
if ( !cs_PR )
{
Assert( false );
return;
}
int nAttacker = engine->GetPlayerForUserID( event->GetInt( "attacker" ) );
int nVictim = engine->GetPlayerForUserID( event->GetInt( "userid" ) );
int nAssister = mp_display_kill_assists.GetBool() ? engine->GetPlayerForUserID( event->GetInt( "assister" ) ) : 0;
const char * szWeapon = event->GetString( "weapon" );
if ( szWeapon == NULL || szWeapon[ 0 ] == 0 )
return;
bool bHeadshot = event->GetInt( "headshot" ) > 0;
bool bSuicide = ( nAttacker == 0 || nAttacker == nVictim );
bool bDominated = false;
bool bRevenge = false;
bool isVictim = GetLocalPlayerIndex() == nVictim;
bool bPenetrated = ( event->GetInt( "penetrated" ) > 0 );
bool isKiller = !isVictim && ( GetLocalPlayerIndex() == nAttacker || GetLocalPlayerIndex() == nAssister ); //Need to check isVictim because the player is both killer and victim in a suicide
wchar_t szAttackerName[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
wchar_t szVictimName[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
wchar_t szAssisterName[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
szAttackerName[ 0 ] = L'\0';
szVictimName[ 0 ] = L'\0';
szAssisterName[ 0 ] = L'\0';
EDecoratedPlayerNameFlag_t kDontShowClanName = k_EDecoratedPlayerNameFlag_DontShowClanName;
if ( cl_show_clan_in_death_notice.GetInt() > 0 )
kDontShowClanName = k_EDecoratedPlayerNameFlag_Simple;
if ( nAttacker > 0 )
{
cs_PR->GetDecoratedPlayerName( nAttacker, szAttackerName, sizeof( szAttackerName ), EDecoratedPlayerNameFlag_t( k_EDecoratedPlayerNameFlag_AddBotToNameIfControllingBot | kDontShowClanName ) );
}
if ( nVictim > 0 )
{
cs_PR->GetDecoratedPlayerName( nVictim, szVictimName, sizeof( szVictimName ), EDecoratedPlayerNameFlag_t( k_EDecoratedPlayerNameFlag_AddBotToNameIfControllingBot | kDontShowClanName ) );
}
if ( nAssister > 0 )
{
// if our attacker is the same as our assiter, it means a bot attacked the victim and a player took over that bot
if ( nAssister == nAttacker )
nAssister = 0;
else
{
cs_PR->GetDecoratedPlayerName( nAssister, szAssisterName, sizeof( szAssisterName ), EDecoratedPlayerNameFlag_t( k_EDecoratedPlayerNameFlag_AddBotToNameIfControllingBot | kDontShowClanName ) );
}
}
// Highlight "The Suspect" in death feed
if ( CDemoPlaybackParameters_t const *pParameters = engine->GetDemoPlaybackParameters() )
{
if ( pParameters->m_uiLockFirstPersonAccountID )
{
player_info_t pinfo;
engine->GetPlayerInfo( nAttacker, &pinfo );
if ( pParameters->m_uiLockFirstPersonAccountID == CSteamID( pinfo.xuid ).GetAccountID() )
{
isKiller = true;
}
}
}
if ( bSuicide )
{
STEAMWORKS_TESTSECRETALWAYS();
}
int nVictimTeam = nVictim > 0 ? cs_PR->GetTeam( nVictim ) : 0;
int nAtackerTeam = nAttacker > 0 ? cs_PR->GetTeam( nAttacker ) : 0;
int nAssisterTeam = nAssister > 0 ? cs_PR->GetTeam( nAssister ) : 0;
CCSPlayer* pCSPlayerKiller = ToCSPlayer( ClientEntityList().GetBaseEntity( nAttacker ) );
CCSPlayer* pCSPlayerAssister = ToCSPlayer( ClientEntityList().GetBaseEntity( nAssister ) );
if ( event->GetInt( "dominated" ) > 0 || ( pCSPlayerKiller != NULL && pCSPlayerKiller->IsPlayerDominated( nVictim ) ) )
{
bDominated = true;
}
else if ( event->GetInt( "revenge" ) > 0 )
{
bRevenge = true;
}
// Setup HTML
wchar_t szDomination[ 64 ];
GetIconHTML( L"domination", szDomination, ARRAYSIZE( szDomination ) );
wchar_t szHeadshot[ 64 ];
GetIconHTML( L"headshot", szHeadshot, ARRAYSIZE( szHeadshot ) );
wchar_t szPenetration[ 64 ];
GetIconHTML( L"penetrate", szPenetration, ARRAYSIZE( szPenetration ) );
wchar_t szRevenge[ 64 ];
GetIconHTML( L"revenge", szRevenge, ARRAYSIZE( szRevenge ) );
wchar_t szSuicide[ 64 ];
GetIconHTML( L"suicide", szSuicide, ARRAYSIZE( szSuicide ) );
C_CSPlayer *pLocalCSPlayer = C_CSPlayer::GetLocalCSPlayer();
if ( !pLocalCSPlayer )
return;
bool bAssisterIsTarget = pCSPlayerAssister && pCSPlayerAssister->IsAssassinationTarget();
bool bAttackerIsTarget = pCSPlayerKiller && pCSPlayerKiller->IsAssassinationTarget();
if ( nAssister > 0 )
{
if ( !bAttackerIsTarget )
TruncatePlayerName( szAttackerName, ARRAYSIZE( szAttackerName ), DEATH_NOTICE_ASSIST_NAME_TRUNCATE_AT );
if ( !bAssisterIsTarget )
TruncatePlayerName( szAssisterName, ARRAYSIZE( szAssisterName ), DEATH_NOTICE_ASSIST_SHORT_NAME_TRUNCATE_AT );
}
else
{
if ( !bAttackerIsTarget )
TruncatePlayerName( szAttackerName, ARRAYSIZE( szAttackerName ), DEATH_NOTICE_NAME_TRUNCATE_AT );
}
wchar_t szAttackerHTML[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
V_snwprintf( szAttackerHTML, ARRAYSIZE( szAttackerHTML ), DEATH_NOTICE_FONT_STRING, ( nAtackerTeam == TEAM_CT ) ? m_wCTColor : m_wTColor, ( !bSuicide ) ? szAttackerName : L"" );
wchar_t szAssisterHTML[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
V_snwprintf( szAssisterHTML, ARRAYSIZE( szAssisterHTML ), DEATH_NOTICE_FONT_STRING, ( nAssisterTeam == TEAM_CT ) ? m_wCTColor : m_wTColor, ( nAssister > 0 ) ? szAssisterName : L"" );
CCSPlayer* pCSPlayerVictim = ToCSPlayer( ClientEntityList().GetBaseEntity( nVictim ) );
bool bVictimIsTarget = pCSPlayerVictim && pCSPlayerVictim->IsAssassinationTarget();
if ( !bVictimIsTarget )
{
if ( nAssister > 0 )
TruncatePlayerName( szVictimName, ARRAYSIZE( szVictimName ), DEATH_NOTICE_ASSIST_NAME_TRUNCATE_AT );
else
TruncatePlayerName( szVictimName, ARRAYSIZE( szVictimName ), DEATH_NOTICE_NAME_TRUNCATE_AT );
}
wchar_t szVictimHTML[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
V_snwprintf( szVictimHTML, ARRAYSIZE( szVictimHTML ), DEATH_NOTICE_FONT_STRING, ( nVictimTeam == TEAM_CT ) ? m_wCTColor : m_wTColor, szVictimName );
wchar_t szAttAssComboHTML[ MAX_DECORATED_PLAYER_NAME_LENGTH ];
V_snwprintf( szAttAssComboHTML, ARRAYSIZE( szAttAssComboHTML ), ( nAssister > 0 ) ? DEATH_NOTICE_ATTACKER_PLUS_ASSISTER : DEATH_NOTICE_ATTACKER_NO_ASSIST, bSuicide ? szVictimHTML : szAttackerHTML, szAssisterHTML );
if ( Q_strcmp( "knifegg", szWeapon ) == 0 )
szWeapon = "knife";
else if ( Q_strcmp( "molotov_projectile_impact", szWeapon ) == 0 )
szWeapon = "inferno";
if ( Q_strcmp( "knife", szWeapon ) == 0 )
{
if ( pCSPlayerKiller && pCSPlayerKiller->GetTeamNumber() == TEAM_CT )
{
szWeapon = "knife_default_ct";
}
else
{
szWeapon = "knife_default_t";
}
}
wchar_t wszWeapon[ 64 ];
V_UTF8ToUnicode( szWeapon, wszWeapon, sizeof( wszWeapon ) );
wchar_t szWeaponHTML[ 64 ];
GetIconHTML( wszWeapon, szWeaponHTML, ARRAYSIZE( szWeaponHTML ) );
wchar_t szNotice[ COMPILETIME_MAX( DEATH_NOTICE_TEXT_MAX, 3 * MAX_DECORATED_PLAYER_NAME_LENGTH ) ];
V_snwprintf( szNotice,
ARRAYSIZE( szNotice ),
#if defined(_PS3) || defined(POSIX)
L"%ls%ls%ls%ls%ls%ls%ls%ls",
#else
L"%s%s%s%s%s%s%s%s",
#endif
bRevenge ? szRevenge : L"",
bDominated ? szDomination : L"",
szAttAssComboHTML,
bSuicide ? L"" : szWeaponHTML,
bPenetrated ? szPenetration : L"",
bHeadshot ? szHeadshot : L"",
bSuicide ? szSuicide : L"",
szVictimHTML );
PushNotice( szNotice, isVictim, isKiller );
}
void SFHudDeathNoticeAndBotStatus::ClearNotices( void )
{
ScaleformDisplayInfo dinfo;
FOR_EACH_VEC_BACK( m_vecNoticeText, i )
{
dinfo.Clear();
dinfo.SetVisibility( false );
m_pScaleformUI->Value_SetDisplayInfo( m_vecNoticeText[i].m_pPanel, &dinfo );
m_vecNoticeHandleCache.AddToTail( m_vecNoticeText[i].m_pPanel );
m_vecNoticeText.Remove( i );
}
FOR_EACH_VEC_BACK( m_vecPendingNoticeText, i )
{
m_vecNoticeHandleCache.AddToTail( m_vecPendingNoticeText[i].m_pPanel );
m_vecPendingNoticeText.Remove( i );
}
}
void SFHudDeathNoticeAndBotStatus::PushNotice( const char * szNoticeText, bool isVictim, bool isKiller )
{
NoticeText_t notice;
g_pVGuiLocalize->ConvertANSIToUnicode( szNoticeText, notice.m_szNotice, sizeof( notice.m_szNotice ) );
PushNotice( notice, isVictim, isKiller );
}
void SFHudDeathNoticeAndBotStatus::PushNotice( const wchar_t* wszNoticeText, bool isVictim, bool isKiller )
{
NoticeText_t notice;
V_wcsncpy( notice.m_szNotice, wszNoticeText, sizeof( notice.m_szNotice ) );
PushNotice( notice, isVictim, isKiller );
}
void SFHudDeathNoticeAndBotStatus::PushNotice( NoticeText_t& notice, bool isVictim, bool isKiller )
{
WITH_SLOT_LOCKED
{
SFVALUE result = NULL;
if ( m_vecNoticeHandleCache.Count() )
{
result = m_vecNoticeHandleCache.Tail();
m_vecNoticeHandleCache.FastRemove( m_vecNoticeHandleCache.Count()-1 );
}
else
{
result = m_pScaleformUI->Value_Invoke( m_FlashAPI, "AddPanel", NULL, 0 );
}
IScaleformUI::_ValueType resultType = m_pScaleformUI->Value_GetType( result );
if ( resultType == IScaleformUI::VT_DisplayObject )
{
notice.m_pPanel = result;
WITH_SFVALUEARRAY( args, 4 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, notice.m_pPanel);
m_pScaleformUI->ValueArray_SetElement( args, 1, &notice.m_szNotice[0]);
m_pScaleformUI->ValueArray_SetElement( args, 2, isVictim );
m_pScaleformUI->ValueArray_SetElement( args, 3, isKiller );
SFVALUE boxheight = m_pScaleformUI->Value_Invoke( m_FlashAPI, "SetPanelText", args, 4);
notice.m_fTextHeight = (float)m_pScaleformUI->Value_GetNumber( boxheight ) + EXTRA_NOTICE_PADDING;
SafeReleaseSFVALUE( boxheight );
}
notice.m_fLifetimeMod = isVictim || isKiller ? m_fLocalPlayerLifetimeMod : 1.0f;
notice.m_fSpawnTime = gpGlobals->curtime;
m_vecPendingNoticeText.AddToHead( notice );
// if we have too many pending notices, then remove the oldest one
// this happens when we are skipping in demos
int numPending = m_vecPendingNoticeText.Count();
if ( numPending > 15 )
{
// pull the oldest one
numPending -= 1;
NoticeText_t noticeToRemove = m_vecPendingNoticeText[numPending];
m_vecPendingNoticeText.Remove( numPending );
m_vecNoticeHandleCache.AddToTail( noticeToRemove.m_pPanel );
}
}
else
{
SafeReleaseSFVALUE( result );
Assert( false && "AddPanel failed. Probably referencing a bad name." );
}
}
}
void SFHudDeathNoticeAndBotStatus::SetConfig( SCALEFORM_CALLBACK_ARGS_DECL )
{
m_nNotificationDisplayMax = m_pScaleformUI->Params_GetArgAsNumber( obj, 0 );
m_fNotificationScrollLength = m_pScaleformUI->Params_GetArgAsNumber( obj, 1 );
m_fNotificationFadeLength = m_pScaleformUI->Params_GetArgAsNumber( obj, 2 );
m_fNotificationLifetime = m_pScaleformUI->Params_GetArgAsNumber( obj, 3 );
V_UTF8ToUnicode( pui->Params_GetArgAsString( obj, 4 ), m_wCTColor, sizeof( m_wCTColor ) );
V_UTF8ToUnicode( pui->Params_GetArgAsString( obj, 5 ), m_wTColor, sizeof( m_wTColor ) );
m_fLocalPlayerLifetimeMod = m_pScaleformUI->Params_GetArgAsNumber( obj, 6 );
}
void SFHudDeathNoticeAndBotStatus::ProcessInput( void )
{
// limit how often we update this stuff because it doesn't have to be too
// smooth
if ( gpGlobals->curtime > m_fNextUpdateTime )
{
m_fNextUpdateTime = gpGlobals->curtime + NOTICE_UPDATE_INTERVAL;
// go through the visible list, moving and setting positions as appropriate
// we're going to to move the first one. And we're going to make sure that each item after that
// is above the item below it. so if we go in order from head to tail, we should end up
// moving the whole list just by calculating where the first entry should be.
ScaleformDisplayInfo dinfo;
float previousY = 0.f;
float currentY = 0.f;
float alpha = 0.f;
bool bANoticeIsSpawning = false;
for ( int i = m_vecNoticeText.Count() - 1; i >= 0; i-- )
{
// keep track of these through the function and set them at the bottom.
// if the alpha is zero at the end of the function ( and it's not spawning )
// we'll mark this notice for removal
// doing it this way lets us add in the alpha from the lifetime being over
alpha =0.0f;
currentY = m_vecNoticeText[i].m_fY;
if ( m_vecNoticeText[i].m_iState == NS_SPAWNING )
{
// this notice is fading in at the bottom of the panel
// we want to scroll its position up the screen from 0, and bring the alpha up too
// we do both of these over m_fNotificationScrollLength seconds
float t = ( gpGlobals->curtime - m_vecNoticeText[i].m_fStateTime ) / m_fNotificationScrollLength;
if ( t >= 1 )
{
// done spawning, now move to normal mode ( text just sits, and scrolls up )
t = 1;
m_vecNoticeText[i].m_iState = NS_IDLE;
}
else
{
// keep track of whether a notice is currently spawning
// we can only add one notice at a time, so we need to know
// if this one is still fading in. We'll wait until this stays false
// to move a notice over from the pending list.
bANoticeIsSpawning = true;
if ( t < 0 )
t = 0;
}
// these will be set on the panel at the bottom of the loop
currentY = ( -m_vecNoticeText[i].m_fTextHeight * t ) + ( previousY + ( m_vecNoticeText[i].m_fTextHeight * 2 ) );
alpha = t;
}
else
{
// make this notice's position be just below the previous notice's
// position
currentY = previousY + m_vecNoticeText[i].m_fTextHeight;
alpha = 1.0f;
}
// now figure out if we need to fade this notice out because it's so old
float dt = gpGlobals->curtime - m_vecNoticeText[i].m_fSpawnTime;
if ( dt > ( m_fNotificationLifetime * m_vecNoticeText[i].m_fLifetimeMod ) )
{
float t = ( dt - ( m_fNotificationLifetime * m_vecNoticeText[i].m_fLifetimeMod ) ) / m_fNotificationFadeLength;
// this is just Max( Min( t,1 ) , 0 );
t = ( t < 0 ) ? 0 : ( ( t > 1 ) ? 1 : t );
alpha *= 1.0f - t;
}
// if our alpha is zero ( and we're not spawning ) it means this notice
// is now dead and can be removed
if ( m_vecNoticeText[i].m_iState != NS_SPAWNING && alpha <= 0.0f )
{
m_vecNoticeText[i].m_bRemove = true;
}
else
{
// set the actual position / alpha on the notice
dinfo.SetAlpha( alpha*100 );
dinfo.SetY( currentY );
m_pScaleformUI->Value_SetDisplayInfo( m_vecNoticeText[i].m_pPanel, &dinfo );
}
// remember this notice's position so that the next notice can be
// placed below it
previousY = currentY;
}
// now remove all the guys that are marked for removal ( they had 0 alpha )
for ( int i = m_vecNoticeText.Count() - 1; i >= 0; i-- )
{
if ( m_vecNoticeText[i].m_bRemove )
{
dinfo.Clear();
dinfo.SetVisibility( false );
m_pScaleformUI->Value_SetDisplayInfo( m_vecNoticeText[i].m_pPanel, &dinfo );
m_vecNoticeHandleCache.AddToTail( m_vecNoticeText[i].m_pPanel );
m_vecNoticeText.Remove( i );
}
}
// if we aren't currently bringing in a message, then
// see if there are any pending ones to add
if ( !bANoticeIsSpawning )
{
int numPending = m_vecPendingNoticeText.Count();
if ( numPending )
{
// pull the next pending notice and put it on the bottom of the notice stack
numPending -= 1;
NoticeText_t notice = m_vecPendingNoticeText[numPending];
m_vecPendingNoticeText.Remove( numPending );
// only add notices that are not too old (stop spew when coming back from pause menu or when skipping in demos)
if ( ( gpGlobals->curtime - notice.m_fSpawnTime ) < ( ( m_fNotificationLifetime * notice.m_fLifetimeMod ) + m_fNotificationFadeLength ) )
{
notice.m_iState = NS_SPAWNING;
notice.m_fSpawnTime = gpGlobals->curtime;
notice.m_fStateTime = gpGlobals->curtime;
dinfo.Clear();
dinfo.SetAlpha( 0.f );
dinfo.SetY( 0.f );
dinfo.SetVisibility( true );
m_pScaleformUI->Value_SetDisplayInfo( notice.m_pPanel, &dinfo );
m_vecNoticeText.AddToHead( notice );
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, notice.m_pPanel );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "UpdateWidth", data, 1 );
}
}
else
{
m_vecNoticeHandleCache.AddToTail( notice.m_pPanel );
}
}
}
}
else if ( m_fNextUpdateTime > gpGlobals->curtime + NOTICE_UPDATE_INTERVAL )
{
m_fNextUpdateTime = gpGlobals->curtime + NOTICE_UPDATE_INTERVAL;
}
}
void SFHudDeathNoticeAndBotStatus::Show( void )
{
if ( m_bVisible == false )
{
for ( int nPos = 0; nPos < m_vecNoticeText.Count(); nPos++ )
{
if ( m_vecNoticeText[nPos].m_pPanel )
{
ScaleformDisplayInfo dinfo;
m_pScaleformUI->Value_GetDisplayInfo( m_vecNoticeText[nPos].m_pPanel, &dinfo );
dinfo.SetVisibility( true );
m_pScaleformUI->Value_SetDisplayInfo( m_vecNoticeText[nPos].m_pPanel, &dinfo );
}
}
m_bVisible = true;
}
}
void SFHudDeathNoticeAndBotStatus::Hide( void )
{
if ( m_bVisible == true )
{
for ( int nPos = 0; nPos < m_vecNoticeText.Count(); nPos++ )
{
if ( m_vecNoticeText[nPos].m_pPanel )
{
ScaleformDisplayInfo dinfo;
m_pScaleformUI->Value_GetDisplayInfo( m_vecNoticeText[nPos].m_pPanel, &dinfo );
dinfo.SetVisibility( false );
m_pScaleformUI->Value_SetDisplayInfo( m_vecNoticeText[nPos].m_pPanel, &dinfo );
}
}
m_bVisible = false;
}
}
void SFHudDeathNoticeAndBotStatus::GetIconHTML( const wchar_t * szIcon, wchar_t * szBuffer, int nArraySize )
{
V_snwprintf( szBuffer, nArraySize, DEATH_NOTICE_IMG_STRING, szIcon );
}
#endif // INCLUDE_SCALEFORM

View File

@@ -0,0 +1,139 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SFHUD_DEATHNOTICE_H_
#define SFHUD_DEATHNOTICE_H_
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "strtools.h"
#define DEATH_NOTICE_TEXT_MAX 512 // max number of characters in a notice text
#if defined( _GAMECONSOLE )
#define DEATH_NOTICE_NAME_TRUNCATE_AT 16 // number of name character displayed before truncation
#define DEATH_NOTICE_ASSIST_NAME_TRUNCATE_AT 11 // number of name character displayed before truncation
#define DEATH_NOTICE_ASSIST_SHORT_NAME_TRUNCATE_AT 8 // number of name character displayed before truncation
#else
#define DEATH_NOTICE_NAME_TRUNCATE_AT 22 // number of name character displayed before truncation
#define DEATH_NOTICE_ASSIST_NAME_TRUNCATE_AT 18 // number of name character displayed before truncation
#define DEATH_NOTICE_ASSIST_SHORT_NAME_TRUNCATE_AT 12 // number of name character displayed before truncation
#endif
//c9c9c9
#if defined(_PS3) || defined(POSIX)
#define DEATH_NOTICE_IMG_STRING L" <img src='icon-%ls.png' height='16'/>"
#define DEATH_NOTICE_FONT_STRING L"<font color=\"%ls\">%ls</font>"
#define DEATH_NOTICE_ATTACKER_PLUS_ASSISTER L"%ls <font color='#bababa'>+</font> %ls"
#define DEATH_NOTICE_ATTACKER_NO_ASSIST L"%ls%ls"
#else
#define DEATH_NOTICE_IMG_STRING L" <img src='icon-%s.png' height='16'/>"
#define DEATH_NOTICE_FONT_STRING L"<font color=\"%s\">%s</font>"
#define DEATH_NOTICE_ATTACKER_PLUS_ASSISTER L"%s <font color='#bababa'>+</font> %s"
#define DEATH_NOTICE_ATTACKER_NO_ASSIST L"%s%s"
#endif
class SFHudDeathNoticeAndBotStatus : public SFHudFlashInterface
{
public:
explicit SFHudDeathNoticeAndBotStatus( const char *value );
virtual ~SFHudDeathNoticeAndBotStatus();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual bool ShouldDraw( void );
// CGameEventListener methods
virtual void FireGameEvent( IGameEvent *event );
void OnPlayerDeath( IGameEvent * event );
void ClearNotices( void );
// Scaleform callbacks
void SetConfig( SCALEFORM_CALLBACK_ARGS_DECL );
protected:
void ShowPanel( const bool bShow );
// Add the text notice to our internal queue and trigger add
// animation in scaleform.
void PushNotice( const char * szNoticeText, bool isVictim, bool isKiller );
void PushNotice( const wchar_t* wszNoticeText, bool isVictim, bool isKiller );
struct NoticeText_t;
void PushNotice( NoticeText_t& notice, bool isVictim, bool isKiller );
void GetIconHTML( const wchar_t * szIcon, wchar_t * szBuffer, int nArraySize );
// Show the death notices
void Show( void );
// Hide the death notices
void Hide( void );
protected:
enum
{
NS_PENDING,
NS_SPAWNING,
NS_IDLE,
NS_FORCED_OUT,
} NOTICE_STATE;
struct NoticeText_t
{
NoticeText_t() :
m_pPanel( NULL ),
m_bRemove( false ),
m_fTextHeight( 0.0f ),
m_fSpawnTime( 0.0f ),
m_fStateTime( 0.0f ),
m_fLifetimeMod( 1.0f ),
m_fY( 0.0f ),
m_iState( NS_PENDING )
{
V_memset( m_szNotice, 0, sizeof( m_szNotice ) );
};
wchar_t m_szNotice[DEATH_NOTICE_TEXT_MAX]; // Notice text
bool m_bRemove; // Removal flag
SFVALUE m_pPanel; // Handle to instantiated scaleform display object
float m_fTextHeight;
int m_iState;
float m_fSpawnTime;
float m_fStateTime;
float m_fLifetimeMod;
float m_fY;
// its proper state after a show or hide
};
int m_nNotificationDisplayMax; // Number of notices to display at one time
float m_fNotificationLifetime; // Notification display time before fading out
float m_fNotificationFadeLength;
float m_fNotificationScrollLength;
float m_fNextUpdateTime;
float m_fLocalPlayerLifetimeMod;
CUtlVector<NoticeText_t> m_vecNoticeText; // Oldest notices at the end
CUtlVector<NoticeText_t> m_vecPendingNoticeText; // Notices that are queued up to be displayed.
CUtlVector<SFVALUE> m_vecNoticeHandleCache; // Cache of notice panel handles to reuse
// (to avoid creating a new notice from scratch)
bool m_bVisible; // Element visibility flag
wchar_t m_wCTColor[8]; // Highlight color for CT
wchar_t m_wTColor[8]; // Highlight color for T
};
#endif /* SFHUD_DEATHNOTICE_H_ */

View File

@@ -0,0 +1,144 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD element to show we are having connectivity trouble
//
//=====================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhud_radio.h"
#include "hud_macros.h"
#include "view.h"
#include "sfhudfreezepanel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudRadio );
SFUI_BEGIN_GAME_API_DEF
SFUI_DECL_METHOD( InvokeCommand ),
SFUI_END_GAME_API_DEF( SFHudRadio, RadioPanel );
SFHudRadio::SFHudRadio( const char *value ) : SFHudFlashInterface( value ),
m_bVisible( false )
{
SetHiddenBits( HIDEHUD_MISCSTATUS );
}
SFHudRadio::~SFHudRadio()
{
}
void SFHudRadio::ShowPanel( bool bShow )
{
if ( bShow != m_bVisible )
{
m_bVisible = bShow;
if ( m_FlashAPI )
{
WITH_SLOT_LOCKED
{
if ( bShow )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
}
else
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
}
}
}
}
}
void SFHudRadio::ProcessInput( void )
{
}
void SFHudRadio::FlashReady( void )
{
ShowPanel( false );
}
bool SFHudRadio::PreUnloadFlash( void )
{
return true;
}
void SFHudRadio::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudRadio, this, RadioPanel );
}
}
void SFHudRadio::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
void SFHudRadio::Reset( void )
{
}
bool SFHudRadio::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() )
return false;
return cl_drawhud.GetBool() && CHudElement::ShouldDraw();
}
void SFHudRadio::SetActive( bool bActive )
{
if ( !bActive && m_bVisible )
{
ShowPanel( bActive );
}
CHudElement::SetActive( bActive );
}
void SFHudRadio::ShowRadioGroup( int nSetID )
{
if ( FlashAPIIsValid() )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, nSetID );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowRadioGroup", args, 1 );
}
m_bVisible = true;
}
}
void SFHudRadio::InvokeCommand( SCALEFORM_CALLBACK_ARGS_DECL )
{
if ( pui->Params_GetNumArgs( obj ) != 1 )
{
Warning("Bad command invoked by radio panel");
return;
}
if ( pui->Params_ArgIs( obj, 0, IScaleformUI::VT_String ) )
{
engine->ClientCmd( pui->Params_GetArgAsString( obj, 0 ) );
}
ShowPanel( false );
}
bool SFHudRadio::PanelRaised( void )
{
return m_bVisible;
}

View File

@@ -0,0 +1,45 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD element to show we are having connectivity trouble
//
//=====================================================================================//
#ifndef SFHUDRADIO_H_
#define SFHUDRADIO_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
class SFHudRadio : public SFHudFlashInterface
{
public:
explicit SFHudRadio( const char *value );
virtual ~SFHudRadio();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual bool ShouldDraw( void );
virtual void SetActive( bool bActive );
virtual void Reset( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
bool PanelRaised( void );
void ShowRadioGroup( int nSetID );
void InvokeCommand( SCALEFORM_CALLBACK_ARGS_DECL );
private:
void ShowPanel( bool bShow );
private:
bool m_bVisible;
};
#endif /* SFHUDRADIO_H_ */

View File

@@ -0,0 +1,221 @@
//========= Copyright © Valve Corporation, All rights reserved. ============//
//
// Purpose: Use mouse control to select among displayed options
//
//=====================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhud_rosettaselector.h"
#include "hud_macros.h"
#include "view.h"
#include "sfhudfreezepanel.h"
#include "engine/IEngineSound.h"
#include "clientmode_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static const char* g_pszSprayErrorSound = "ui/menu_back.wav";
bool Helper_CanUseSprays( void )
{
if ( g_bEngineIsHLTV )
return false;
C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
if ( !pLocalPlayer )
return false;
return pLocalPlayer->IsAlive() && ( pLocalPlayer->GetTeamNumber() == TEAM_TERRORIST || pLocalPlayer->GetTeamNumber() == TEAM_CT );
}
void ShowSprayMenu( const CCommand &args )
{
if ( Helper_CanUseSprays() )
{
SFHudRosettaSelector * pRosetta = GET_HUDELEMENT( SFHudRosettaSelector );
pRosetta->SetShowRosetta( true, "spray" );
}
}
ConCommand showSprayMenu( "+spray_menu", ShowSprayMenu );
void HideSprayMenu( const CCommand &args )
{
extern ConVar cl_playerspray_auto_apply;
SFHudRosettaSelector * pRosetta = GET_HUDELEMENT( SFHudRosettaSelector );
pRosetta->SetShowRosetta( false, "spray" );
}
ConCommand hideSprayMenu( "-spray_menu", HideSprayMenu);
DECLARE_HUDELEMENT( SFHudRosettaSelector );
SFUI_BEGIN_GAME_API_DEF
SFUI_DECL_METHOD( FlashHide ),
SFUI_DECL_METHOD( GetMouseEnableBindingName ),
SFUI_END_GAME_API_DEF( SFHudRosettaSelector, RosettaSelector );
SFHudRosettaSelector::SFHudRosettaSelector( const char *value )
: SFHudFlashInterface( value )
, m_bVisible( false )
{
SetHiddenBits( HIDEHUD_MISCSTATUS );
}
SFHudRosettaSelector::~SFHudRosettaSelector()
{
}
void SFHudRosettaSelector::SetShowRosetta( bool bShow, const char* szType )
{
if ( !FlashAPIIsValid() )
return;
uint32 unNumArgs = 1;
uint32 unArgCount = 0;
WITH_SFVALUEARRAY( args, unNumArgs )
{
m_pScaleformUI->ValueArray_SetElement( args, unArgCount++, szType );
WITH_SLOT_LOCKED
{
Assert( unNumArgs == unArgCount );
g_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, CFmtStr( "%sRosetta", bShow?"Show":"Hide" ).Access() , args, unArgCount );
}
}
Visible( bShow );
}
void SFHudRosettaSelector::ShowPanel( bool bShow )
{
if ( bShow != Visible() )
{
Visible(bShow);
if ( m_FlashAPI )
{
WITH_SLOT_LOCKED
{
if ( bShow )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
}
else
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
}
}
}
}
}
void SFHudRosettaSelector::ProcessInput( void )
{
}
void SFHudRosettaSelector::FlashReady( void )
{
ShowPanel( false );
}
bool SFHudRosettaSelector::PreUnloadFlash( void )
{
return true;
}
void SFHudRosettaSelector::FlashHide( SCALEFORM_CALLBACK_ARGS_DECL )
{
SetShowRosetta( false, "spray" );
}
void SFHudRosettaSelector::GetMouseEnableBindingName( SCALEFORM_CALLBACK_ARGS_DECL )
{
/* Removed for partner depot */
}
void SFHudRosettaSelector::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudRosettaSelector, this, RosettaSelector );
Visible( false );
enginesound->PrecacheSound( g_pszSprayErrorSound, true, true );
}
}
void SFHudRosettaSelector::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
Visible( false );
}
}
void SFHudRosettaSelector::Reset( void )
{
}
bool SFHudRosettaSelector::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() )
return false;
return cl_drawhud.GetBool() && CHudElement::ShouldDraw();
}
void SFHudRosettaSelector::SetActive( bool bActive )
{
if ( !bActive && Visible() )
{
ShowPanel( bActive );
}
CHudElement::SetActive( bActive );
}
void SFHudRosettaSelector::HACK_OnShowCursorBindingDown( const char* szKeyName )
{
if ( !Visible() )
return;
if ( m_FlashAPI && m_pScaleformUI )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, szKeyName );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "OnShowCursorBindingPressed", args, 1 );
}
}
}
extern void PlayerDecalDataSendActionSprayToServer( int nSlot );
extern bool Helper_CanShowPreviewDecal( CEconItemView **ppOutEconItemView = NULL, trace_t* pOutSprayTrace = NULL, Vector *pOutVecPlayerRight = NULL, uint32* pOutUnStickerKitID = NULL );
// Return nonzero to swallow this key
int SFHudRosettaSelector::KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding )
{
if ( down && pszCurrentBinding && ContainsBinding( pszCurrentBinding, "+attack", true ) )
{
if ( Helper_CanShowPreviewDecal() )
{
// If we're pretty sure this will result in a successful spray application, tell the server we want to spray
// the currently equipped item and close the menu
PlayerDecalDataSendActionSprayToServer( 0 );
SetShowRosetta( false, "spray" );
}
else // keep menu up and play error sound
{
enginesound->EmitAmbientSound( g_pszSprayErrorSound, 1.0f );
}
// always swallow the input if this menu is up
return 1;
}
return 0;
}

View File

@@ -0,0 +1,48 @@
//========= Copyright © Valve Corporation, All rights reserved. ============//
//
// Purpose: Use mouse control to select among displayed options
//
//=====================================================================================//
#pragma once
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
class SFHudRosettaSelector : public SFHudFlashInterface
{
public:
explicit SFHudRosettaSelector( const char *value );
virtual ~SFHudRosettaSelector();
// These overload the CHudElement class
virtual void ProcessInput( void ) OVERRIDE;
virtual void LevelInit( void ) OVERRIDE;
virtual void LevelShutdown( void ) OVERRIDE;
virtual bool ShouldDraw( void ) OVERRIDE;
virtual void SetActive( bool bActive ) OVERRIDE;
virtual void Reset( void ) OVERRIDE;
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void ) OVERRIDE;
virtual bool PreUnloadFlash( void ) OVERRIDE;
void FlashHide( SCALEFORM_CALLBACK_ARGS_DECL );
void GetMouseEnableBindingName( SCALEFORM_CALLBACK_ARGS_DECL );
void SetShowRosetta( bool bShow, const char* szType );
bool Visible() const { return m_bVisible; }
void HACK_OnShowCursorBindingDown( const char* szKeyName );
int KeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding );
private:
void ShowPanel( bool bShow );
void Visible( bool val ) { m_bVisible = val; }
private:
bool m_bVisible;
};
bool Helper_CanUseSprays();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,269 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SFHUD_TEAMCOUNTER_H_
#define SFHUD_TEAMCOUNTER_H_
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#if !defined( _X360 )
#include "xbox/xboxstubs.h"
#endif
#if defined(_PS3) || defined(POSIX)
#define TEAM_COUNT_IMG_STRING L"<img src='icon-%ls.png' height='16'/>"
#define TEAM_COUNT_FONT_STRING L"<font color=\"%ls\">%ls</font>"
#define TEAM_COUNT_FINAL_STRING L"%ls %ls"
#else
#define TEAM_COUNT_IMG_STRING L"<img src='icon-%s.png' height='16'/>"
#define TEAM_COUNT_FONT_STRING L"<font color=\"%s\">%s</font>"
#define TEAM_COUNT_FINAL_STRING L"%s %s"
#endif
struct MiniStatus
{
XUID nXUID;
int nEntIdx;
int nPlayerIdx;
int nGunGameLevel;
int nHealth;
int nArmor;
int nTeammateColor;
bool bIsCT;
bool bLocalPlayer;
bool bDead;
bool bDominated;
bool bDominating;
bool bSpeaking;
bool bPlayerBot; // indicates that the player took over this bot
bool bSpectated;
bool bTeamLeader;
float flLastRefresh;
int nGGProgressiveRank; // save this character's rank
int nPoints;
int nTeam;
MiniStatus() :
nXUID( INVALID_XUID ), nPlayerIdx(-1), nGunGameLevel(-1), bIsCT(false), bLocalPlayer(false), bDead(false), bDominated(false),
bDominating( false ), bTeamLeader( false ), bSpeaking( false ), bPlayerBot( false ), bSpectated( false ), nGGProgressiveRank( -1 ), nPoints( 0 ), nTeam( 0 ), nTeammateColor( -1 ), flLastRefresh( -1 )
{
}
MiniStatus( const MiniStatus &copy )
{
memcpy( this, &copy, sizeof(MiniStatus) );
}
MiniStatus& operator=( const MiniStatus &rhs )
{
memcpy( this, &rhs, sizeof(MiniStatus) );
return *this;
}
void Reset()
{
memset( this, 0, sizeof(MiniStatus) );
nXUID = INVALID_XUID;
nPlayerIdx = -1;
nEntIdx = 0;
nGGProgressiveRank = -1;
flLastRefresh = -1;
}
// Returns true if any of these fields has changed since last update
bool Update( XUID _Xuid, int _EntIdx, int _PlayerIdx, int _GunGameLevel, int _nHealth, int _nArmor, bool _IsCT, bool _LocalPlayer, bool _Dead, bool _Dominated, bool _Dominating, bool _bTeamLeader, bool _Speaking, bool _PlayerBot, bool _Spectated, int _Points, int _Team, int _TeammateColor, float _CurtimeRefresh )
{
bool bDiff = ( _Xuid != nXUID ) ||
( _EntIdx != nEntIdx ) ||
( _PlayerIdx != nPlayerIdx ) ||
( _GunGameLevel != nGunGameLevel ) ||
( _nHealth != nHealth ) ||
( _nArmor != nArmor ) ||
( _GunGameLevel != nGunGameLevel ) ||
( _IsCT ^ bIsCT ) ||
( _LocalPlayer ^ bLocalPlayer ) ||
( _Dead ^ bDead ) ||
( _Dominated ^ bDominated ) ||
( _Dominating ^ bDominating ) ||
( _bTeamLeader ^ bTeamLeader ) ||
( _Speaking ^ bSpeaking ) ||
( _PlayerBot ^ bPlayerBot ) ||
( _Spectated ^ bSpectated ) ||
( _Points != nPoints ) ||
( _Team != nTeam ) ||
( _TeammateColor != nTeammateColor ) ||
( _CurtimeRefresh > flLastRefresh + 3.0f );
nXUID = _Xuid;
nEntIdx = _EntIdx;
nPlayerIdx = _PlayerIdx;
nGunGameLevel = _GunGameLevel;
nHealth = _nHealth;
nArmor = _nArmor;
bIsCT = _IsCT;
bLocalPlayer = _LocalPlayer;
bDead = _Dead;
bDominated = _Dominated;
bDominating = _Dominating;
bTeamLeader = _bTeamLeader;
bSpeaking = _Speaking;
bPlayerBot = _PlayerBot;
bSpectated = _Spectated;
nPoints = _Points;
nTeam = _Team;
nTeammateColor = _TeammateColor;
if ( bDiff )
flLastRefresh = _CurtimeRefresh;
return bDiff;
}
};
class SFHudTeamCounter : public SFHudFlashInterface, public IShaderDeviceDependentObject
{
public:
explicit SFHudTeamCounter( const char *value );
virtual ~SFHudTeamCounter();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
// CGameEventListener methods
virtual void FireGameEvent( IGameEvent *event );
int FindNextObserverTargetIndex( bool reverse );
int GetSpectatorTargetFromSlot( int idx );
virtual void DeviceLost( void ) { }
virtual void DeviceReset( void *pDevice, void *pPresentParameters, void *pHWnd ) { m_bForceAvatarRefresh = true; }
virtual void ScreenSizeChanged( int width, int height ) { }
void OnFlashResize( SCALEFORM_CALLBACK_ARGS_DECL );
int GetPlayerEntIndexInSlot( int nIndex );
int GetPlayerSlotIndex( int playerEntIndex );
int GetPlayerSlotIndex( int playerEntIndex ) const; // version with no side effects
int GetPlayerSlotIndexForDisplay( int playerEntIndex ) const; // When displayed to users, slot is one higher and slot 10 is displayed as 0 for legacy reasons.
protected:
void LockSlot( bool wantItLocked, bool& currentlyLocked );
// update game clock
void UpdateTimer( void );
// update team scores and balance of power indicator
void UpdateScore( void );
// update current player's team selection graphic
void UpdateTeamSelection( void );
// update mini-scoreboard (team list + status bar)
void UpdateMiniScoreboard( void );
void ShowPanel( const bool bShow );
void GetIconHTML( const char * szIcon, wchar_t * szBuffer, int nBufferSize );
// resets the progressive leader HUD with the local player and weapon
// and resets m_nLeaderWeaponRank
void ResetLeader();
void InvokeAvatarSlotUpdate( SFVALUEARRAY &avatarData, const MiniStatus* msInfo, int slotNumber );
static int GGProgSortFunction( MiniStatus* const* entry1, MiniStatus* const* entry2 );
static int DMSortFunction( MiniStatus* const* entry1, MiniStatus* const* entry2 );
protected:
enum BALANCE_OF_POWER
{
BOP_EVEN = 0, // teams even
BOP_CT = TEAM_CT, // CT winning
BOP_T = TEAM_TERRORIST // T winning
};
enum VIEW_MODE
{
VIEW_MODE_NORMAL = 0,
VIEW_MODE_GUN_GAME_PROGRESSIVE, // Gun game progressive view mode
VIEW_MODE_GUN_GAME_BOMB, // Gun game bomb view mode
VIEW_MODE_NUM,
};
ISFTextObject * m_pTimeRedText;
ISFTextObject * m_pTimeGreenText;
ISFTextObject * m_pTime;
ISFTextObject * m_pCTScore;
ISFTextObject * m_pTScore;
ISFTextObject * m_pCTGunGameBombScore;
ISFTextObject * m_pTGunGameBombScore;
SFVALUE m_ProgressiveLeaderHandle;
bool m_bTimerAlertTriggered; // True if the timer's alert state has been triggered
bool m_bRoundStarted; // True if a round is currently in progress
bool m_bTimerHidden; // True if the timer is hidden from view
int m_nTScoreLastUpdate; // Terrorist score posted to Scaleform
int m_nCTScoreLastUpdate; // Counter-Terrorist score posted to Scaleform
int m_nTeamSelectionLastUpdate; // Team selection posted to Scaleform
int m_nLeaderWeaponRank; // The weapon rank of the current leader
VIEW_MODE m_Mode; // Tracks the current view mode
bool m_bRoundIsEnding; // True if the round ended event was received
bool m_bIsBombDefused;
bool m_bColorTabsInitialized;
enum PLAYER_TEAM_COUNT
{
MAX_TEAM_SIZE = 16
};
enum GG_PROG_PLAYER_COUNT
{
MAX_GGPROG_PLAYERS = 32
};
// track the team info we've already pushed to the mini-scoreboard
int m_nTerroristTeamCount;
int m_nCTTeamCount;
MiniStatus m_TerroristTeam[MAX_TEAM_SIZE];
MiniStatus m_CTTeam[MAX_TEAM_SIZE];
// for GG Prog only: Track the status of the players, regardless of team
int m_nPreviousGGProgressiveTotalPlayers;
MiniStatus m_GGProgressivePlayers[MAX_GGPROG_PLAYERS];
CUtlVector<MiniStatus*> m_ggSortedList;
CountdownTimer m_GGProgRankingTimer;
// Signals that avatar images should be reloaded (needed after a render device reset)
bool m_bForceAvatarRefresh;
protected:
// Sets the view mode, hiding or showing elements and changing
// update behavior
void SetViewMode( VIEW_MODE mode );
const MiniStatus* GetPlayerStatus( int index );
const MiniStatus* GetPlayerStatus( int index ) const; // version with no side effects
private:
float m_flPlayingTeamFadeoutTime;
float m_flLastSpecListUpdate;
};
#endif /* SFHUD_TEAMCOUNTER_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SFUNIQUEALERTS_H
#define SFUNIQUEALERTS_H
#pragma once
#include "hudelement.h"
#include "ehandle.h"
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include <vgui_controls/Panel.h>
#define MAX_PLAYER_GIFT_DROP_DISPLAY 4
// Experimental feature, not ready to enable. Turn this on to visualize quest progress
// messages in the Flash GUI
#define MISSIONPANEL_ENABLE_QUEST_PROGRESSION 1
//-----------------------------------------------------------------------------
// Purpose: Used to draw the history of weapon / item pickups and purchases by the player
//-----------------------------------------------------------------------------
class SFUniqueAlerts : public SFHudFlashInterface
{
public:
explicit SFUniqueAlerts( const char *value );
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
virtual void Reset( void );
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
// CGameEventListener methods
virtual void FireGameEvent( IGameEvent *event );
virtual void OnTimeJump() OVERRIDE;
// This should probably be a message listen, but I'm new and not sure the right layering. Will update on review.
void ShowQuestProgress(uint32 numPointsEarned, uint32 numPointsTotal, uint32 numPointsMax, const char* weaponName, const char* questDesc);
// Scaleform callbacks
void OnAlertPanelHideAnimEnd( SCALEFORM_CALLBACK_ARGS_DECL );
protected:
void ShowDMBonusWeapon( CEconItemView* pItem, int nPos, int nSecondsLeft );
// Helper functions for setting active/non-active
void Show( void );
void Hide( void );
void UpdateGGWeaponIconList( void );
void ShowWarmupAlertPanel( void );
void ShowHltvReplayAlertPanel( int nHltvReplayLeft );
// Display an alert in the 'alert text' area. If 'oneShot' is true, will automatically hide.
// One-shot messages always flash on set, otherwise will only flash if the panel is coming from
// hidden to showing.
void ShowAlertText( const wchar_t* szMessage, bool oneShot = false );
// Hide a non-one-shot alert text
void HideAlertText();
// Update for each sub-panel
// These can assume that all the following are non-null:
// CSGameRules()
// C_CSPlayer::GetLocalCSPlayer()
// m_pScaleformUI
void ProcessMissionPanelGuardian();
void ProcessDMBonusPanel();
void ProcessAlertBar();
#if defined ( ENABLE_GIFT_PANEL )
void ProcessGiftPanel();
#endif
#if MISSIONPANEL_ENABLE_QUEST_PROGRESSION
void ProcessMissionPanelQuest();
#endif
private:
enum AlertState {
ALERTSTATE_HIDDEN,
ALERTSTATE_SHOWING,
ALERTSTATE_HIDING, // Automatically will transition to ALERTSTATE_HIDDEN at some unknown point in the future
};
// Whether any of this UI is active
// (it could all be hidden due to hud settings)
bool m_bVisible;
// Alert line (e.g. "Round Start", "Warmup ends in xx:xx")
AlertState m_AlertState;
float m_flNextAlertTick;
// Demolition mode panel
bool m_bShowDemolitionProgressionPanel;
// Deathmatch extra points for using a certain weapon panel
bool m_bDMBonusIsActive;
float m_flNextDMBonusTick;
int m_nDMCurrentWeaponPoints;
int m_nDMCurrentWeaponBonusPoints;
int m_nDMBonusWeaponSlot;
// Mission/quest panel:
bool m_bMissionVisible;
// Mission panel for guardian co-op missions
bool m_guardianPanelInitialized;
float m_guardianPanelHideTick;
int m_nGuardianKills;
int m_nGuardianWeapon;
int m_nPlayerMoney;
bool m_bGuardianHasWeapon;
bool m_bGuardianHasWeaponEquipped;
// Mission panel for quest missions
// (Only used if MISSIONPANEL_ENABLE_QUEST_PROGRESSION is enabled)
bool m_bQuestMissionActive;
// Gift panel
#if defined ( ENABLE_GIFT_PANEL )
bool m_bIsGiftPanelActive;
int m_nGlobalGiftsGivenInPeriod;
int m_nGlobalNumGiftersInPeriod;
int m_nGlobalGiftingPeriodSeconds;
float m_flLastGiftPanelUpdate;
struct GiftTempList_t
{
int nDefindex;
AccountID_t uiAccountID;
int nNumGifts;
bool bIsLocalPlayer;
GiftTempList_t() :
nDefindex( 0 ), uiAccountID( 0 ), nNumGifts( 0 ), bIsLocalPlayer( false )
{
}
};
CUtlVector<GiftTempList_t> m_PlayerSpotlightTempList;
#endif // ENABLE_GIFT_PANEL
};
#endif // SFUNIQUEALERTS_H

View File

@@ -0,0 +1,388 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#if defined( INCLUDE_SCALEFORM )
#include "sfhudcallvotepanel.h"
#include "hud_macros.h"
#include <vgui/ILocalize.h>
#include "c_cs_player.h"
#include "c_cs_playerresource.h"
#include "basepanel.h"
#include "gametypes.h"
#include "cs_gamerules.h"
#include "c_user_message_register.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar cl_test_vote_scroll( "cl_test_vote_scroll", "0", FCVAR_CLIENTDLL | FCVAR_DEVELOPMENTONLY );
SFHudCallVotePanel* SFHudCallVotePanel::m_pInstance = NULL;
SFUI_BEGIN_GAME_API_DEF
SFUI_DECL_METHOD( PopulatePlayerTargets ),
SFUI_DECL_METHOD( PopulateMapTargets ),
SFUI_DECL_METHOD( PopulateBackupFilenames ),
SFUI_DECL_METHOD( GetNumberOfValidMapsInGroup ),
SFUI_DECL_METHOD( GetNumberOfValidKickTargets ),
SFUI_DECL_METHOD( IsQueuedMatchmaking ),
SFUI_DECL_METHOD( IsEndMatchMapVoteEnabled ),
SFUI_DECL_METHOD( IsPlayingClassicCompetitive ),
SFUI_END_GAME_API_DEF( SFHudCallVotePanel, CallVotePanel );
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
SFHudCallVotePanel::SFHudCallVotePanel() : ScaleformFlashInterface()
{
}
void SFHudCallVotePanel::LoadDialog( void )
{
if ( m_pInstance )
{
m_pInstance->Show();
}
else
{
m_pInstance = new SFHudCallVotePanel();
SFUI_REQUEST_ELEMENT( SF_FULL_SCREEN_SLOT, g_pScaleformUI, SFHudCallVotePanel, m_pInstance, CallVotePanel );
}
}
void SFHudCallVotePanel::UnloadDialog( void )
{
if ( m_pInstance )
{
m_pInstance->RemoveFlashElement();
m_pInstance = NULL;
}
}
void SFHudCallVotePanel::PostUnloadFlash( void )
{
BasePanel()->DismissPauseMenu();
m_pInstance = NULL;
delete this;
}
void SFHudCallVotePanel::LevelShutdown( void )
{
UnloadDialog();
}
void SFHudCallVotePanel::FlashReady( void )
{
if ( !m_FlashAPI )
{
return;
}
Show();
}
bool SFHudCallVotePanel::PreUnloadFlash( void )
{
return true;
}
void SFHudCallVotePanel::Show()
{
WITH_SLOT_LOCKED
{
if ( m_pScaleformUI )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
}
}
}
void SFHudCallVotePanel::Hide( void )
{
WITH_SLOT_LOCKED
{
if ( m_pScaleformUI )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
}
}
}
void SFHudCallVotePanel::PopulatePlayerTargets( SCALEFORM_CALLBACK_ARGS_DECL )
{
if ( g_PR )
{
int slot = 0;
SFVALUE result = CreateFlashObject();
SFVALUE names = CreateFlashArray( MAX_PLAYERS );
SFVALUE ids = CreateFlashArray( MAX_PLAYERS );
for ( int player = 1 ; player < MAX_PLAYERS; ++player )
{
if ( g_PR->IsConnected( player ) &&
( cl_test_vote_scroll.GetBool() || !g_PR->IsFakePlayer( player ) ) &&
GetLocalPlayerIndex() != player &&
g_PR->GetTeam( player ) == g_PR->GetTeam( GetLocalPlayerIndex() ) )
{
player_info_t playerInfo;
if ( engine->GetPlayerInfo( player, &playerInfo ) )
{
wchar_t szName[MAX_DECORATED_PLAYER_NAME_LENGTH];
wchar_t szSafeName[MAX_DECORATED_PLAYER_NAME_LENGTH];
g_pVGuiLocalize->ConvertANSIToUnicode( g_PR->GetPlayerName( player ), szName, sizeof(szName) );
g_pScaleformUI->MakeStringSafe( szName, szSafeName, sizeof( szSafeName ) );
TruncatePlayerName( szSafeName, ARRAYSIZE( szSafeName ), CALLVOTE_NAME_TRUNCATE_AT );
m_pScaleformUI->Value_SetArrayElement( names, slot, szSafeName );
m_pScaleformUI->Value_SetArrayElement( ids, slot, playerInfo.userID );
slot++;
}
}
}
m_pScaleformUI->Value_SetMember( result, "names", names );
m_pScaleformUI->Value_SetMember( result, "ids", ids );
m_pScaleformUI->Value_SetMember( result, "count", slot );
m_pScaleformUI->Params_SetResult( obj, result );
SafeReleaseSFVALUE( names );
SafeReleaseSFVALUE( ids );
SafeReleaseSFVALUE( result );
}
}
void SFHudCallVotePanel::GetNumberOfValidKickTargets( SCALEFORM_CALLBACK_ARGS_DECL )
{
if ( g_PR )
{
int slot = 0;
SFVALUE result = CreateFlashObject();
for ( int player = 1; player < MAX_PLAYERS; ++player )
{
if ( g_PR->IsConnected( player ) &&
( cl_test_vote_scroll.GetBool() || !g_PR->IsFakePlayer( player ) ) &&
GetLocalPlayerIndex() != player &&
g_PR->GetTeam( player ) == g_PR->GetTeam( GetLocalPlayerIndex() ) )
{
player_info_t playerInfo;
if ( engine->GetPlayerInfo( player, &playerInfo ) )
{
slot++;
}
}
}
m_pScaleformUI->Value_SetMember( result, "count", slot );
m_pScaleformUI->Params_SetResult( obj, result );
SafeReleaseSFVALUE( result );
}
}
void SFHudCallVotePanel::PopulateMapTargets( SCALEFORM_CALLBACK_ARGS_DECL )
{
bool bIncludeCurrentMap = false;
if ( pui->Params_GetNumArgs( obj ) >= 1 )
{
bIncludeCurrentMap = pui->Params_GetArgAsBool( obj, 0 );
}
SFVALUE result = CreateFlashObject();
SFVALUE names = CreateFlashArray( MAX_TARGET_COUNT );
SFVALUE ids = CreateFlashArray( MAX_TARGET_COUNT );
int numMaps = 0; //The number of maps in this cycle group
int actualNumMaps = 0; //The number of maps we display (in case we have any errors)
if ( g_pGameTypes )
{
const char* mapGroupName = engine->GetMapGroupName();
const CUtlStringList* mapsInGroup = g_pGameTypes->GetMapGroupMapList( mapGroupName );
if ( mapsInGroup )
{
numMaps = mapsInGroup->Count();
char szCurLevel[MAX_PATH];
V_strcpy_safe( szCurLevel, engine->GetLevelName() );
V_FixSlashes(szCurLevel, '/' ); // use consistent slashes.
V_StripExtension( szCurLevel, szCurLevel, sizeof( szCurLevel ) );
for( int i = 0 ; i < numMaps ; ++i )
{
const char* internalMapName = (*mapsInGroup)[i];
if ( !bIncludeCurrentMap && V_strstr( szCurLevel, V_GetFileName( internalMapName ) ) )
{
// don't populate the list with the same map that we're on
continue;
}
if ( internalMapName && V_strcmp( "undefined", internalMapName ) != 0 && V_strlen( internalMapName ) > 0 )
{
const wchar_t* friendlyMapName = CSGameRules()->GetFriendlyMapName(internalMapName);
if ( friendlyMapName )
{
m_pScaleformUI->Value_SetArrayElement( names, actualNumMaps, friendlyMapName );
}
else
{
m_pScaleformUI->Value_SetArrayElement( names, actualNumMaps, internalMapName );
}
m_pScaleformUI->Value_SetArrayElement( ids, actualNumMaps, internalMapName );
actualNumMaps++;
}
}
}
}
m_pScaleformUI->Value_SetMember( result, "friendlyNames", names );
m_pScaleformUI->Value_SetMember( result, "names", ids );
m_pScaleformUI->Value_SetMember( result, "count", actualNumMaps );
m_pScaleformUI->Params_SetResult( obj, result );
SafeReleaseSFVALUE( names );
SafeReleaseSFVALUE( ids );
SafeReleaseSFVALUE( result );
}
void SFHudCallVotePanel::PopulateBackupFilenames( SCALEFORM_CALLBACK_ARGS_DECL )
{
engine->ServerCmd( "send_round_backup_file_list" );
}
bool __MsgFunc_RoundBackupFilenames( const CCSUsrMsg_RoundBackupFilenames &msg )
{
if ( SFHudCallVotePanel::m_pInstance )
{
SFHudCallVotePanel::m_pInstance->PopulateBackupFilenames_Callback( msg );
}
return true;
}
USER_MESSAGE_REGISTER( RoundBackupFilenames );
void SFHudCallVotePanel::PopulateBackupFilenames_Callback( const CCSUsrMsg_RoundBackupFilenames &msg )
{
if ( !FlashAPIIsValid() )
return;
static CCSUsrMsg_RoundBackupFilenames files[ 10 ];
files[ clamp( msg.index(), 0, 9 ) ] = msg;
// don't do anything until we get the last file msg.
if ( msg.index() < ( msg.count() - 1 ) )
return;
char szCommaDelimitedFilenames[1024] = { 0 };
char szCommaDelimitedNicenames[1024] = { 0 };
for ( int i = 0; i < min ( msg.count(), 10 ); i++ )
{
if ( *szCommaDelimitedFilenames )
V_strcat_safe( szCommaDelimitedFilenames, "," );
V_strcat_safe( szCommaDelimitedFilenames, files[ i ].filename().c_str() );
if ( *szCommaDelimitedNicenames )
V_strcat_safe( szCommaDelimitedNicenames, "," );
V_strcat_safe( szCommaDelimitedNicenames, files[ i ].nicename().c_str() );
}
WITH_SFVALUEARRAY( data, 2 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, szCommaDelimitedFilenames );
m_pScaleformUI->ValueArray_SetElement( data, 1, szCommaDelimitedNicenames );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "PopulateBackupFilenames_Callback", data, 2 );
}
}
void SFHudCallVotePanel::GetNumberOfValidMapsInGroup( SCALEFORM_CALLBACK_ARGS_DECL )
{
bool bIncludeCurrentMap = false;
if ( pui->Params_GetNumArgs( obj ) >= 1 )
{
bIncludeCurrentMap = pui->Params_GetArgAsBool( obj, 0 );
}
SFVALUE result = CreateFlashObject();
int numMaps = 0; //The number of maps in this cycle group
int actualNumMaps = 0; //The number of maps we display (in case we have any errors)
static ConVarRef sv_vote_to_changelevel_before_match_point( "sv_vote_to_changelevel_before_match_point" );
if ( g_pGameTypes && CSGameRules()
&& !( sv_vote_to_changelevel_before_match_point.GetInt() > 0 && ( CSGameRules()->IsMatchPoint() || CSGameRules()->IsIntermission() ) ) )
{
const char* mapGroupName = engine->GetMapGroupName();
const CUtlStringList* mapsInGroup = g_pGameTypes->GetMapGroupMapList( mapGroupName );
if ( mapsInGroup )
{
numMaps = mapsInGroup->Count();
for( int i = 0 ; i < numMaps ; ++i )
{
const char* internalMapName = ( *mapsInGroup )[i];
if ( !bIncludeCurrentMap && 0 == V_strcmp( engine->GetLevelNameShort(), internalMapName ) )
{
// don't populate the list with the same map that we're on
continue;
}
else if ( internalMapName && V_strlen( internalMapName ) > 0 )
{
actualNumMaps++;
}
}
}
}
m_pScaleformUI->Value_SetMember( result, "count", actualNumMaps );
m_pScaleformUI->Params_SetResult( obj, result );
SafeReleaseSFVALUE( result );
}
void SFHudCallVotePanel::IsQueuedMatchmaking( SCALEFORM_CALLBACK_ARGS_DECL )
{
bool bQ = CSGameRules() && CSGameRules()->IsQueuedMatchmaking();
m_pScaleformUI->Params_SetResult( obj, bQ );
}
void SFHudCallVotePanel::IsEndMatchMapVoteEnabled( SCALEFORM_CALLBACK_ARGS_DECL )
{
bool bY = false;
C_CS_PlayerResource *cs_PR = dynamic_cast<C_CS_PlayerResource *>( g_PR );
if ( cs_PR && CSGameRules()->IsEndMatchVotingForNextMapEnabled() )
bY = true;
m_pScaleformUI->Params_SetResult( obj, bY );
}
void SFHudCallVotePanel::IsPlayingClassicCompetitive( SCALEFORM_CALLBACK_ARGS_DECL )
{
m_pScaleformUI->Params_SetResult( obj, ( CSGameRules() && CSGameRules()->IsPlayingAnyCompetitiveStrictRuleset() ) );
}
#endif // INCLUDE_SCALEFORM

View File

@@ -0,0 +1,50 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SFHUDCALLVOTEPANEL_H
#define SFHUDCALLVOTEPANEL_H
#ifdef _WIN32
#pragma once
#endif //_WIN32
#include "sfhudflashinterface.h"
#define MAX_TARGET_COUNT 10
#define CALLVOTE_NAME_TRUNCATE_AT 16 // number of name character displayed before truncation
class SFHudCallVotePanel: public ScaleformFlashInterface
{
public:
static SFHudCallVotePanel *m_pInstance;
SFHudCallVotePanel();
static void LoadDialog( void );
static void UnloadDialog( void );
virtual void LevelShutdown( void );
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual void PostUnloadFlash( void );
void PopulatePlayerTargets( SCALEFORM_CALLBACK_ARGS_DECL );
void PopulateMapTargets( SCALEFORM_CALLBACK_ARGS_DECL );
void PopulateBackupFilenames( SCALEFORM_CALLBACK_ARGS_DECL );
void PopulateBackupFilenames_Callback( const CCSUsrMsg_RoundBackupFilenames &msg );
void GetNumberOfValidMapsInGroup( SCALEFORM_CALLBACK_ARGS_DECL );
void GetNumberOfValidKickTargets( SCALEFORM_CALLBACK_ARGS_DECL );
void IsQueuedMatchmaking( SCALEFORM_CALLBACK_ARGS_DECL );
void IsEndMatchMapVoteEnabled( SCALEFORM_CALLBACK_ARGS_DECL );
void IsPlayingClassicCompetitive( SCALEFORM_CALLBACK_ARGS_DECL );
void Show( void );
void Hide( void );
};
#endif // SFHUDCALLVOTEPANEL_H

View File

@@ -0,0 +1,332 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD elements to indicate damage taken
//
//=====================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhuddamageindicator.h"
#include "vgui/ILocalize.h"
#include "text_message.h"
#include "hud_macros.h"
#include "view.h"
#include "sfhudfreezepanel.h"
#include "sfhudreticle.h"
#include "hltvcamera.h"
#include "inputsystem/iinputsystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudDamageIndicator );
DECLARE_HUD_MESSAGE( SFHudDamageIndicator, Damage );
SFUI_BEGIN_GAME_API_DEF
SFUI_END_GAME_API_DEF( SFHudDamageIndicator, DamageIndicatorModule );
extern ConVar cl_draw_only_deathnotices;
// [jason] Globals, extracted from the vgui version of the damage indicators. Comments are my own:
static float g_FadeScale = 2.f; // scale applied to delta-seconds to control the fade of the direction dmg indicators
static float g_StartFadeThreshold = 0.4f; // scale at which the directional dmg indicator begins to auto-fade out (controlled entirely in Flash); used to be the point where it became invisible in VGui
static float g_DetectDamageTakenInterval = 1.0f; // (in seconds) - if you haven't received new damage at least this recently, all direction indicators fade out at this point
static float g_CloseDamageDistance = 50.f; // (in world units) - if damage received is closer than this to player, all directions light up
static float g_DirectionDotTolerance = 0.3f; // incoming dmg direction dot product must be > this value in order for damage to be "from" this direction
SFHudDamageIndicator::SFHudDamageIndicator( const char *value ) : SFHudFlashInterface( value ),
m_flAttackFront(0.f),
m_flAttackRear(0.f),
m_flAttackLeft(0.f),
m_flAttackRight(0.f),
m_flFadeCompleteTime(0.f),
m_lastFrameTime(0.f)
{
SetHiddenBits( HIDEHUD_HEALTH );
HOOK_HUD_MESSAGE( SFHudDamageIndicator, Damage );
}
SFHudDamageIndicator::~SFHudDamageIndicator()
{
}
void SFHudDamageIndicator::IndicateDamage( DamageDirection dmgDir, float newPercentage )
{
if ( m_bActive && m_FlashAPI )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 2 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, dmgDir );
m_pScaleformUI->ValueArray_SetElement( data, 1, newPercentage );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showDamageDirection", data, 2 );
}
}
}
void SFHudDamageIndicator::HideAll( void )
{
if ( m_FlashAPI )
{
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideAll", NULL, 0 );
}
}
}
#define UPDATE_DIR_DAMAGE( dirValue, dirEnum ) \
if ( dirValue > 0.f ) \
{ \
dirValue = MAX( 0.f, dirValue - flFade ); \
if ( dirValue > g_StartFadeThreshold ) \
{ \
IndicateDamage( dirEnum, dirValue ); \
} \
else \
{ /* start auto-fade at this level */ \
dirValue = 0.f; \
IndicateDamage( dirEnum, -1.f ); \
} \
}
void SFHudDamageIndicator::ProcessInput( void )
{
if ( m_flFadeCompleteTime > gpGlobals->curtime )
{
// We have recent damage information, propagate it to all damage directions:
float flFade = ( gpGlobals->curtime - m_lastFrameTime ) * g_FadeScale;
UPDATE_DIR_DAMAGE( m_flAttackFront, SFDD_DamageUp );
UPDATE_DIR_DAMAGE( m_flAttackRear, SFDD_DamageDown );
UPDATE_DIR_DAMAGE( m_flAttackLeft, SFDD_DamageLeft );
UPDATE_DIR_DAMAGE( m_flAttackRight, SFDD_DamageRight );
}
else
{
// We haven't received recent damage info, so begin to fade out all dmg directions
if ( m_flAttackFront > 0.f ||
m_flAttackRear > 0.f ||
m_flAttackLeft > 0.f ||
m_flAttackRight > 0.f )
{
m_flAttackFront = 0.0f;
m_flAttackRear = 0.0f;
m_flAttackRight = 0.0f;
m_flAttackLeft = 0.0f;
// -1 causes all damage directions to fade down to zero from their current levels
IndicateDamage( SFDD_DamageTotal, -1.f );
}
}
m_lastFrameTime = gpGlobals->curtime;
}
void SFHudDamageIndicator::FlashReady( void )
{
// hide everything initially
HideAll();
}
bool SFHudDamageIndicator::PreUnloadFlash( void )
{
// $TODO: Anything to release?
return true;
}
void SFHudDamageIndicator::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudDamageIndicator, this, DamageIndicatorModule );
}
else
{
// When initially loaded, hide all indicators
HideAll();
}
}
void SFHudDamageIndicator::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
void SFHudDamageIndicator::Reset( void )
{
m_flAttackFront = 0.0f;
m_flAttackRear = 0.0f;
m_flAttackRight = 0.0f;
m_flAttackLeft = 0.0f;
m_flFadeCompleteTime = 0.0f;
HideAll();
}
bool SFHudDamageIndicator::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() )
return false;
return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
}
void SFHudDamageIndicator::SetActive( bool bActive )
{
if ( m_bActive && !bActive )
{
HideAll();
}
CHudElement::SetActive( bActive );
}
//-----------------------------------------------------------------------------
// Purpose: Message handler for Damage message
//-----------------------------------------------------------------------------
bool SFHudDamageIndicator::MsgFunc_Damage( const CCSUsrMsg_Damage &msg )
{
C_BasePlayer *pVictimPlayer = NULL;
if ( g_bEngineIsHLTV )
{
// Only show damage indicator for the player we are currently observing.
if ( HLTVCamera()->GetMode() != OBS_MODE_IN_EYE )
return true;
C_BaseEntity* pTarget = HLTVCamera()->GetPrimaryTarget();
if ( !pTarget || !pTarget->IsPlayer() || pTarget->entindex() != msg.victim_entindex() )
return true;
// This cast is safe because pTarget->IsPlayer() returned true above
pVictimPlayer = static_cast< C_BasePlayer* >( pTarget );
}
else
{
Assert( C_BasePlayer::GetLocalPlayer()->entindex() == msg.victim_entindex() );
pVictimPlayer = C_BasePlayer::GetLocalPlayer();
}
int damageTaken = msg.amount();
if ( damageTaken > 0 )
{
Vector vecFrom;
vecFrom.x = msg.inflictor_world_pos().x();
vecFrom.y = msg.inflictor_world_pos().y();
vecFrom.z = msg.inflictor_world_pos().z();
m_flFadeCompleteTime = gpGlobals->curtime + g_DetectDamageTakenInterval;
CalcDamageDirection( vecFrom, pVictimPlayer );
// If we are using a Steam Controller, do haptics on the Steam Controller
// to indicate getting hit.
if ( g_pInputSystem->IsSteamControllerActive() && steamapicontext->SteamController() )
{
static ConVarRef steam_controller_haptics( "steam_controller_haptics" );
if ( steam_controller_haptics.GetBool() )
{
ControllerHandle_t handles[MAX_STEAM_CONTROLLERS];
int nControllers = steamapicontext->SteamController()->GetConnectedControllers( handles );
for ( int i = 0; i < nControllers; ++i )
{
float flLeft = m_flAttackLeft + m_flAttackFront*0.5 + m_flAttackRear*0.5;
float flRight = m_flAttackRight + m_flAttackFront*0.5 + m_flAttackRear*0.5;
float flTotal = flLeft + flRight;
if ( flTotal > 0.0 )
{
flLeft /= flTotal;
flRight /= flTotal;
if ( flRight > 0 )
{
steamapicontext->SteamController()->TriggerHapticPulse( handles[ i ], k_ESteamControllerPad_Right, 2000*flRight );
}
if ( flLeft > 0 )
{
steamapicontext->SteamController()->TriggerHapticPulse( handles[ i ], k_ESteamControllerPad_Left, 2000*flLeft );
}
}
}
}
}
}
return true;
}
// [jason] This code is duplicated from cs_hud_damageindicator.cpp:
void SFHudDamageIndicator::CalcDamageDirection( const Vector &vecFrom, C_BasePlayer *pVictimPlayer )
{
// I assume this is done to detect damage from world (falling) and not display
// an indicator for this. Old code was zeroing all indicator values here which caused
// a bug if we were currently in mid-fade for a previous damage source.
if ( vecFrom == vec3_origin )
{
return;
}
if ( !pVictimPlayer )
{
return;
}
Vector vecDelta = ( vecFrom - pVictimPlayer->GetRenderOrigin() );
if ( vecDelta.Length() <= g_CloseDamageDistance )
{
m_flAttackFront = 1.0f;
m_flAttackRear = 1.0f;
m_flAttackRight = 1.0f;
m_flAttackLeft = 1.0f;
return;
}
VectorNormalize( vecDelta );
Vector forward;
Vector right;
AngleVectors( MainViewAngles( GET_ACTIVE_SPLITSCREEN_SLOT() ), &forward, &right, NULL );
float flFront = DotProduct( vecDelta, forward );
float flSide = DotProduct( vecDelta, right );
if ( flFront > 0 )
{
if ( flFront > g_DirectionDotTolerance )
m_flAttackFront = MAX( m_flAttackFront, flFront );
}
else
{
float f = fabs( flFront );
if ( f > g_DirectionDotTolerance )
m_flAttackRear = MAX( m_flAttackRear, f );
}
if ( flSide > 0 )
{
if ( flSide > g_DirectionDotTolerance )
m_flAttackRight = MAX( m_flAttackRight, flSide );
}
else
{
float f = fabs( flSide );
if ( f > g_DirectionDotTolerance )
m_flAttackLeft = MAX( m_flAttackLeft, f );
}
}

View File

@@ -0,0 +1,69 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD elements to indicate damage taken
//
//=====================================================================================//
#ifndef SFHUDDAMAGEINDICATOR_H_
#define SFHUDDAMAGEINDICATOR_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
class SFHudDamageIndicator : public SFHudFlashInterface
{
enum DamageDirection
{
SFDD_DamageUp = 0,
SFDD_DamageDown,
SFDD_DamageLeft,
SFDD_DamageRight,
SFDD_DamageTotal, // also means turn on damage from all directions
SFDD_DamageFirst = SFDD_DamageUp
};
public:
explicit SFHudDamageIndicator( const char *value );
virtual ~SFHudDamageIndicator();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual bool ShouldDraw( void );
virtual void SetActive( bool bActive );
virtual void Reset( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
// Handler for our message
bool MsgFunc_Damage( const CCSUsrMsg_Damage &msg );
CUserMessageBinder m_UMCMsgDamage;
protected:
void IndicateDamage( DamageDirection dmgDir, float newPercentage );
void HideAll( void );
private:
void CalcDamageDirection( const Vector &vecFrom, C_BasePlayer *pVictimPlayer );
protected:
float m_lastFrameTime;
// Parameters copied from cs_hud_damageindicator:
float m_flAttackFront;
float m_flAttackRear;
float m_flAttackLeft;
float m_flAttackRight;
float m_flFadeCompleteTime; //don't draw past this time
};
#endif /* SFHUDINFOPANEL_H_ */

View File

@@ -0,0 +1,26 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#if !defined( SFHUDFLASHINTERFACE_H_ )
#define SFHUDFLASHINTERFACE_H_
#include "hudelement.h"
#include "scaleformui/scaleformui.h"
class SFHudFlashInterface : public ScaleformFlashInterfaceMixin<CHudElement>
{
public:
explicit SFHudFlashInterface( const char* name ) : ScaleformFlashInterfaceMixin<CHudElement>()
{
InitCHudElementAfterConstruction( name );
}
virtual bool ShouldProcessInputBeforeFlashApiReady() { return false; }
};
extern ConVar cl_drawhud;
#endif // SHHUDFLASHINTERFACE_H_

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SFHUDFREEZEPANEL_H
#define SFHUDFREEZEPANEL_H
#pragma once
#include "hudelement.h"
#include "ehandle.h"
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include "weapon_csbase.h"
#include "takedamageinfo.h"
#include "weapon_csbase.h"
#include "ammodef.h"
#include <vgui_controls/Panel.h>
bool IsTakingAFreezecamScreenshot( void );
#define FREEZE_PANEL_NAME_TRUNCATE_AT_SHORT 10 // number of name character displayed before truncation
#define FREEZE_PANEL_NAME_TRUNCATE_AT_LONG 16 // number of name character displayed before truncation
class SFHudFreezePanel: public SFHudFlashInterface, public IShaderDeviceDependentObject
{
public:
explicit SFHudFreezePanel( const char *value );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual void FireGameEvent( IGameEvent * event );
virtual void ShowPanel( bool bShow );
virtual void ShowCancelPanel( bool bShow );
virtual bool IsVisible( void ) { return m_bIsVisible; }
virtual void OnTimeJump( void ) OVERRIDE;
void ResetDamageText( int iPlayerIndexKiller, int iPlayerIndexVictim );
void OnHltvReplayButtonStateChanged( void );
virtual void DeviceLost( void ) { }
virtual void DeviceReset( void *pDevice, void *pPresentParameters, void *pHWnd );
virtual void ScreenSizeChanged( int width, int height ) { }
bool IsHoldingAfterScreenShot( void ) { return m_bHoldingAfterScreenshot; }
void TakeFreezeShot( void );
enum DominationIconType
{
None,
Nemesis,
Revenge,
DominationIconMax
};
private:
void PopulateDominationInfo( DominationIconType iconType, const char* localizationToken1, const char* localizationToken2, wchar_t *szWeaponHTML );
void PopulateWeaponInfo( wchar_t *szWeaponName );
void PopulateNavigationText( void );
void SetIcon( DominationIconType iconType );
void ProcessInput( void );
void PositionPanel( void );
ISFTextObject* m_dominationIcons[DominationIconMax];
ISFTextObject* m_dominationText1;
ISFTextObject* m_dominationText2;
ISFTextObject* m_killerName;
ISFTextObject* m_navigationText;
ISFTextObject* m_weaponInfoText1;
ISFTextObject* m_weaponInfoText2;
ISFTextObject* m_ssDescText;
ISFTextObject* m_ssNameText;
SFVALUE m_freezePanel;
SFVALUE m_ssFreezePanel;
int m_PosX;
int m_PosY;
CHandle< CBaseEntity > m_FollowEntity;
int m_iKillerIndex;
const char *GetFilesafePlayerName( const char *pszOldName );
bool m_bHoldingAfterScreenshot;
bool m_bDominationIconVisible;
bool m_bIsVisible;
bool m_bIsCancelPanelVisible;
bool m_bFreezePanelStateRelevant; // flag showing if the information in the freeze panel is relevant and it makes sense to show, tracks show_freezepanel and hide_freezepanel events from the game; the panel may still be hidden sometimes (like before autoreplay) to avoid confusing the player (e.g. right before autoplay kicks in and there's not enough time to virually process it for a human being), even if the information in there is relevant
};
#endif // SFHUDFREEZEPANEL_H

View File

@@ -0,0 +1,367 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. =============================//
//
// Purpose: Purpose: Displays HUD elements about armor, current weapon, ammo, and TR weapon progress
//
//======================================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "iclientmode.h"
#include "view.h"
#include "vgui_controls/Controls.h"
#include "vgui/ISurface.h"
#include "ivrenderview.h"
#include "scaleformui/scaleformui.h"
#include "sfhudhealtharmorpanel.h"
#include "vgui/ILocalize.h"
#include "c_cs_hostage.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SAFECALL( handle, func ) \
if ( handle ) \
{ \
func \
}
DECLARE_HUDELEMENT( SFHudHealthArmorPanel );
SFUI_BEGIN_GAME_API_DEF
SFUI_END_GAME_API_DEF( SFHudHealthArmorPanel, HealthArmorModule ); // Asset named WeaponModule to maintain consistency with Flash file naming
// global tunables
const float g_LowHealthPercent = 0.20f;
const float g_HealthFlashSeconds = 1.0f;
extern ConVar cl_draw_only_deathnotices;
SFHudHealthArmorPanel::SFHudHealthArmorPanel( const char *value ) : SFHudFlashInterface( value ),
m_PanelHandle( NULL ),
m_HealthTextHandle( NULL ),
m_HealthTextHandleRed( NULL ),
m_ArmorTextHandle( NULL ),
m_HealthBarHandle( NULL ),
m_HealthRedBarHandle( NULL ),
m_HealthPanel( NULL ),
m_HealthPanelRed( NULL ),
m_HealthPanelRedSmall( NULL ),
m_PrevHealth( -1 ),
m_PrevArmor( -1 ),
m_PrevHasHelmet( false ),
m_PrevHasHeavyArmor( false )
{
// TODO Auto-generated constructor stub
SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD );
m_HealthFlashTimer.Invalidate();
}
SFHudHealthArmorPanel::~SFHudHealthArmorPanel()
{
// TODO Auto-generated destructor stub
}
void SFHudHealthArmorPanel::ShowPanel( bool value )
{
if ( !m_pScaleformUI )
return;
WITH_SLOT_LOCKED
{
if ( m_FlashAPI )
{
if ( value )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showNow", NULL, 0 );
}
else
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideNow", NULL, 0 );
}
}
// This forces the health and armor bars to reset
m_PrevHealth = -1;
m_PrevArmor = -1;
m_PrevHasHelmet = false;
m_PrevHasHeavyArmor = false;
}
}
void SFHudHealthArmorPanel::SetVisible( bool bVisible )
{
if ( FlashAPIIsValid() )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, bVisible );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setVisible", data, 1 );
}
}
}
void SFHudHealthArmorPanel::LockSlot( bool wantItLocked, bool& currentlyLocked )
{
if ( currentlyLocked != wantItLocked )
{
if ( wantItLocked )
{
LockScaleformSlot();
}
else
{
UnlockScaleformSlot();
}
currentlyLocked = wantItLocked;
}
}
void SFHudHealthArmorPanel::ProcessInput( void )
{
// Update stats
int realHealth = 0;
int realArmor = 0;
float healthPercent = 0.0f;
float armorPercent = 0.0f;
bool bHasHelmet = false;
bool bHasHeavyArmor = false;
// Collect all player, weapon and game state data first:
C_CSPlayer *pPlayer = GetHudPlayer();
if ( pPlayer )
{
realHealth = MAX( pPlayer->GetHealth(), 0 );
realArmor = MAX( pPlayer->ArmorValue(), 0 );
healthPercent = ( ( float )realHealth / ( float )pPlayer->GetMaxHealth() );
// HACK (for now)
float flMaxArmor = pPlayer->HasHeavyArmor() ? 200 : 100;
armorPercent = ( ( float )realArmor / ( float )flMaxArmor );
bHasHelmet = pPlayer->HasHelmet();
bHasHeavyArmor = pPlayer->HasHeavyArmor();
}
// Updating flash, slot locking begins...
bool bSlotIsLocked = false;
char cNewStr[ 128 ];
// Update health and which color health bar to draw
if ( m_PrevHealth != realHealth )
{
LockSlot( true, bSlotIsLocked );
V_snprintf( cNewStr, sizeof( cNewStr ), "%d", realHealth );
SAFECALL( m_HealthTextHandle, m_pScaleformUI->Value_SetText( m_HealthTextHandle, cNewStr ); );
SAFECALL( m_HealthTextHandleRed, m_pScaleformUI->Value_SetText( m_HealthTextHandleRed, cNewStr ); );
bool bTurnHealthRed = false;
// if our health has decreased...
if ( realHealth < m_PrevHealth )
{
bTurnHealthRed = true;
if ( healthPercent <= g_LowHealthPercent )
{
// Turn a steady red, turn off the color restoring timer
m_HealthFlashTimer.Invalidate();
}
else
{
// Flash red briefly, set a timer to restore color later
m_HealthFlashTimer.Start( g_HealthFlashSeconds );
}
}
SAFECALL( m_HealthPanel, m_pScaleformUI->Value_SetVisible( m_HealthPanel, !( healthPercent <= g_LowHealthPercent ) ); );
ConVarRef cl_hud_healthammo_style( "cl_hud_healthammo_style" );
SAFECALL( m_HealthPanelRed, m_pScaleformUI->Value_SetVisible( m_HealthPanelRed, cl_hud_healthammo_style.GetInt() == 0 ? ( healthPercent <= g_LowHealthPercent ) : false ); );
SAFECALL( m_HealthPanelRedSmall, m_pScaleformUI->Value_SetVisible( m_HealthPanelRedSmall, cl_hud_healthammo_style.GetInt( ) == 1 ? ( healthPercent <= g_LowHealthPercent ) : false ); );
SAFECALL( m_HealthBarHandle, m_pScaleformUI->Value_SetVisible( m_HealthBarHandle, !bTurnHealthRed ); );
SAFECALL( m_HealthRedBarHandle, m_pScaleformUI->Value_SetVisible( m_HealthRedBarHandle, bTurnHealthRed ); );
SAFECALL( m_HealthTextHandle, m_pScaleformUI->Value_SetVisible( m_HealthTextHandle, !bTurnHealthRed ); );
SAFECALL( m_HealthTextHandleRed, m_pScaleformUI->Value_SetVisible( m_HealthTextHandleRed, bTurnHealthRed ); );
}
// When timer elapses, restore the standard health bar color
if ( m_HealthFlashTimer.HasStarted() && m_HealthFlashTimer.IsElapsed() )
{
LockSlot( true, bSlotIsLocked );
m_HealthFlashTimer.Invalidate();
SAFECALL( m_HealthBarHandle, m_pScaleformUI->Value_SetVisible( m_HealthBarHandle, true ); );
SAFECALL( m_HealthRedBarHandle, m_pScaleformUI->Value_SetVisible( m_HealthRedBarHandle, false ); );
SAFECALL( m_HealthTextHandle, m_pScaleformUI->Value_SetVisible( m_HealthTextHandle, true ); );
SAFECALL( m_HealthTextHandleRed, m_pScaleformUI->Value_SetVisible( m_HealthTextHandleRed, false ); );
}
// Update armor display
// $TODO: update the icon to reflect the type of armor, per design?
if ( m_PrevArmor != realArmor )
{
LockSlot( true, bSlotIsLocked );
V_snprintf( cNewStr, sizeof( cNewStr ), "%d", realArmor);
SAFECALL( m_ArmorTextHandle, m_pScaleformUI->Value_SetText( m_ArmorTextHandle, cNewStr ); );
}
// Update the health/armor bar lengths
if ( ( m_PrevHealth != realHealth ) ||
( m_PrevArmor != realArmor ) ||
( m_PrevHasHelmet != bHasHelmet ) ||
( m_PrevHasHeavyArmor != bHasHeavyArmor ) )
{
if ( FlashAPIIsValid() )
{
LockSlot( true, bSlotIsLocked );
WITH_SFVALUEARRAY( data, 6 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, realHealth );
m_pScaleformUI->ValueArray_SetElement( data, 1, clamp( int(healthPercent*100), 1, 100 ) );
m_pScaleformUI->ValueArray_SetElement( data, 2, clamp( realArmor, 1, 100 ) );
m_pScaleformUI->ValueArray_SetElement( data, 3, clamp( int(armorPercent*100), 1, 100 ) );
m_pScaleformUI->ValueArray_SetElement( data, 4, bHasHelmet );
m_pScaleformUI->ValueArray_SetElement( data, 5, bHasHeavyArmor );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "updateValues", data, 6 );
}
}
}
m_PrevHealth = realHealth;
m_PrevArmor = realArmor;
m_PrevHasHelmet = bHasHelmet;
m_PrevHasHeavyArmor = bHasHeavyArmor;
LockSlot( false, bSlotIsLocked );
}
static void GetTextBoxForElement( IScaleformUI *pScaleformUI, SFVALUE root, const char *elementName, const char *textElementName, SFVALUE &sfv )
{
SFVALUE TempHandle = pScaleformUI->Value_GetMember( root, elementName );
if ( TempHandle )
{
sfv = pScaleformUI->Value_GetMember( TempHandle, textElementName );
pScaleformUI->ReleaseValue( TempHandle );
}
}
void SFHudHealthArmorPanel::FlashReady( void )
{
m_PanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanel" );
if ( m_PanelHandle )
{
SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_PanelHandle, "HealthArmorPanel" );
if ( AnimatedPanelHandle )
{
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "Armor", "TextBox", m_ArmorTextHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "Health", "TextBox", m_HealthTextHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "HealthRed", "TextBox", m_HealthTextHandleRed );
m_HealthPanel = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "HealthPanel" );
m_HealthPanelRed = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "HealthPanelRed" );
m_HealthPanelRedSmall = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "HealthPanelRed_small" );
SAFECALL( m_HealthPanelRed, m_pScaleformUI->Value_SetVisible( m_HealthPanelRed, false ); );
SAFECALL( m_HealthPanelRedSmall, m_pScaleformUI->Value_SetVisible( m_HealthPanelRedSmall, false ); );
SFVALUE HealthPanelHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "HealthBar" );
if ( HealthPanelHandle )
{
m_HealthBarHandle = m_pScaleformUI->Value_GetMember( HealthPanelHandle, "HealthBar" );
m_HealthRedBarHandle = m_pScaleformUI->Value_GetMember( HealthPanelHandle, "HealthBarRed" );
SafeReleaseSFVALUE( HealthPanelHandle );
}
SafeReleaseSFVALUE( AnimatedPanelHandle );
}
}
// hide everything initially
SetVisible( false );
}
bool SFHudHealthArmorPanel::PreUnloadFlash( void )
{
SafeReleaseSFVALUE( m_PanelHandle );
SafeReleaseSFVALUE( m_HealthTextHandle );
SafeReleaseSFVALUE( m_HealthTextHandleRed );
SafeReleaseSFVALUE( m_ArmorTextHandle );
SafeReleaseSFVALUE( m_HealthBarHandle );
SafeReleaseSFVALUE( m_HealthRedBarHandle );
SafeReleaseSFVALUE( m_HealthPanel );
SafeReleaseSFVALUE( m_HealthPanelRed );
SafeReleaseSFVALUE( m_HealthPanelRedSmall );
return true;
}
void SFHudHealthArmorPanel::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudHealthArmorPanel, this, HealthArmorModule );
}
else
{
// When initially loaded, hide this panel
SetVisible( false );
}
// Reset all transient data
m_PrevHealth = -1;
m_PrevArmor = -1;
m_PrevHasHelmet = false;
m_HealthFlashTimer.Invalidate();
}
void SFHudHealthArmorPanel::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
bool SFHudHealthArmorPanel::ShouldDraw( void )
{
return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
}
void SFHudHealthArmorPanel::SetActive( bool bActive )
{
if ( bActive != m_bActive )
{
ShowPanel( bActive );
}
CHudElement::SetActive( bActive );
}

View File

@@ -0,0 +1,62 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ==================//
//
// Purpose: Displays HUD elements about armor, current weapon, ammo, and TR weapon progress
//
//===========================================================================================//
#ifndef SFHUDHEALTHARMORPANEL_H_
#define SFHUDHEALTHARMORPANEL_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
class SFHudHealthArmorPanel : public SFHudFlashInterface
{
public:
explicit SFHudHealthArmorPanel( const char *value );
virtual ~SFHudHealthArmorPanel();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
virtual void Init( void ) { SetVisible( true ); }
virtual void Reset( void ) { SetVisible( true ); }
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
protected:
void ShowPanel( bool value );
void SetVisible( bool bVisible );
void LockSlot( bool wantItLocked, bool& currentlyLocked );
protected:
SFVALUE m_PanelHandle;
SFVALUE m_HealthPanel;
SFVALUE m_HealthPanelRed;
SFVALUE m_HealthPanelRedSmall;
SFVALUE m_HealthTextHandle;
SFVALUE m_HealthTextHandleRed;
SFVALUE m_ArmorTextHandle;
SFVALUE m_HealthBarHandle;
SFVALUE m_HealthRedBarHandle;
int m_PrevHealth;
int m_PrevArmor;
bool m_PrevHasHelmet;
bool m_PrevHasHeavyArmor;
CountdownTimer m_HealthFlashTimer;
};
#endif /* SFHUDHEALTHARMORPANEL_H_ */

View File

@@ -0,0 +1,873 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD elements for medals/achievements, and hint text
//
//=====================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "iclientmode.h"
#include "view.h"
#include "vgui_controls/Controls.h"
#include "vgui/ISurface.h"
#include "ivrenderview.h"
#include "scaleformui/scaleformui.h"
#include "sfhudinfopanel.h"
#include "vgui/ILocalize.h"
#include "text_message.h"
#include "hud_macros.h"
#include "achievementmgr.h"
#include "fmtstr.h"
#include "sfhudfreezepanel.h"
#include "bannedwords.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudInfoPanel );
DECLARE_HUD_MESSAGE( SFHudInfoPanel, HintText );
DECLARE_HUD_MESSAGE( SFHudInfoPanel, KeyHintText );
SFUI_BEGIN_GAME_API_DEF
SFUI_END_GAME_API_DEF( SFHudInfoPanel, HelpAchievementModule ); // Asset named HelpAchievementModule to maintain consistency with Flash file naming
// global tunables for this panel
static float g_HintDisplayTime = 6.f;
static float g_MedalDisplayTime = 5.f;
extern ConVar cl_draw_only_deathnotices;
SFHudInfoPanel::SFHudInfoPanel( const char *value ) : SFHudFlashInterface( value ),
m_HelpPanelHandle(NULL),
m_HelpBodyTextHandle(NULL),
m_MedalPanelHandle(NULL),
m_MedalTitleTextHandle(NULL),
m_MedalBodyTextHandle(NULL),
m_DefusePanelHandle(NULL),
m_DefuseTitleTextHandle(NULL),
m_DefuseBodyTextHandle(NULL),
m_DefuseIconKit( NULL ),
m_DefuseIconNoKit( NULL ),
m_DefuseTimerTextHandle(NULL),
m_PriorityMessagePanelHandle(NULL),
m_PriorityMessageTitleTextHandle(NULL),
m_PriorityMessageBodyTextHandle(NULL),
m_activeAchievement(CSInvalidAchievement),
m_PreviousDefusePercent(-1.0f),
m_bDeferRaiseHelpPanel(false),
m_bHintPanelHidden( false ),
m_bDeferRaisePriorityMessagePanel(false),
m_bIsVisible(false)
{
HOOK_HUD_MESSAGE( SFHudInfoPanel, HintText );
HOOK_HUD_MESSAGE( SFHudInfoPanel, KeyHintText );
SetHiddenBits( HIDEHUD_MISCSTATUS );
m_HintDisplayTimer.Invalidate();
m_AchievementDisplayTimer.Invalidate();
m_PriorityMsgDisplayTimer.Invalidate();
}
SFHudInfoPanel::~SFHudInfoPanel()
{
}
void SFHudInfoPanel::ShowPanel( HUDINFO_TYPE panelType, bool value )
{
if ( m_bActive && m_FlashAPI )
{
WITH_SLOT_LOCKED
{
ShowPanelNoLock( panelType, value );
}
}
}
// Caution! If you call this from code that isn't wrapped with Slot Locks, you will run into run-time multi-threading issues!
void SFHudInfoPanel::ShowPanelNoLock( HUDINFO_TYPE panelType, bool value )
{
if ( m_bActive && FlashAPIIsValid() )
{
WITH_SFVALUEARRAY( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, panelType );
if ( value )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", data, 1 );
m_bIsVisible = true;
}
else
{
if ( panelType == SFHUDINFO_PriorityMessage ||
panelType == SFHUDINFO_Help )
{
STEAMWORKS_TESTSECRET_AMORTIZE( 149 );
}
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", data, 1 );
m_bIsVisible = false;
}
}
}
else
{
// Set the flags so that panels will be raised once this HUD element is visible and loaded
if ( value )
{
if ( panelType == SFHUDINFO_Help )
{
m_bDeferRaiseHelpPanel = true;
}
else if ( panelType == SFHUDINFO_PriorityMessage )
{
m_bDeferRaisePriorityMessagePanel = true;
}
}
}
}
void SFHudInfoPanel::HideAll( void )
{
if ( m_FlashAPI )
{
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideAll", NULL, 0 );
}
m_bIsVisible = false;
// Reset the defuse percent so that we detect the defuse panel needs to be shown again when we un-hide this HUD element
m_PreviousDefusePercent = -1.0f;
}
}
void SFHudInfoPanel::LockSlot( bool wantItLocked, bool& currentlyLocked )
{
if ( currentlyLocked != wantItLocked )
{
if ( wantItLocked )
{
LockScaleformSlot();
}
else
{
UnlockScaleformSlot();
}
currentlyLocked = wantItLocked;
}
}
void SFHudInfoPanel::ProcessInput( void )
{
// Collect information about defuse progress
float DefusePercent = -1.0f;
int DefuseTimeRemaining = -1;
bool bDefuseCanceled = false;
C_CSPlayer *pPlayer = C_CSPlayer::GetLocalCSPlayer();
bool bSpectating = ( pPlayer && ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE || pPlayer->GetObserverMode() == OBS_MODE_CHASE ) );
if ( pPlayer && bSpectating )
{
C_BaseEntity *pTarget = pPlayer->GetObserverTarget();
if ( pTarget && pTarget->IsPlayer() )
{
pPlayer = ToCSPlayer( pTarget );
if ( pPlayer && !pPlayer->IsAlive() )
{
pPlayer = NULL;
}
}
else
{
pPlayer = NULL;
}
}
if ( pPlayer )
{
bDefuseCanceled = (pPlayer->m_iProgressBarDuration == 0);
if ( pPlayer->m_iProgressBarDuration > 0 )
{
// ProgressBarStartTime is now with respect to m_flSimulationTime rather than local time
DefusePercent = (pPlayer->m_flSimulationTime - pPlayer->m_flProgressBarStartTime) / (float)pPlayer->m_iProgressBarDuration;
DefusePercent = clamp( DefusePercent, 0.f, 1.f );
DefuseTimeRemaining = static_cast<int>( ceil( (float)pPlayer->m_iProgressBarDuration - (pPlayer->m_flSimulationTime - pPlayer->m_flProgressBarStartTime) ) );
}
}
else
{
// if the player goes away (drops from server, dies, etc) remember to clear any defuse panel for them
if ( m_PreviousDefusePercent >= 0.f )
bDefuseCanceled = true;
}
// Updating flash, slot locking begins
bool bSlotIsLocked = false;
if ( m_HintDisplayTimer.HasStarted() )
{
// Check if the current hint text should go away
if ( m_HintDisplayTimer.IsElapsed() )
{
LockSlot( true, bSlotIsLocked );
// clear the hint, which also clears our timer
SetHintText(NULL);
m_bHintPanelHidden = false;
}
else if ( m_bHintPanelHidden && m_PriorityMsgDisplayTimer.IsElapsed() )
{
// Hint message was defered while a priority message was shown. Bring it back.
LockSlot( true, bSlotIsLocked );
m_bHintPanelHidden = false;
ShowPanelNoLock( SFHUDINFO_Help, true );
}
else if ( m_bActive && m_bDeferRaiseHelpPanel )
{
// The help panel was triggered before the HUD was visible: raise it now
LockSlot( true, bSlotIsLocked );
ShowPanelNoLock( SFHUDINFO_Help, true );
}
}
if ( m_PriorityMsgDisplayTimer.HasStarted() )
{
// Check if the priority message text should go away
if ( m_PriorityMsgDisplayTimer.IsElapsed() )
{
LockSlot( true, bSlotIsLocked );
// clear the hint, which also clears our timer
SetPriorityText( static_cast<wchar_t*>(NULL) );
}
else if ( m_bActive && m_bDeferRaisePriorityMessagePanel )
{
// The priority message panel was triggered before the HUD was visible: raise it now
LockSlot( true, bSlotIsLocked );
ShowPanelNoLock( SFHUDINFO_PriorityMessage, true );
}
}
// Update the defuse UI
if ( DefusePercent >= 0.0f )
{
LockSlot( true, bSlotIsLocked );
// Update the timer text and progress bar
if ( DefuseTimeRemaining >= 0 && m_DefuseTimerTextHandle )
{
char cTimerStr[ 128 ];
int clampedTime = MAX( DefuseTimeRemaining, 0 );
Q_snprintf( cTimerStr, sizeof(cTimerStr), "%02d:%02d", ( clampedTime / 60 ), ( clampedTime % 60 ) );
m_pScaleformUI->Value_SetText( m_DefuseTimerTextHandle, cTimerStr );
}
if ( DefusePercent >= 0.f )
{
WITH_SFVALUEARRAY( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, DefusePercent);
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setDefuseProgress", data, 1 );
}
}
}
if ( m_PreviousDefusePercent < 0.f && DefusePercent >= 0.f )
{
LockSlot( true, bSlotIsLocked );
// activated the defuse process: set our static text once, and then show the panel
if ( m_DefuseTitleTextHandle )
{
if ( pPlayer->m_bIsGrabbingHostage )
m_pScaleformUI->Value_SetText( m_DefuseTitleTextHandle, "#SFUIHUD_InfoPanel_HostageTitle" );
else
m_pScaleformUI->Value_SetText( m_DefuseTitleTextHandle, "#SFUIHUD_InfoPanel_DefuseTitle" );
}
if ( m_DefuseBodyTextHandle )
{
if ( bSpectating )
{
C_CSPlayer *pTargetPlayer = ToCSPlayer( pPlayer->GetObserverTarget() );
if ( pTargetPlayer )
{
wchar_t wszLocalized[100];
wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH];
g_pVGuiLocalize->ConvertANSIToUnicode( pTargetPlayer->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) );
if ( pTargetPlayer->HasDefuser() )
g_pVGuiLocalize->ConstructString( wszLocalized, sizeof( wszLocalized ), g_pVGuiLocalize->Find( "#SFUIHUD_InfoPanel_Spec_DefuseText" ), 1, wszPlayerName );
else
g_pVGuiLocalize->ConstructString( wszLocalized, sizeof( wszLocalized ), g_pVGuiLocalize->Find( "#SFUIHUD_InfoPanel_Spec_DefuseText_NoKit" ), 1, wszPlayerName );
m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, wszLocalized );
}
else
{
m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "" );
}
}
else
{
if ( pPlayer->m_bIsGrabbingHostage )
m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "#SFUIHUD_InfoPanel_HostageText" );
else if ( pPlayer->HasDefuser() )
m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "#SFUIHUD_InfoPanel_DefuseText" );
else
m_pScaleformUI->Value_SetText( m_DefuseBodyTextHandle, "#SFUIHUD_InfoPanel_DefuseText_NoKit" );
}
}
if ( m_DefuseIconKit && m_DefuseIconNoKit )
{
bool bHasDefuser = pPlayer->HasDefuser();
m_pScaleformUI->Value_SetVisible( m_DefuseIconKit, bHasDefuser );
m_pScaleformUI->Value_SetVisible( m_DefuseIconNoKit, !bHasDefuser );
}
ShowPanelNoLock( SFHUDINFO_Defuse, true );
}
if ( m_PreviousDefusePercent >= 0.f && bDefuseCanceled )
{
LockSlot( true, bSlotIsLocked );
// stopped defusing: hide the panel
ShowPanelNoLock( SFHUDINFO_Defuse, false );
}
m_PreviousDefusePercent = DefusePercent;
// Update current achievement UI
if ( m_activeAchievement != CSInvalidAchievement )
{
if ( m_AchievementDisplayTimer.HasStarted() && m_AchievementDisplayTimer.IsElapsed() )
{
LockSlot( true, bSlotIsLocked );
m_AchievementDisplayTimer.Invalidate();
// start the hide process on the panel
ShowPanelNoLock( SFHUDINFO_Medal, false );
}
else
{
// Once the panel is fully gone, clear the active achievement so we can display the next one
if ( m_MedalPanelHandle )
{
LockSlot( true, bSlotIsLocked );
ScaleformDisplayInfo dinfo;
m_pScaleformUI->Value_GetDisplayInfo( m_MedalPanelHandle, &dinfo );
if ( !dinfo.GetVisibility() )
{
m_activeAchievement = CSInvalidAchievement;
}
}
}
}
else if ( m_achievementQueue.Count() > 0 )
{
// Grab the next queued achievement and pop it up
AchivementQueueInfo queueInfo = m_achievementQueue.RemoveAtHead();
m_AchievementDisplayTimer.Start( g_MedalDisplayTime );
m_activeAchievement = queueInfo.type;
// [dwenger] Play the achievement earned sound effect
vgui::surface()->PlaySound( "UI/achievement_earned.wav" );
// Here we get the achievement to be displayed and set that in the popup windows
IAchievementMgr *pAchievementMgr = engine->GetAchievementMgr();
if ( !pAchievementMgr )
return;
IAchievement *pAchievement = pAchievementMgr->GetAchievementByID( m_activeAchievement, queueInfo.playerSlot );
if ( pAchievement )
{
LockSlot( true, bSlotIsLocked );
if ( m_MedalTitleTextHandle )
{
m_pScaleformUI->Value_SetText( m_MedalTitleTextHandle, ACHIEVEMENT_LOCALIZED_NAME( pAchievement ) );
}
if ( m_MedalBodyTextHandle )
{
// not showing the text for right now because the body field isn't incorperated into the design, will address later
m_pScaleformUI->Value_SetText( m_MedalBodyTextHandle, "" );
//m_pScaleformUI->Value_SetText( m_MedalBodyTextHandle, ACHIEVEMENT_LOCALIZED_DESC( pAchievement ) );
}
// Notify the panel of the achievement name, so we can display the appropriate icon (icon name MUST match the achievement short name, eg. "ENEMY_KILL_HIGH", "SAME_UNIFORM")
WITH_SFVALUEARRAY( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, pAchievement->GetName());
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setMedalAnnouncement", data, 1 );
}
// Achievements and medals always take precedent over hints / priority messages.
if ( m_PriorityMsgDisplayTimer.HasStarted() )
{
if ( m_bHintPanelHidden )
{
m_bHintPanelHidden = false;
m_HintDisplayTimer.Invalidate();
}
SetPriorityText( static_cast<wchar_t*>(NULL) );
}
if ( m_HintDisplayTimer.HasStarted() )
{
SetHintText( NULL );
}
ShowPanelNoLock( SFHUDINFO_Medal, true );
}
}
LockSlot( false, bSlotIsLocked );
// Clear any transient data now
if ( m_bActive )
{
m_bDeferRaiseHelpPanel = false;
m_bDeferRaisePriorityMessagePanel = false;
}
}
static void GetTextBoxForElement( IScaleformUI *pScaleformUI, SFVALUE root, const char *elementName, const char *textElementName, SFVALUE &sfv )
{
SFVALUE TempHandle = pScaleformUI->Value_GetMember( root, elementName );
if ( TempHandle )
{
sfv = pScaleformUI->Value_GetMember( TempHandle, textElementName );
pScaleformUI->ReleaseValue( TempHandle );
}
}
void SFHudInfoPanel::FlashReady( void )
{
ListenForGameEvent( "achievement_earned_local" );
m_HelpPanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelHelp" );
if ( m_HelpPanelHandle )
{
SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_HelpPanelHandle, "Panel" );
if ( AnimatedPanelHandle )
{
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "HelpText", "TextBox", m_HelpBodyTextHandle );
m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
}
}
m_PriorityMessagePanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelCenter" );
if ( m_PriorityMessagePanelHandle )
{
SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_PriorityMessagePanelHandle, "Panel" );
if ( AnimatedPanelHandle )
{
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "CenterTextTitle", "TextBox", m_PriorityMessageTitleTextHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "CenterText", "TextBox", m_PriorityMessageBodyTextHandle );
m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
}
}
m_MedalPanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelMedal" );
if ( m_MedalPanelHandle )
{
SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_MedalPanelHandle, "Panel" );
if ( AnimatedPanelHandle )
{
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "MedalTitleText", "TextBox", m_MedalTitleTextHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "MedalText", "TextBox", m_MedalBodyTextHandle );
m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
}
}
m_DefusePanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanelDefuse" );
if ( m_DefusePanelHandle )
{
SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_DefusePanelHandle, "Panel" );
m_DefuseIconKit = m_pScaleformUI->Value_GetMember( m_DefusePanelHandle, "icon_defuse" );
m_DefuseIconNoKit = m_pScaleformUI->Value_GetMember( m_DefusePanelHandle, "icon_no_defusekit" );
if ( AnimatedPanelHandle )
{
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "DefuseText", "TextBox", m_DefuseBodyTextHandle );
SFVALUE TitleBarHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "DefuseTextTitle" );
if ( TitleBarHandle )
{
SFVALUE TitleTextHandle = m_pScaleformUI->Value_GetMember( TitleBarHandle, "DefuseTitle" );
if ( TitleTextHandle )
{
GetTextBoxForElement( m_pScaleformUI, TitleTextHandle, "DefuseTitle", "TextBox1", m_DefuseTitleTextHandle );
GetTextBoxForElement( m_pScaleformUI, TitleTextHandle, "DefuseTitle", "TextBox2", m_DefuseTimerTextHandle );
m_pScaleformUI->ReleaseValue( TitleTextHandle );
}
m_pScaleformUI->ReleaseValue( TitleBarHandle );
}
m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
}
}
// hide everything initially
HideAll();
}
bool SFHudInfoPanel::PreUnloadFlash( void )
{
StopListeningForAllEvents();
SafeReleaseSFVALUE( m_HelpPanelHandle );
SafeReleaseSFVALUE( m_HelpBodyTextHandle );
SafeReleaseSFVALUE( m_MedalPanelHandle );
SafeReleaseSFVALUE( m_MedalTitleTextHandle );
SafeReleaseSFVALUE( m_MedalBodyTextHandle );
SafeReleaseSFVALUE( m_DefusePanelHandle );
SafeReleaseSFVALUE( m_DefuseTitleTextHandle );
SafeReleaseSFVALUE( m_DefuseTimerTextHandle );
SafeReleaseSFVALUE( m_DefuseBodyTextHandle );
SafeReleaseSFVALUE( m_DefuseIconKit );
SafeReleaseSFVALUE( m_DefuseIconNoKit );
SafeReleaseSFVALUE( m_PriorityMessagePanelHandle );
SafeReleaseSFVALUE( m_PriorityMessageTitleTextHandle );
SafeReleaseSFVALUE( m_PriorityMessageBodyTextHandle );
return true;
}
void SFHudInfoPanel::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudInfoPanel, this, HelpAchievementModule );
}
else
{
// When initially loaded, hide this panel
HideAll();
}
}
void SFHudInfoPanel::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
void SFHudInfoPanel::Reset( void )
{
HideAll();
}
bool SFHudInfoPanel::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() )
return false;
return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
}
void SFHudInfoPanel::SetActive( bool bActive )
{
if ( m_bActive && !bActive )
{
HideAll();
}
CHudElement::SetActive( bActive );
}
bool SFHudInfoPanel::MsgFunc_HintText( const CCSUsrMsg_HintText &msg )
{
const char *tmpStr = hudtextmessage->LookupString( msg.text().c_str(), NULL );
LocalizeAndDisplay( tmpStr, tmpStr );
return true;
}
bool SFHudInfoPanel::MsgFunc_KeyHintText( const CCSUsrMsg_KeyHintText &msg )
{
const char *tmpStr = hudtextmessage->LookupString( msg.hints(0).c_str(), NULL );
LocalizeAndDisplay( tmpStr, tmpStr );
return true;
}
void SFHudInfoPanel::LocalizeAndDisplay( const char *pszHudTxtMsg, const char *szRawString )
{
wchar_t szBuf[255];
wchar_t *pszBuf;
// init buffers & pointers
szBuf[0] = 0;
pszBuf = szBuf;
// try to localize
if ( pszHudTxtMsg )
{
pszBuf = g_pVGuiLocalize->Find( pszHudTxtMsg );
}
else
{
pszBuf = g_pVGuiLocalize->Find( szRawString );
}
if ( !pszBuf )
{
// use plain ASCII string
g_pVGuiLocalize->ConvertANSIToUnicode( szRawString, szBuf, sizeof(szBuf) );
pszBuf = szBuf;
}
// replace key binding text
wchar_t keyBindingBuf[512];
UTIL_ReplaceKeyBindings( pszBuf, sizeof( szBuf ), keyBindingBuf, sizeof( keyBindingBuf ) );
// make it visible
SetHintText( pszBuf );
}
bool SFHudInfoPanel::SetHintText( wchar_t *text )
{
if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
{
WITH_SLOT_LOCKED
{
if ( text )
{
if ( m_HelpBodyTextHandle )
{
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_SetTextHTML( m_HelpBodyTextHandle, m_pScaleformUI->ReplaceGlyphKeywordsWithHTML( text ) );
}
}
if ( m_PriorityMsgDisplayTimer.HasStarted() )
{
// Defer display of the hint message until the priority message has finished displaying
m_bHintPanelHidden = true;
m_HintDisplayTimer.Start( g_HintDisplayTime + m_PriorityMsgDisplayTimer.GetRemainingTime() );
}
else
{
// start (or reset) the timer for auto-hiding this latest hint
m_HintDisplayTimer.Start( g_HintDisplayTime );
ShowPanelNoLock( SFHUDINFO_Help, true );
}
}
else
{
m_HintDisplayTimer.Invalidate();
ShowPanelNoLock( SFHUDINFO_Help, false );
}
}
}
return true;
}
#ifndef _GAMECONSOLE
ConVar cl_display_scaleform_achievement_popups( "cl_display_scaleform_achievement_popups", "0", FCVAR_CLIENTDLL );
#else
ConVar cl_display_scaleform_achievement_popups( "cl_display_scaleform_achievement_popups", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE );
#endif
void SFHudInfoPanel::FireGameEvent( IGameEvent * event )
{
const char *pEventName = event->GetName();
if ( cl_display_scaleform_achievement_popups.GetBool() )
{
if ( Q_strcmp( "achievement_earned_local", pEventName ) == 0 )
{
AchivementQueueInfo queueInfo;
queueInfo.type = (eCSAchievementType)event->GetInt( "achievement" );
queueInfo.playerSlot = event->GetInt( "splitscreenplayer" );
// If this achievement is for this player, enqueue it to display on the next tick
if ( queueInfo.playerSlot == engine->GetActiveSplitScreenPlayerSlot() )
{
m_achievementQueue.Insert(queueInfo);
}
}
}
}
// Common code to setup the priority text window for a new message, or tear it down if the message is cleared
void SFHudInfoPanel::ModifyPriorityTextWindow( bool bMsgSet )
{
if ( bMsgSet )
{
bool bAlreadyActive = m_PriorityMsgDisplayTimer.HasStarted() && !m_PriorityMsgDisplayTimer.IsElapsed();
// start (or reset) the timer for auto-hiding this latest text
static ConVarRef scr_centertime( "scr_centertime" );
m_PriorityMsgDisplayTimer.Start( scr_centertime.GetFloat() );
if ( m_PriorityMessageTitleTextHandle )
{
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_SetText( m_PriorityMessageTitleTextHandle, "#SFUIHUD_InfoPanel_PriorityMsgTitle" );
}
}
if ( bAlreadyActive )
{
WITH_SLOT_LOCKED
{
// don't re-animate the window into position, just flash it and swap the text
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "flashCenterText", NULL, 0 );
}
}
else
{
if ( m_HintDisplayTimer.HasStarted() )
{
// Priority messages take precedent. Temporarily hide the hint panel.
m_bHintPanelHidden = true;
m_HintDisplayTimer.Start( m_HintDisplayTimer.GetElapsedTime() + scr_centertime.GetFloat() );
ShowPanelNoLock( SFHUDINFO_Help, false );
}
ShowPanelNoLock( SFHUDINFO_PriorityMessage, true );
}
}
else
{
m_PriorityMsgDisplayTimer.Invalidate();
ShowPanelNoLock( SFHUDINFO_PriorityMessage, false );
}
}
// ANSI C-string version
void SFHudInfoPanel::SetPriorityText( char *pMsg )
{
if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
{
WITH_SLOT_LOCKED
{
ModifyPriorityTextWindow( (pMsg != NULL) );
if ( pMsg && m_PriorityMessageBodyTextHandle )
{
if ( g_BannedWords.BInitialized() )
{
int nLen = V_strlen( pMsg );
int cubDestSizeInBytes = ( 1 + nLen ) * sizeof( wchar_t );
wchar_t * pwchBuffer = ( wchar_t * ) stackalloc( cubDestSizeInBytes );
V_UTF8ToUnicode( pMsg, pwchBuffer, cubDestSizeInBytes );
if ( g_BannedWords.CensorBannedWordsInplace( pwchBuffer ) )
{
m_pScaleformUI->Value_SetText( m_PriorityMessageBodyTextHandle, pwchBuffer );
pMsg = NULL;
}
}
if ( pMsg )
{
m_pScaleformUI->Value_SetText( m_PriorityMessageBodyTextHandle, pMsg );
}
}
}
}
}
// TCHAR (multi-byte) string version
void SFHudInfoPanel::SetPriorityText( wchar_t *pMsg )
{
if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
{
WITH_SLOT_LOCKED
{
ModifyPriorityTextWindow( (pMsg != NULL) );
if ( pMsg && m_PriorityMessageBodyTextHandle )
{
g_BannedWords.CensorBannedWordsInplace( pMsg );
m_pScaleformUI->Value_SetTextHTML( m_PriorityMessageBodyTextHandle, m_pScaleformUI->ReplaceGlyphKeywordsWithHTML( pMsg ) );
}
}
}
}
void SFHudInfoPanel::SetPriorityHintText( wchar_t *pMsg )
{
if ( FlashAPIIsValid() && !m_AchievementDisplayTimer.HasStarted() )
{
WITH_SLOT_LOCKED
{
//m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "flashCenterText", NULL, 0 );
if ( pMsg )
{
// make it visible
g_BannedWords.CensorBannedWordsInplace( pMsg );
SetHintText( pMsg );
}
}
}
}
void SFHudInfoPanel::ApplyYOffset( int nOffset )
{
if ( FlashAPIIsValid() )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, nOffset );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setYOffset", data, 1 );
}
}
}

View File

@@ -0,0 +1,123 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD elements for medals/achievements, and hint text
//
//=====================================================================================//
#ifndef SFHUDINFOPANEL_H_
#define SFHUDINFOPANEL_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include "tier1/utlqueue.h"
class SFHudInfoPanel : public SFHudFlashInterface
{
enum HUDINFO_TYPE
{
SFHUDINFO_All,
SFHUDINFO_Help,
SFHUDINFO_Defuse,
SFHUDINFO_Medal,
SFHUDINFO_PriorityMessage
};
public:
explicit SFHudInfoPanel( const char *value );
virtual ~SFHudInfoPanel();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual bool ShouldDraw( void );
virtual void SetActive( bool bActive );
virtual void Reset( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
// receivers for hint messages
bool MsgFunc_HintText( const CCSUsrMsg_HintText &msg );
bool MsgFunc_KeyHintText( const CCSUsrMsg_KeyHintText &msg );
virtual void FireGameEvent( IGameEvent * event );
// Priority text replaces what used to be called CenterPrint text in VGui
void SetPriorityText( char *pMsg );
void SetPriorityText( wchar_t *pMsg );
void SetPriorityHintText( wchar_t *pMsg );
// Offsets the Y location of the notification panels
void ApplyYOffset( int nOffset );
bool IsVisible( void ) { return m_bIsVisible; }
CUserMessageBinder m_UMCMsgHintText;
CUserMessageBinder m_UMCMsgKeyHintText;
CUserMessageBinder m_UMCMsgQuestProgress;
protected:
void ModifyPriorityTextWindow( bool bMsgSet );
void ShowPanel( HUDINFO_TYPE panelType, bool value );
// Only call this function if you're already inside of a slot-lock block!
void ShowPanelNoLock( HUDINFO_TYPE panelType, bool value );
void HideAll( void );
void LockSlot( bool wantItLocked, bool& currentlyLocked );
bool SetHintText( wchar_t *text );
void LocalizeAndDisplay( const char *pszHudTxtMsg, const char *szRawString );
protected:
SFVALUE m_HelpPanelHandle;
SFVALUE m_HelpBodyTextHandle;
CountdownTimer m_HintDisplayTimer;
SFVALUE m_DefusePanelHandle;
SFVALUE m_DefuseTitleTextHandle;
SFVALUE m_DefuseBodyTextHandle;
SFVALUE m_DefuseTimerTextHandle;
SFVALUE m_DefuseIconKit;
SFVALUE m_DefuseIconNoKit;
float m_PreviousDefusePercent;
SFVALUE m_MedalPanelHandle;
SFVALUE m_MedalTitleTextHandle;
SFVALUE m_MedalBodyTextHandle;
struct AchivementQueueInfo
{
eCSAchievementType type;
int playerSlot;
};
CUtlQueue<AchivementQueueInfo> m_achievementQueue;
eCSAchievementType m_activeAchievement;
CountdownTimer m_AchievementDisplayTimer;
CountdownTimer m_PriorityMsgDisplayTimer;
SFVALUE m_PriorityMessagePanelHandle;
SFVALUE m_PriorityMessageTitleTextHandle;
SFVALUE m_PriorityMessageBodyTextHandle;
bool m_bDeferRaiseHelpPanel;
bool m_bDeferRaisePriorityMessagePanel;
bool m_bHintPanelHidden; // True when we have hidden a help panel in order to show a priority message
bool m_bIsVisible;
};
#endif /* SFHUDINFOPANEL_H_ */

View File

@@ -0,0 +1,313 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"
#include "hudelement.h"
#include "sfhudmoney.h"
#include "hud_macros.h"
#include "cs_gamerules.h"
#include "sfhudfreezepanel.h"
#include "c_plantedc4.h"
#include "sfhudradar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
DECLARE_HUDELEMENT( SFHudMoney);
DECLARE_HUD_MESSAGE( SFHudMoney, AdjustMoney );
SFUI_BEGIN_GAME_API_DEF
SFUI_DECL_METHOD( DoneAnimatingAdd ),
SFUI_DECL_METHOD( DoneAnimatingSub ),
SFUI_END_GAME_API_DEF( SFHudMoney, Money );
extern ConVar cl_draw_only_deathnotices;
SFHudMoney::SFHudMoney( const char *value ) : SFHudFlashInterface( value )
{
m_bAnimatingAdd = false;
m_bAnimatingSub = false;
m_nLastMoney = 0;
m_lastEntityIndex = 0;
m_hCash = NULL;
m_hAddCash = NULL;
m_hRemoveCash = NULL;
m_hBuyZoneIcon = NULL;
m_bShowBuyZoneIcon = false;
m_nShiftState = -1;
SetIgnoreGlobalHudDisable( true );
}
SFHudMoney::~SFHudMoney()
{
}
void SFHudMoney::Init( void )
{
HOOK_HUD_MESSAGE( SFHudMoney, AdjustMoney );
}
void SFHudMoney::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudMoney, this, Money );
}
}
void SFHudMoney::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
bool SFHudMoney::ShouldDraw( void )
{
if ( IsTakingAFreezecamScreenshot() )
return false;
if ( !CSGameRules() )
return false;
if ( CSGameRules()->IsPlayingTraining() || !CSGameRules()->CanSpendMoneyInMap() )
return false;
IViewPortPanel* buyPanel = NULL;
IViewPortPanel *scoreboard = NULL;
if ( GetViewPortInterface() )
{
buyPanel = GetViewPortInterface()->FindPanelByName( PANEL_BUY );
scoreboard = GetViewPortInterface()->FindPanelByName( PANEL_SCOREBOARD );
}
if ( CSGameRules()->GetGamePhase() == GAMEPHASE_MATCH_ENDED && scoreboard && scoreboard->IsVisible() )
return false;
bool bGloballyHidden = GetHud().HudDisabled() && ( !buyPanel || !buyPanel->IsVisible() );
return cl_drawhud.GetBool() && !bGloballyHidden && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
}
void SFHudMoney::SetActive( bool bActive )
{
Show( bActive );
CHudElement::SetActive( bActive );
}
void SFHudMoney::Show( bool show )
{
if ( m_FlashAPI && show != m_bActive )
{
WITH_SLOT_LOCKED
{
if ( show )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
}
else
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
}
}
UpdateCurrentMoneyText();
}
}
void SFHudMoney::FlashReady( void )
{
m_bAnimatingAdd = false;
m_bAnimatingSub = false;
m_cashAdjustmentQueue.SetCount( 0 );
SFVALUE root = m_pScaleformUI->Value_GetMember( m_FlashAPI, "MoneyPanel" );
if ( root )
{
SFVALUE innerPanel = m_pScaleformUI->Value_GetMember( root, "InnerMoneyPanel" );
if ( innerPanel )
{
m_hBuyZoneIcon = m_pScaleformUI->TextObject_MakeTextObjectFromMember( innerPanel, "BuyZoneIcon" );
SFVALUE container = m_pScaleformUI->Value_GetMember( innerPanel, "CashContainer" );
if ( container )
{
m_hCash = m_pScaleformUI->TextObject_MakeTextObjectFromMember( container, "Cash" );
SFVALUE AddCash = m_pScaleformUI->Value_GetMember( container, "AddCash" );
if ( AddCash )
{
m_hAddCash = m_pScaleformUI->TextObject_MakeTextObjectFromMember( AddCash, "AddText" );
g_pScaleformUI->ReleaseValue( AddCash );
}
SFVALUE RemoveCash = m_pScaleformUI->Value_GetMember( container, "RemoveCash" );
if ( RemoveCash )
{
m_hRemoveCash = m_pScaleformUI->TextObject_MakeTextObjectFromMember( RemoveCash, "RemoveText" );
g_pScaleformUI->ReleaseValue( RemoveCash );
}
g_pScaleformUI->ReleaseValue( container );
}
g_pScaleformUI->ReleaseValue( innerPanel );
}
g_pScaleformUI->ReleaseValue( root );
}
if ( m_bActive )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showPanel", NULL, 0 );
}
else
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hidePanel", NULL, 0 );
}
if ( m_hBuyZoneIcon )
{
m_hBuyZoneIcon->SetVisible( false );
m_bShowBuyZoneIcon = false;
}
m_nShiftState = -1;
UpdateCurrentMoneyText();
}
bool SFHudMoney::PreUnloadFlash( void )
{
SafeReleaseSFTextObject( m_hCash );
SafeReleaseSFTextObject( m_hAddCash );
SafeReleaseSFTextObject( m_hRemoveCash );
SafeReleaseSFTextObject( m_hBuyZoneIcon );
return true;
}
void SFHudMoney::ProcessInput( void )
{
C_CSPlayer* pPlayer = pPlayer = GetHudPlayer();
CCSGameRules* pGameRules = CSGameRules();
if ( pGameRules && pPlayer )
{
int entityIndex = pPlayer->entindex();
if ( pPlayer->IsControllingBot() )
entityIndex = pPlayer->GetControlledBotIndex();
// let's always draw attention to when the player's money has changed
if ( entityIndex == m_lastEntityIndex )
{
if ( m_nLastMoney != pPlayer->GetAccount() )
{
// if this is the start of the very first round, don't show the change that can happen from the warmup round to the start round
if ( pGameRules->GetTotalRoundsPlayed() == 0 && pGameRules->GetRoundElapsedTime() < 1 )
{
UpdateCurrentMoneyText();
}
else
{
UpdateMoneyChange( pPlayer->GetAccount() - m_nLastMoney );
}
}
}
else
{
// we changed who we're observing, so just update it directly
m_lastEntityIndex = entityIndex;
UpdateCurrentMoneyText();
}
m_nLastMoney = pPlayer->GetAccount();
bool bShowBuyZoneIcon = CSGameRules()->CanSpendMoneyInMap() &&
!pGameRules->IsBuyTimeElapsed() &&
pPlayer->IsInBuyZone();
if ( m_hBuyZoneIcon && ( m_bShowBuyZoneIcon != bShowBuyZoneIcon ) )
{
m_bShowBuyZoneIcon = bShowBuyZoneIcon;
WITH_SLOT_LOCKED
{
m_hBuyZoneIcon->SetVisible( m_bShowBuyZoneIcon );
}
}
int nShiftState = 0;
bool bRoundRadar = ( GET_HUDELEMENT( SFHudRadar ) )->m_bRound;
nShiftState = ( pGameRules->IsHostageRescueMap() || !bRoundRadar ) ? 1: nShiftState;
nShiftState = pPlayer->IsBuyMenuOpen() ? 2: nShiftState;
if ( FlashAPIIsValid() && ( m_nShiftState != nShiftState ) )
{
m_nShiftState = nShiftState;
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, nShiftState );
g_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "SetShift", data, 1 );
}
}
}
}
bool SFHudMoney::MsgFunc_AdjustMoney( const CCSUsrMsg_AdjustMoney &msg )
{
return true;
}
void SFHudMoney::UpdateMoneyChange( int nDelta )
{
if ( FlashAPIIsValid() )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, nDelta );
g_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "DisplayMoneyAdjustment", data, 1 );
}
}
if ( nDelta < 0 )
{
UpdateCurrentMoneyText();
m_bAnimatingSub = true;
}
else
{
m_bAnimatingAdd = true;
}
}
void SFHudMoney::DoneAnimatingAdd( SCALEFORM_CALLBACK_ARGS_DECL )
{
m_bAnimatingAdd = false;
UpdateCurrentMoneyText();
}
void SFHudMoney::DoneAnimatingSub( SCALEFORM_CALLBACK_ARGS_DECL )
{
m_bAnimatingSub = false;
}
void SFHudMoney::UpdateCurrentMoneyText( void )
{
C_CSPlayer *pPlayer = GetHudPlayer();
if ( pPlayer && m_hCash )
{
WITH_SLOT_LOCKED
{
m_hCash->SetText( CFmtStr( "$%d", pPlayer->GetAccount() ) );
}
}
}

View File

@@ -0,0 +1,69 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SFHUDMONEY_H_
#define SFHUDMONEY_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "c_cs_hostage.h"
class SFHudMoney : public SFHudFlashInterface
{
public:
explicit SFHudMoney( const char *value );
virtual ~SFHudMoney();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual void Init( void );
virtual bool ShouldDraw( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
void Show( bool show );
bool MsgFunc_AdjustMoney( const CCSUsrMsg_AdjustMoney &msg );
void UpdateMoneyChange( int nDelta = 0 );
void DoneAnimatingAdd( SCALEFORM_CALLBACK_ARGS_DECL );
void DoneAnimatingSub( SCALEFORM_CALLBACK_ARGS_DECL );
CUserMessageBinder m_UMCMsgAdjustMoney;
private:
void UpdateCurrentMoneyText();
int m_nMoneyChange;
int m_nLastMoney;
int m_lastEntityIndex;
int m_nShiftState;
bool m_bShowBuyZoneIcon;
ISFTextObject * m_hCash;
ISFTextObject * m_hAddCash;
ISFTextObject * m_hRemoveCash;
ISFTextObject * m_hBuyZoneIcon;
CUtlVector<int> m_cashAdjustmentQueue;
bool m_bAnimatingAdd;
bool m_bAnimatingSub;
};
#endif /* SFHUDMONEY_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,603 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SFHUDRADAR_H_
#define SFHUDRADAR_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "c_cs_hostage.h"
#define MAX_LOCATION_TEXT_LENGTH 100
#define MAX_DECOYS 30
class SFHudRadar : public SFHudFlashInterface
{
// this manages the display of the players and hostages
// in the radar
protected:
enum ICON_PACK_TYPE
{
ICON_PACK_PLAYER,
ICON_PACK_HOSTAGE,
ICON_PACK_DECOY,
ICON_PACK_DEFUSER,
};
enum
{
R_BELOW = 0,
R_SAMELEVEL = 1,
R_ABOVE = 2,
};
// each enum represents an icon that this class is managing
enum PLAYER_ICON_INDICES
{
PI_PLAYER_NUMBER,
PI_PLAYER_LETTER,
PI_FIRST_ROTATED,
PI_PLAYER_INDICATOR = PI_FIRST_ROTATED,
PI_SPEAKING,
PI_SPEAKING_OFFMAP,
PI_ABOVE,
PI_BELOW,
PI_HOSTAGE_MOVING,
PI_HOSTAGE_MOVING_OFFMAP,
PI_CT,
PI_CT_OFFMAP,
PI_CT_DEAD,
PI_CT_GHOST,
PI_T,
PI_T_OFFMAP,
PI_T_DEAD,
PI_T_GHOST,
PI_ENEMY,
PI_ENEMY_OFFMAP,
PI_ENEMY_DEAD,
PI_ENEMY_GHOST,
PI_HOSTAGE,
PI_HOSTAGE_OFFMAP,
PI_HOSTAGE_DEAD,
PI_HOSTAGE_GHOST,
PI_DIRECTION_INDICATOR,
PI_DEFUSER,
PI_SELECTED,
PI_VIEWFRUSTRUM,
PI_ENEMY_SEELOCAL,
PI_NUM_ICONS
};
class SFHudRadarIconPackage
{
public:
SFHudRadarIconPackage();
~SFHudRadarIconPackage();
// zero all the internal variables
void ClearAll( void );
// get handles to the icons which will all be children
// of the iconPackage handle
void Init( IScaleformUI* pui, SFVALUE iconPackage );
// release all the handles, and clear all the variables
// used when removing players or changing maps
void NukeFromOrbit( SFHudRadar* pSFUI );
// reset all variables to their start of round values
void StartRound( void );
// set the states for this player
void SetIsPlayer( bool value );
void SetIsSelected( bool value );
void SetIsSpeaking ( bool value );
void SetIsOffMap( bool value );
void SetIsAboveOrBelow( int value );
void SetIsMovingHostage( bool value );
void SetIsDead( bool value );
void SetIsRescued( bool value );
void SetPlayerTeam( int team );
void SetGrenadeExpireTime( float value );
void SetIsSpotted( bool value );
void SetIsSpottedByFriendsOnly( bool value );
void SetAlpha( float newAlpha );
void SetIsOnLocalTeam( bool value );
void SetIsBot( bool value );
void SetIsControlledBot( void );
void SetIsDefuse( bool bValue );
// given the current set of states, decide which
// icons should be shown and which should be hidden
void SetupIconsFromStates( void );
// each bit in newFlags represents the visibility of one of the
// icons in the PLAYER_ICON_INDICES. If the bit is on, the icon
// is shown.
void SetVisibilityFlags( int newFlags );
void UpdateIconsPostion( void );
bool IsHostageType( void ) { return m_IconPackType == ICON_PACK_HOSTAGE;}
bool IsDecoyType( void ) { return m_IconPackType == ICON_PACK_DECOY;}
bool IsPlayerType( void ) { return m_IconPackType == ICON_PACK_PLAYER;}
bool IsDefuserType( void ) { return m_IconPackType == ICON_PACK_DEFUSER;}
bool IsVisible( void );
public:
// pointer to scaleform
IScaleformUI* m_pScaleformUI;
// the parent for all the icons
SFVALUE m_IconPackage;
SFVALUE m_IconPackageRotate;
// the handles for all the icons listed in PLAYER_ICON_INDICES
SFVALUE m_Icons[PI_NUM_ICONS];
// the location and position of this player/hostage
// only updated when the player is spotted
Vector m_Position; // current x,y pos
QAngle m_Angle; // view origin 0..360
// HUD Position, rotation and scale - used to update the position of the visible icons
Vector m_HudPosition;
float m_HudRotation;
float m_HudScale;
// ignore visibility updates until a little time has passed
// this keeps track of when the round started
float m_fRoundStartTime;
// the time at which this player/hostage died ( or was rescued )
// used to calculate the alpha of the X icon.
float m_fDeadTime;
// the time at which the player / hostage was last spotted
// used to fade out the ? icon
float m_fGhostTime;
// the alpha currently used to display all icons
// used to lazy update the actual scaleform value
float m_fCurrentAlpha;
// last time we applied this color to the movie
float m_fLastColorUpdate;
// each bit represents one of the PLAYER_ICON_INDICES
// used to lazy update the visibility of the icons in scaleform
int m_iCurrentVisibilityFlags;
// the index of this player/hostage in the radar.
// used to create the instance name of the icon package in flash
int m_iIndex;
// set from the player objects UserID or EntityID ( for the hostages ). Lets us find the radar
// object that represents a player / hostage
int m_iEntityID;
// state variables used to keep track of the player / hostage state
// so we know which icon( s ) to show
int m_Health; // 0..100, 7 bit
wchar_t m_wcName[MAX_PLAYER_NAME_LENGTH+1];
// the base icon for the player
int m_iPlayerType; // will be PI_CT, PI_T, or PI_HOSTAGE
int m_nAboveOrBelow;// R_BELOW = 0,R_SAMELEVEL = 1,R_ABOVE = 2,
float m_fGrenExpireTime;
ICON_PACK_TYPE m_IconPackType;
bool m_bIsActive : 1;
bool m_bOffMap : 1;
bool m_bIsPlayer : 1;
bool m_bIsSelected : 1;
bool m_bIsSpeaking : 1;
bool m_bIsDead : 1;
bool m_bIsBot : 1;
bool m_bIsMovingHostage : 1;
bool m_bIsSpotted : 1;
bool m_bIsSpottedByFriendsOnly : 1;
bool m_bIsRescued : 1;
bool m_bIsOnLocalTeam : 1;
bool m_bIsDefuser : 1;
bool m_bHostageIsUsed : 1;
// don't put anything new after the bitfields or suffer the Wrath of the Compiler!
};
// this little class manages the display of the hostage
// indicators in the panel
class SFHudRadarHostageIcons
{
public:
enum HOSTAGE_ICON_INDICES
{
HI_DEAD,
HI_RESCUED,
HI_ALIVE,
HI_TRANSIT,
HI_NUM_ICONS,
HI_UNUSED = HI_NUM_ICONS,
};
public:
SFHudRadarHostageIcons();
~SFHudRadarHostageIcons();
void Init( IScaleformUI* scaleformui, SFVALUE iconPackage );
void ReleaseHandles( SFHudRadar* pradar );
void SetStatus( int status );
public:
IScaleformUI* m_pScaleformUI;
// the parent object of all the icons
SFVALUE m_IconPackage;
// the icons which represent each of the HOSTAGE_ICON_INDICES
SFVALUE m_Icons[HI_NUM_ICONS];
// the index of the icon that is currently shown
int m_iCurrentIcon;
};
// this just keeps track of the bombzone and hostagezone
// icons that are shown on the radar
struct SFHudRadarGoalIcon
{
Vector m_Position;
SFVALUE m_Icon;
};
public:
explicit SFHudRadar( const char *value );
virtual ~SFHudRadar();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual void Init( void );
virtual bool ShouldDraw( void );
virtual void Reset( void )
{
SetActive( true );
}
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashLoaded( void );
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
void MapLoaded( SCALEFORM_CALLBACK_ARGS_DECL );
// overloads for the CGameEventListener class
virtual void FireGameEvent( IGameEvent *event );
bool MsgFunc_ProcessSpottedEntityUpdate( const CCSUsrMsg_ProcessSpottedEntityUpdate &msg );
void ShowRadar( bool value ) {m_bShowRadar = value;}
bool IsRadarShown( void ) {return m_bShowRadar;}
void ResizeHud( void );
void SwitchRadarToRound( bool toRound );
CUserMessageBinder m_UMCMsgProcessSpottedEntityUpdate;
bool m_bRound; // Is the radar round ( otherwise square )
protected:
void ResetRadar( bool bResetGlobalStates = true );
void ResetForNewMap( void );
void ResetRound( void );
void SetMap( const char* pMapName );
void WorldToRadar( const Vector& ptin, Vector& ptout );
void RadarToHud( const Vector& ptin, Vector& ptout );
void LazyCreateGoalIcons( void );
void FlashLoadMap( const char* pMapName );
void FlashUpdateMapLayer( int layerIdx );
void InitIconPackage( SFHudRadarIconPackage* pPlayer, int iAbsoluteIndex, ICON_PACK_TYPE packType );
void RemoveIconPackage( SFHudRadarIconPackage* pPlayer );
SFHudRadarIconPackage* CreatePlayer( int index );
void ResetPlayer( int index );
void RemovePlayer( int index );
SFHudRadarIconPackage* CreateHostage( int index );
void ResetHostage( int index );
void RemoveHostage( int index );
void RemoveStaleHostages( void );
void RemoveAllHostages( void );
SFHudRadarIconPackage* CreateDecoy( int index );
void RemoveAllDecoys( void );
void RemoveDecoy( int index );
SFHudRadarIconPackage * CreateDefuser( int nEntityID );
SFHudRadarIconPackage * GetDefuser( int nEntityID, bool bCreateIfNotFound = false );
void SetDefuserPos( int nEntityID, int x, int y, int z, int a );
void UpdateAllDefusers( void );
void RemoveAllDefusers( void );
void RemoveDefuser( int index );
bool LazyUpdateIconArray( SFHudRadarIconPackage* pArray, int lastIndex );
virtual bool LazyCreateIconPackage( SFHudRadarIconPackage* pPackage );
void LazyCreatePlayerIcons( void );
void SetPlayerTeam( int index, int team );
int GetPlayerIndexFromUserID( int userID );
int GetHostageIndexFromHostageEntityID( int entityID );
int GetDecoyIndexFromEntityID( int entityID );
int GetDefuseIndexFromEntityID( int nEntityID );
void ApplySpectatorModes( void );
void PositionRadarViewpoint( void );
void PlaceGoalIcons( void );
void Show( bool show );
void PlacePlayers();
void PlaceHostages();
void SetIconPackagePosition( SFHudRadarIconPackage* pPackage );
void UpdateMiscIcons( void );
void SetVisibilityFlags( int newFlags );
void SetupIconsFromStates( void );
void SetLocationText( wchar_t *newText );
void ResetRoundVariables( bool bResetGlobalStates = true );
void UpdateDecoys( void );
void UpdateAllPlayerNumbers( void );
void UpdatePlayerNumber( SFHudRadarIconPackage* pPackage );
SFHudRadarIconPackage* GetRadarPlayer( int index );
SFHudRadarIconPackage* GetRadarHostage( int index );
SFHudRadarIconPackage* GetRadarDecoy( int index );
SFHudRadarIconPackage* GetRadarDefuser( int index );
SFHudRadarIconPackage* GetRadarHeight( int index );
protected:
// these are the icons used individually by the radar and panel
enum RADAR_ICON_INDICES
{
RI_BOMB_IS_PLANTED,
RI_BOMB_IS_PLANTED_MEDIUM,
RI_BOMB_IS_PLANTED_FAST,
RI_IN_HOSTAGE_ZONE,
RI_DASHBOARD,
RI_BOMB_ICON_PLANTED,
RI_BOMB_ICON_DROPPED,
RI_BOMB_ICON_BOMB_CT,
RI_BOMB_ICON_BOMB_T,
RI_BOMB_ICON_BOMB_ABOVE,
RI_BOMB_ICON_BOMB_BELOW,
RI_BOMB_ICON_PACKAGE,
RI_DEFUSER_ICON_DROPPED,
RI_DEFUSER_ICON_PACKAGE,
RI_NUM_ICONS,
};
enum
{
MAX_BOMB_ZONES = 2,
};
int m_nCurrentRadarVerticalSection;
struct HudRadarLevelVerticalSection_t
{
int m_nSectionIndex;
char m_szSectionName[MAX_MAP_NAME];
float m_flSectionAltitudeFloor;
float m_flSectionAltitudeCeiling;
HudRadarLevelVerticalSection_t()
{
m_nSectionIndex = 0;
m_szSectionName[0] = 0;
m_flSectionAltitudeFloor = 0;
m_flSectionAltitudeCeiling = 0;
}
};
CUtlVector< HudRadarLevelVerticalSection_t > m_vecRadarVerticalSections;
// this holds the names and indexes of the messages we receive so that
// we don't have to do a whole bunch of string compares to find them
static CUtlMap<const char*, int> m_messageMap;
// these are used to scale world coordinates to radar coordinates
Vector m_MapOrigin;
float m_fMapSize;
float m_fRadarSize;
float m_fPixelToRadarScale;
float m_fWorldToPixelScale;
float m_fWorldToRadarScale;
// this is center of the radar in world and map coordinates
Vector m_RadarViewpointWorld;
Vector m_RadarViewpointMap;
float m_RadarRotation;
// the current position of the bomb
Vector m_BombPosition;
// the last time the bomb was seen. Used to fade
// out the bomb icon after it has dropped out of sight
float m_fBombSeenTime;
float m_fBombAlpha;
// the current position of the defuser
Vector m_DefuserPosition;
// the last time the defuser was seen. Used to fade
// out the defuser icon after it has dropped out of sight
float m_fDefuserSeenTime;
float m_fDefuserAlpha;
// a bitmap of the icons that are currently beeing shown.
// each bit corresponds to one the RADAR_ICON_INDICES
int m_iCurrentVisibilityFlags;
// the handles to the RADAR_ICON_INDICES icons
SFVALUE m_Icons[RI_NUM_ICONS];
// Background panel
SFVALUE m_BackgroundPanel;
// handles to the radar movie clips in flash.
// there is a rotation and a translation layer each for the icons and for the background map.
// The map and the icons have separate layers because the map is behind a mask layer, and the
// icons are not.
// the root of the entire radar and dashboard
SFVALUE m_RadarModule;
// the root of the radar part of the module
SFVALUE m_Radar;
// the layers that handle the icons
SFVALUE m_IconTranslation;
SFVALUE m_IconRotation;
// the layers that handle the map
SFVALUE m_MapRotation;
SFVALUE m_MapTranslation;
// handles to the actual bomb zone and hostage icons that are defined
// in the flash file
SFVALUE m_HostageZoneIcons[MAX_HOSTAGE_RESCUES];
SFVALUE m_BombZoneIcons[MAX_BOMB_ZONES];
// "handle" to the text that holds the current location
ISFTextObject* m_LocationText;
// the last index of an active player in the m_Players array
int m_iLastPlayerIndex;
// the last index of an active hostage in the m_Hostages array
int m_iLastHostageIndex;
// the last index of an active decoy in the m_Decoys array
int m_iLastDecoyIndex;
// the last index of an active defuser in the m_Defuser array
int m_iLastDefuserIndex;
// keeps the state information and icon handles for the players
SFHudRadarIconPackage m_Players[MAX_PLAYERS];
// keeps the state information and icon handles for the hostages
SFHudRadarIconPackage m_Hostages[MAX_HOSTAGES];
// keeps the state information and icon handles for the decoys
SFHudRadarIconPackage m_Decoys[MAX_DECOYS];
// keeps the state information and icon handles for the decoys
SFHudRadarIconPackage m_Defusers[MAX_PLAYERS];
// the handles to the hostage status icons that appear beneath the dashboard
SFHudRadarHostageIcons m_HostageStatusIcons[MAX_HOSTAGES];
// a goal icon is either a bomb-area or a hostage-area icon
// This array holds the positions / handles of the ones that are active for the current map
int m_iNumGoalIcons;
SFHudRadarGoalIcon m_GoalIcons[MAX_HOSTAGE_RESCUES + MAX_BOMB_ZONES];
// the current observer mode. Figures into the placement of the center of the radar
// and a few other things
int m_iObserverMode;
// there is a loaded and a desired so that we don't load the same map twice, and so that we
// can request that a map be loaded before the flash stuff is able to actually load it.
char m_cLoadedMapName[MAX_MAP_NAME+1];
char m_cDesiredMapName[MAX_MAP_NAME+1];
// the name of our current location
wchar_t m_wcLocationString[MAX_LOCATION_TEXT_LENGTH+1];
// keeps track of weather flash is ready or not and if it's currently being loaded
bool m_bFlashLoading : 1;
bool m_bFlashReady : 1;
// this is set by a con command to hide the whole radar
bool m_bShowRadar : 1;
bool m_bVisible;
bool m_bShowViewFrustrum;
// set to true in spectator mode if we're not in pro mode
bool m_bShowAll : 1;
// keep track of whether we've already gotten all the goal icons and player icons from the
// flash file. This is necessary because some of the level information is loaded before
// flash is ready
bool m_bGotGoalIcons : 1;
bool m_bGotPlayerIcons : 1;
// state information about which icons should be displayed
bool m_bShowingHostageZone : 1;
bool m_bBombPlanted : 1;
bool m_bBombDropped : 1;
bool m_bBombDefused : 1;
bool m_bBombExploded : 1;
bool m_bShowBombHighlight : 1;
bool m_bShowingDashboard : 1;
bool m_bBombIsSpotted : 1;
int m_nBombEntIndex;
int m_nBombHolderUserId;
bool m_bTrackDefusers;
// entities spotted last ProcessSpottedEntityUpdate
CBitVec<MAX_EDICTS> m_EntitySpotted;
};
#endif /* SFHUDRADAR_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SFHUDRETICLE_H_
#define SFHUDRETICLE_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include "weapon_csbase.h"
#include "takedamageinfo.h"
#include "weapon_csbase.h"
#include "ammodef.h"
#if defined(_PS3) || defined(POSIX)
#define HUDRET_WEPICON_SELECTED_IMG_STRING L"<img src='icon-%ls.png' height='22'/>"
#define HUDRET_WEPICON_IMG_STRING L"<img src='icon-%ls_grey.png' height='22'/>"
#else
#define HUDRET_WEPICON_SELECTED_IMG_STRING L"<img src='icon-%s.png' height='22'/>"
#define HUDRET_WEPICON_IMG_STRING L"<img src='icon-%s_grey.png' height='22'/>"
#endif
#define VIEWPUNCH_COMPENSATE_MAGIC_SCALAR 0.65 // cl_flinch_scale.GetFloat()
#define VIEWPUNCH_COMPENSATE_MAGIC_ANGLE 1
struct PlayerIDPanel
{
EHANDLE hPlayer;
SFVALUE panel;
SFVALUE arrowA;
SFVALUE arrowB;
SFVALUE arrowF;
SFVALUE voiceIcon;
SFVALUE defuseIcon;
int iconsFlag;
bool bActive;
bool bShowName;
bool bFriend;
int nTeam;
int nHealth;
float flUpdateAt;
float bFlashedAmt;
float flLastHighlightTime;
float flNameAlpha;
};
class SFHudReticle : public SFHudFlashInterface
{
enum
{
TEXTFIELD_LENGTH = 256
};
public:
enum RETICLE_MODE
{
RETICLE_MODE_NONE,
RETICLE_MODE_WEAPON,
RETICLE_MODE_OBSERVER
};
explicit SFHudReticle( const char *value );
virtual ~SFHudReticle();
void OnSwapReticle( SCALEFORM_CALLBACK_ARGS_DECL );
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual void FireGameEvent( IGameEvent *event );
void ToggleTeamEquipmentVisibility( bool bShow );
protected:
void ShowReticle( RETICLE_MODE mode, bool value );
bool SetReticlePosition( int distance, int crosshairGap , int offsetX, int offsetY, int nDesiredFishtail );
void LockSlot(bool wantItLocked, bool& currentlyLocked);
void ResetDisplay( void );
int TeamToTextIndex( int iTeamNumber );
// Swaps the current reticle assets
void PerformSwapReticle( const char * szReticleName );
void AddNewPlayerID( CBaseEntity *player, bool bShowName, bool bFriend = false );
void UpdatePlayerID( CBaseEntity *player, int slot, bool bHealthAndNameOnly = false );
void RemoveID( int index );
void RemoveAllIDs( void );
void GetIconHTML( const wchar_t * szIcon, wchar_t * szBuffer, int nBufferSize, bool bSelected );
bool ShouldShowAllFriendlyTargetIDs( void );
bool ShouldShowAllFriendlyEquipment( void );
protected:
wchar_t m_wcIDString[ TEXTFIELD_LENGTH ];
bool m_bCrosshairPositionsInitialized;
double m_TopPipY;
double m_BottomPipY;
double m_LeftPipX;
double m_RightPipX;
float m_dotX;
float m_dotY;
float m_blackRingX;
float m_blackRingY;
float m_friendIndicatorX;
float m_friendIndicatorY;
float m_IDMovieX;
float m_IDMovieY;
SFVALUE m_WeaponCrosshairHandle;
SFVALUE m_ObserverCrosshairHandle;
SFVALUE m_TopPip;
SFVALUE m_BottomPip;
SFVALUE m_LeftPip;
SFVALUE m_RightPip;
SFVALUE m_topCrosshairArc;
SFVALUE m_rightCrosshairArc;
SFVALUE m_leftCrosshairArc;
SFVALUE m_bottomCrosshairArc;
SFVALUE m_FriendCrosshair;
SFVALUE m_crosshairDot;
SFVALUE m_blackRing;
SFVALUE m_IDMovie;
SFVALUE m_IDText;
SFVALUE m_FlashedIcon;
RETICLE_MODE m_iReticleMode;
float m_fIDTimer;
int m_iLastGap;
int m_iLastSpread;
bool m_bTextIDVisible;
bool m_bFriendlyCrosshairVisible;
bool m_bEnemyCrosshairVisible;
bool m_bFlashedIconFadingOut;
bool m_bForceShowAllTeammateTargetIDs;
CUtlVector<PlayerIDPanel> m_playerIDs;
};
extern ConVar crosshair;
//extern ConVar sfcrosshair;
#endif /* SFHUDRETICLE_H_ */

View File

@@ -0,0 +1,202 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: [jpaquin] The "Player Two press start" widget
//
//=============================================================================//
#include "cbase.h"
#include "basepanel.h"
#include "scaleformui/scaleformui.h"
#include "iclientmode.h"
#include "clientmode_csnormal.h"
#include "sfhudflashinterface.h"
#include "vgui/ILocalize.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#if defined( _X360 )
#include "xbox/xbox_launch.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static const float UPDATE_INTERVAL = 60.0f;
class SFHudTrialTimer : public SFHudFlashInterface
{
public:
explicit SFHudTrialTimer( const char *value ) : SFHudFlashInterface( value ),
m_fNextUpdate( 0.0f ),
m_bVisible( false )
{
SetHiddenBits( /* HIDEHUD_MISCSTATUS */ 0 );
}
virtual ~SFHudTrialTimer()
{
}
void ProcessInput( void )
{
if ( FlashAPIIsValid() )
{
if ( m_fNextUpdate < gpGlobals->curtime )
{
m_fNextUpdate = gpGlobals->curtime + UPDATE_INTERVAL;
bool bUnlocked = false;
float timeLeft = 0;
#if defined( _X360 )
if ( xboxsystem )
{
bUnlocked = xboxsystem->IsArcadeTitleUnlocked();
if ( !bUnlocked )
{
timeLeft = xboxsystem->GetArcadeRemainingTrialTime( m_iFlashSlot - SF_FIRST_SS_SLOT );
}
}
#else
ConVarRef xbox_arcade_title_unlocked( "xbox_arcade_title_unlocked" );
ConVarRef xbox_arcade_remaining_trial_time( "xbox_arcade_remaining_trial_time" );
bUnlocked = xbox_arcade_title_unlocked.GetBool();
timeLeft = xbox_arcade_remaining_trial_time.GetFloat();
#endif
if ( !bUnlocked )
{
int minutesLeft = floorf( timeLeft / 60.0f );
minutesLeft = MAX( minutesLeft, 0 );
if ( minutesLeft == 1 )
{
WITH_SLOT_LOCKED
{
m_pTimerMessage->SetTextHTML( "#SFUI_TrialHudTextMinute" );
}
}
else
{
char strTrialTime[16];
Q_snprintf( strTrialTime, sizeof( strTrialTime ), "%d", minutesLeft );
wchar_t buffer[128];
wchar_t wTrialTime[16];
g_pVGuiLocalize->ConvertANSIToUnicode( strTrialTime, wTrialTime, sizeof( wTrialTime ) );
g_pVGuiLocalize->ConstructString( buffer, sizeof( buffer ), g_pVGuiLocalize->Find( "#SFUI_TrialHudTextMinutes" ), 1, wTrialTime );
WITH_SLOT_LOCKED
{
m_pTimerMessage->SetTextHTML( buffer );
}
}
}
}
}
}
void LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudTrialTimer, this, TrialTimer );
}
}
virtual void LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
virtual void SetActive( bool bActive )
{
ShowPanel( bActive, false );
CHudElement::SetActive( bActive );
}
virtual bool ShouldDraw( void )
{
bool result = cl_drawhud.GetBool();
#if defined( _X360 )
if ( result && xboxsystem )
{
result = !( xboxsystem->IsArcadeTitleUnlocked() );
}
#else
ConVarRef xbox_arcade_title_unlocked( "xbox_arcade_title_unlocked" );
result = result && !xbox_arcade_title_unlocked.GetBool();
#endif
return result && CHudElement::ShouldDraw();
}
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void )
{
SFVALUE panel = m_pScaleformUI->Value_GetMember( m_FlashAPI, "Panel" );
if ( panel != NULL )
{
m_pTimerMessage = m_pScaleformUI->TextObject_MakeTextObjectFromMember( panel, "AnimatedText" );
m_pScaleformUI->ReleaseValue( panel );
}
ShowPanel( m_bVisible, true );
}
virtual bool PreUnloadFlash( void )
{
SafeReleaseSFTextObject( m_pTimerMessage );
return SFHudFlashInterface::PreUnloadFlash();
}
protected:
void ShowPanel( bool bShow, bool force )
{
if ( ( bShow != m_bVisible ) || force )
{
m_bVisible = bShow;
if ( m_FlashAPI )
{
if ( m_bVisible )
{
m_fNextUpdate = 0.0f;
ProcessInput();
WITH_SLOT_LOCKED
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowPanel", NULL, 0 );
}
else
{
WITH_SLOT_LOCKED
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "HidePanel", NULL, 0 );
}
}
}
}
protected:
ISFTextObject* m_pTimerMessage;
float m_fNextUpdate;
bool m_bVisible;
};
DECLARE_HUDELEMENT( SFHudTrialTimer );
SFUI_BEGIN_GAME_API_DEF
SFUI_END_GAME_API_DEF( SFHudTrialTimer, TrialTimer );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SFHUDVOTEPANEL_H
#define SFHUDVOTEPANEL_H
#ifdef _WIN32
#pragma once
#endif //_WIN32
#include "sfhudflashinterface.h"
#define VOTE_PANEL_NAME_TRUNCATE_AT 16 // number of name character displayed before truncation
class SFHudVotePanel: public SFHudFlashInterface
{
public:
explicit SFHudVotePanel( const char *value );
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual void FireGameEvent( IGameEvent * event );
virtual void SetActive( bool bActive );
//void TimerCallback( SCALEFORM_CALLBACK_ARGS_DECL );
void VoteYes( SCALEFORM_CALLBACK_ARGS_DECL );
void VoteNo( SCALEFORM_CALLBACK_ARGS_DECL );
void UpdateYesNoButtonText( bool bShowOtherTeam = false );
void Hide( void );
virtual bool ShouldDraw( void );
bool MsgFunc_CallVoteFailed( const CCSUsrMsg_CallVoteFailed &msg );
bool MsgFunc_VoteStart( const CCSUsrMsg_VoteStart &msg );
bool MsgFunc_VotePass( const CCSUsrMsg_VotePass &msg );
bool MsgFunc_VoteFailed( const CCSUsrMsg_VoteFailed &msg );
bool MsgFunc_VoteSetup( const CCSUsrMsg_VoteSetup &msg );
void ShowVoteUI( wchar_t* headerText, wchar_t* voteText, bool bShowingOtherTeam = false );
void OnThink( void );
CUserMessageBinder m_UMCMsgCallVoteFailed;
CUserMessageBinder m_UMCMsgVoteStart;
CUserMessageBinder m_UMCMsgVotePass;
CUserMessageBinder m_UMCMsgVoteFailed;
CUserMessageBinder m_UMCMsgVoteSetup;
private:
void SetVoteActive( bool bActive );
SFVALUE m_hVoteButtonBG;
ISFTextObject* m_hVoteLocalCast;
ISFTextObject* m_option1Text;
ISFTextObject* m_option2Text;
ISFTextObject* m_option1CountText;
ISFTextObject* m_option2CountText;
CUtlStringList m_VoteSetupIssues;
CUtlStringList m_VoteSetupMapCycle;
CUtlStringList m_VoteSetupChoices;
bool m_bVoteActive;
float m_flVoteResultCycleTime; // what time will we cycle to the result
float m_flHideTime; // what time will we hide
bool m_bVotePassed; // what mode are we going to cycle to
int m_nVoteOptionCount[MAX_VOTE_OPTIONS]; // Vote options counter
int m_nPotentialVotes; // If set, draw a line at this point to show the required bar length
bool m_bIsYesNoVote;
int m_nVoteChoicesCount;
bool m_bPlayerVoted;
int m_bPlayerLocalVote;
float m_flPostVotedHideTime;
bool m_bVisible;
bool m_bHasFocus;
int m_nVoteYes;
int m_nVoteNo;
};
#endif // SFHUDVOTEPANEL_H

View File

@@ -0,0 +1,692 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD elements about health and armor
//
//=====================================================================================//
#include "cbase.h"
#include "hud.h"
#include "hudelement.h"
#include "hud_element_helper.h"
#include "iclientmode.h"
#include "view.h"
#include "vgui_controls/Controls.h"
#include "vgui/ISurface.h"
#include "ivrenderview.h"
#include "scaleformui/scaleformui.h"
#include "sfhudweaponpanel.h"
#include "vgui/ILocalize.h"
#include "c_cs_hostage.h"
#include "HUD/sfweaponselection.h"
#include "clientsteamcontext.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SAFECALL( handle, func ) \
if ( handle ) \
{ \
func \
}
DECLARE_HUDELEMENT( SFHudWeaponPanel );
SFUI_BEGIN_GAME_API_DEF
SFUI_END_GAME_API_DEF( SFHudWeaponPanel, WeaponModule ); // Asset named WeaponModule to maintain consistency with Flash file naming
extern ConVar cl_draw_only_deathnotices;
SFHudWeaponPanel::SFHudWeaponPanel( const char *value ) : SFHudFlashInterface( value ),
m_PanelHandle( NULL ),
m_CurrentWeaponImageHandle( NULL ),
m_CurrentWeaponTextHandle( NULL ),
m_AmmoTextClipHandle( NULL ),
m_AmmoTextTotalHandle( NULL ),
m_AmmoAnimationHandle( NULL ),
m_BurstIcons_Burst( NULL ),
m_BurstIcons_Single( NULL ),
m_WeaponPenetration1( NULL ),
m_WeaponPenetration2( NULL ),
m_WeaponPenetration3( NULL ),
m_UpgradeKill1( NULL ),
m_UpgradeKill2( NULL ),
m_UpgradeKillText( NULL ),
m_BombHandle( NULL ),
m_DefuseHandle( NULL ),
m_BombZoneHandle( NULL ),
m_WeaponItemName( NULL ),
m_PrevAmmoClipCount( -1 ),
m_PrevAmmoTotalCount( -1 ),
m_PrevAmmoType( -1 ),
m_PrevWeaponID( -1 ),
m_PrevTRGunGameUpgradePoints( 0 ),
m_bHiddenNoAmmo( false ),
m_bCarryingC4( false ),
m_bCarryingDefuse( false ),
m_bInBombZone( false ),
m_lastEntityIndex( 0 ),
m_LastNumRoundKills( 0 ),
m_lastKillEaterCount( 0 )
{
// TODO Auto-generated constructor stub
SetHiddenBits( HIDEHUD_WEAPONSELECTION );
}
SFHudWeaponPanel::~SFHudWeaponPanel()
{
// TODO Auto-generated destructor stub
}
void SFHudWeaponPanel::ShowPanel( bool value )
{
if ( !m_pScaleformUI )
return;
WITH_SLOT_LOCKED
{
if ( m_FlashAPI )
{
if ( value )
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showNow", NULL, 0 );
}
else
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideNow", NULL, 0 );
}
}
}
}
void SFHudWeaponPanel::SetVisible( bool bVisible )
{
if ( FlashAPIIsValid() )
{
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, bVisible );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setVisible", data, 1 );
}
}
}
void SFHudWeaponPanel::LockSlot( bool wantItLocked, bool& currentlyLocked )
{
if ( currentlyLocked != wantItLocked )
{
if ( wantItLocked )
{
LockScaleformSlot();
}
else
{
UnlockScaleformSlot();
}
currentlyLocked = wantItLocked;
}
}
void SFHudWeaponPanel::ProcessInput( void )
{
// Update stats
int currentClip = 0;
// we need the map clip to calculate the percentage of ammo left
// in the clip so the hud knows when to warn you
int maxClip = 0;
int totalAmmo = 0;
int ammoType = -1;
int weaponID = -1;
const char *weaponName = NULL;
const char *shortWeaponName = NULL;
bool bInTRBombMode = false;
bool bHideNoAmmo = false;
int CurrTRPoints = -1;
// Collect all player, weapon and game state data first:
if ( CSGameRules()->IsPlayingGunGame() )
{
if ( CSGameRules()->IsPlayingGunGameTRBomb() )
{
bInTRBombMode = true;
}
}
C_CSPlayer *pPlayer = GetHudPlayer();
CWeaponCSBase *pWeapon = NULL;
int entityIndex = pPlayer->entindex();
if ( pPlayer)
{
if ( CSGameRules()->IsBombDefuseMap() || CSGameRules()->IsHostageRescueMap() )
{
if ( m_bCarryingC4 != pPlayer->HasC4() )
{
m_bCarryingC4 = pPlayer->HasC4();
}
SFWeaponSelection *pHudWS = GET_HUDELEMENT( SFWeaponSelection );
if ( pHudWS )
{
static ConVarRef cl_hud_bomb_under_radar( "cl_hud_bomb_under_radar" );
bool bShowBomb = ( cl_hud_bomb_under_radar.GetInt( ) == 0 && m_bCarryingC4 );
//SAFECALL( m_BombHandle, m_pScaleformUI->Value_SetVisible( m_BombHandle, bShowBomb ); );
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 1 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, bShowBomb );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowBomb", args, 1 );
}
}
if ( m_bCarryingDefuse != pPlayer->HasDefuser() )
{
m_bCarryingDefuse = pPlayer->HasDefuser();
SAFECALL( m_DefuseHandle, m_pScaleformUI->Value_SetVisible( m_DefuseHandle, m_bCarryingDefuse ); );
}
if ( m_bInBombZone != pPlayer->m_bInBombZone )
{
m_bInBombZone = pPlayer->m_bInBombZone;
SAFECALL( m_BombZoneHandle, m_pScaleformUI->Value_SetVisible( m_BombZoneHandle, m_bInBombZone ); );
}
}
int nRoundKills = pPlayer->GetNumRoundKills();
int nRoundKillsHeadshots = pPlayer->GetNumRoundKillsHeadshots();
if( pPlayer->IsControllingBot() )
{
C_CSPlayer *controlledPlayerScorer = ToCSPlayer( UTIL_PlayerByIndex( pPlayer->GetControlledBotIndex() ) );
if( controlledPlayerScorer )
{
nRoundKills = controlledPlayerScorer->GetNumRoundKills();
nRoundKillsHeadshots = controlledPlayerScorer->GetNumRoundKillsHeadshots();
}
}
if ( m_LastNumRoundKills != nRoundKills )
{
int nCurIndex = pPlayer->GetPlayerGunGameWeaponIndex();
int nRequiredKills = 0;
if ( CSGameRules()->IsPlayingGunGameProgressive() )
nRequiredKills = CSGameRules()->GetGunGameNumKillsRequiredForWeapon( nCurIndex, pPlayer->GetTeamNumber() );
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 3 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, nRoundKills );
m_pScaleformUI->ValueArray_SetElement( args, 1, nRoundKillsHeadshots );
m_pScaleformUI->ValueArray_SetElement( args, 2, nRequiredKills );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setNumberKills", args, 3 );
}
m_LastNumRoundKills = nRoundKills;
}
if ( bInTRBombMode == true )
{
CurrTRPoints = pPlayer->GetNumGunGameTRKillPoints();
const int nUpgradedFlag = 99;
// We track "upgrade achieved" by saving the upgrade points as 99 - which means it will
// always differ from the actual kill points once we've already upgraded. So, we don't
// want to push another change to the panel until our points get reset at the next round
bool bAlreadyUpgraded = ( m_PrevTRGunGameUpgradePoints == nUpgradedFlag );
bool bZeroed = ( CurrTRPoints == 0 );
if ( ( m_PrevTRGunGameUpgradePoints != CurrTRPoints ) && ( !bAlreadyUpgraded || bZeroed ) )
{
// disable the little kill flags now because with the NEXT WEAPON panel serves this purpose and the flags cause confusion
// TODO: find a way to bring the kill flags back some way because they add a lot of value
/*
switch( CurrTRPoints )
{
case 0:
SAFECALL( m_UpgradeKill1, m_pScaleformUI->Value_SetVisible( m_UpgradeKill1, false); );
SAFECALL( m_UpgradeKill2, m_pScaleformUI->Value_SetVisible( m_UpgradeKill2, false); );
SAFECALL( m_UpgradeKillText, m_pScaleformUI->Value_SetVisible( m_UpgradeKillText, false ); );
break;
case 1:
SAFECALL( m_UpgradeKill1, m_pScaleformUI->Value_SetVisible( m_UpgradeKill1, true); );
break;
case 2:
SAFECALL( m_UpgradeKill2, m_pScaleformUI->Value_SetVisible( m_UpgradeKill2, true); );
break;
default:
break;
}
*/
static ConVarRef mp_ggtr_bomb_pts_for_upgrade( "mp_ggtr_bomb_pts_for_upgrade" );
if ( CurrTRPoints >= mp_ggtr_bomb_pts_for_upgrade.GetInt() )
{
// disable the little kill flags now because with the NEXT WEAPON panel serves this purpose and the flags cause confusion
// TODO: find a way to bring the kill flags back some way because they add a lot of value
/*
SAFECALL( m_UpgradeKillText, m_pScaleformUI->Value_SetVisible( m_UpgradeKillText, true); );
WITH_SLOT_LOCKED
{
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "playUpgradeAnim", NULL, 0 );
}
*/
m_PrevTRGunGameUpgradePoints = nUpgradedFlag;
}
else
{
m_PrevTRGunGameUpgradePoints = CurrTRPoints;
}
}
}
pWeapon = pPlayer ? (CWeaponCSBase*)pPlayer->GetActiveWeapon() : NULL;
if ( pWeapon )
{
weaponName = pWeapon->GetPrintName();
shortWeaponName = pWeapon->GetName();
// remap weaponID to our ammo numbering (defined in the action script for this hud element) - currently, just bullets vs grenades
// $TODO: are we going to reflect any other ammo types, like XBLA did?
weaponID = pWeapon->GetCSWeaponID();
switch ( weaponID )
{
case WEAPON_DECOY: // $FIXME: prototype grenades just display with the flashbang ammo
case WEAPON_MOLOTOV:
case WEAPON_INCGRENADE:
case WEAPON_FLASHBANG:
case WEAPON_TAGRENADE:
ammoType = 1;
break;
case WEAPON_HEGRENADE:
ammoType = 2;
break;
case WEAPON_SMOKEGRENADE:
ammoType = 3;
break;
case WEAPON_HEALTHSHOT:
ammoType = 10;
break;
default:
ammoType = 0;
break;
}
// determine what to display for ammo: "clip/total", "total" or nothing (for knife, c4, etc)
if ( !pWeapon->UsesPrimaryAmmo() )
{
currentClip = -1;
maxClip = -1;
totalAmmo = -1;
}
else
{
currentClip = pWeapon->Clip1();
maxClip = pWeapon->GetMaxClip1();
if ( currentClip < 0 )
{
// we don't use clip ammo, just use the total ammo count
currentClip = pWeapon->GetReserveAmmoCount( AMMO_POSITION_PRIMARY );
totalAmmo = -1;
}
else
{
// we use clip ammo, so the second ammo is the total ammo
totalAmmo = pWeapon->GetReserveAmmoCount( AMMO_POSITION_PRIMARY );
;
}
}
}
}
// Updating flash, slot locking begins...
bool bSlotIsLocked = false;
char cNewStr[ 128 ];
// Update weapon image and text
if ( m_PrevWeaponID != weaponID )
{
LockSlot( true, bSlotIsLocked );
if ( weaponName )
{
SAFECALL( m_CurrentWeaponTextHandle, m_pScaleformUI->Value_SetText( m_CurrentWeaponTextHandle, weaponName ); );
}
// Update the selected weapon image as well
if ( FlashAPIIsValid() && shortWeaponName )
{
WITH_SFVALUEARRAY( data, 1 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, shortWeaponName );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "switchWeaponName", data, 1 );
}
}
// CCSWeaponInfo const * pWeaponInfo = GetWeaponInfo( static_cast<CSWeaponID>( weaponID ) );
CEconItemView *pItem = pWeapon ? pWeapon->GetEconItemView() : NULL;
// if ( pWeaponInfo )
// {
// SAFECALL( m_WeaponPenetration1, m_pScaleformUI->Value_SetVisible( m_WeaponPenetration1, pWeaponInfo->GetAttributeFloat( "penetration", pItem ) == 1 ? true : false ); );
// SAFECALL( m_WeaponPenetration2, m_pScaleformUI->Value_SetVisible( m_WeaponPenetration2, pWeaponInfo->GetAttributeFloat( "penetration", pItem ) == 2 ? true : false ); );
// SAFECALL( m_WeaponPenetration3, m_pScaleformUI->Value_SetVisible( m_WeaponPenetration3, pWeaponInfo->GetAttributeFloat( "penetration", pItem ) == 3 ? true : false ); );
// }
// update the weapon name
if ( pWeapon )
{
if ( !pItem || !pItem->IsValid() || pItem->GetItemID() <= 0 || !GetItemSchema() || !GetItemSchema()->GetRarityDefinition( pItem->GetRarity() ) )
{
SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetVisible( m_WeaponItemName, false ); );
}
else
{
const CEconItemRarityDefinition* pRarity = GetItemSchema()->GetRarityDefinition( pItem->GetRarity() );
SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetVisible( m_WeaponItemName, true ); );
const int kColorBufSize = 128;
wchar_t rwchColor[kColorBufSize];
Q_UTF8ToUnicode( GetHexColorForAttribColor( pRarity->GetAttribColor() ), rwchColor, kColorBufSize );
// Update target name
wchar_t wcTargetWeaponFormatted[128];
V_snwprintf( wcTargetWeaponFormatted, ARRAYSIZE( wcTargetWeaponFormatted ), L"<font color=\"" PRI_WS_FOR_WS L"\">" PRI_WS_FOR_WS L"</font>", rwchColor, pItem->GetItemName() );
SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetTextHTML( m_WeaponItemName, wcTargetWeaponFormatted ); );
}
}
}
// Determine if this weapon has no ammo at all, so the panel should be hidden
bHideNoAmmo = (( totalAmmo < 0 ) && ( currentClip < 0 )) || !pWeapon;
if ( ( bInTRBombMode && CurrTRPoints > 0 ) ||
m_bCarryingC4 || m_bCarryingDefuse || m_bInBombZone || weaponID == WEAPON_KNIFE )
{
// Ensure we still show this when in TR Bomb AND we have kill points to display
// or if we have bomb/defuse kit or are in the bomb zone
bHideNoAmmo = false;
}
// Update ammo type/count/animating bullets elements
if (
( totalAmmo != m_PrevAmmoTotalCount ) ||
( currentClip != m_PrevAmmoClipCount ) ||
( weaponID != m_PrevWeaponID ) )
{
LockSlot( true, bSlotIsLocked );
// Display current weapon ammunition (or lack thereof)
bool bAmmoShown = true;
if ( totalAmmo < 0 )
{
// doesn't use ammo at all (knife, c4, etc)
cNewStr[0] = 0;
bAmmoShown = false;
}
else
{
V_snprintf( cNewStr, sizeof( cNewStr ), "%d", currentClip );
}
if ( bAmmoShown )
{
SAFECALL( m_AmmoTextClipHandle, m_pScaleformUI->Value_SetText( m_AmmoTextClipHandle, cNewStr ); );
V_snprintf( cNewStr, sizeof( cNewStr ), "/ %d", totalAmmo );
SAFECALL( m_AmmoTextTotalHandle, m_pScaleformUI->Value_SetText( m_AmmoTextTotalHandle, cNewStr ); );
}
SAFECALL( m_AmmoTextClipHandle, m_pScaleformUI->Value_SetVisible( m_AmmoTextClipHandle, bAmmoShown ); );
SAFECALL( m_AmmoTextTotalHandle, m_pScaleformUI->Value_SetVisible( m_AmmoTextTotalHandle, bAmmoShown ); );
}
bool bShowBurstBurst = (pWeapon && pWeapon->WeaponHasBurst() && pWeapon->IsInBurstMode());
bool bShowBurstSingle = (pWeapon && pWeapon->WeaponHasBurst() && !pWeapon->IsInBurstMode());
SAFECALL( m_BurstIcons_Burst, m_pScaleformUI->Value_SetVisible( m_BurstIcons_Burst, bShowBurstBurst ); );
SAFECALL( m_BurstIcons_Single, m_pScaleformUI->Value_SetVisible( m_BurstIcons_Single, bShowBurstSingle ); );
// Show the appropriate ammo for our weapon type
if ( ( m_PrevAmmoType != ammoType ) ||
( m_PrevAmmoClipCount != currentClip ) || (ammoType != 0 && weaponID != m_PrevWeaponID) )
{
if ( m_FlashAPI )
{
LockSlot( true, bSlotIsLocked );
WITH_SFVALUEARRAY( data, 4 )
{
m_pScaleformUI->ValueArray_SetElement( data, 0, ammoType );
m_pScaleformUI->ValueArray_SetElement( data, 1, currentClip );
m_pScaleformUI->ValueArray_SetElement( data, 2, maxClip );
m_pScaleformUI->ValueArray_SetElement( data, 3, shortWeaponName );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "updateAmmo", data, 4 );
}
}
}
// Notify the HUD when we fire - detected by not changing weapon/observed player, and our ammo count decreases
if ( entityIndex == m_lastEntityIndex && m_PrevWeaponID == weaponID && (ammoType == 0) && m_PrevAmmoClipCount > 0 && currentClip < m_PrevAmmoClipCount )
{
if ( m_FlashAPI )
{
LockSlot( true, bSlotIsLocked );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "weaponFired", NULL, 0 );
}
}
// Update previous state so we know which elements need to be refreshed next time
m_PrevAmmoClipCount = currentClip;
m_PrevAmmoTotalCount = totalAmmo;
m_PrevAmmoType = ammoType;
m_PrevWeaponID = weaponID;
m_lastEntityIndex = entityIndex;
LockSlot( false, bSlotIsLocked );
// Now determine if the panel should be entirely hidden, because our current weapon uses no ammo
if ( bHideNoAmmo != m_bHiddenNoAmmo )
{
if ( m_bActive )
{
ShowPanel( !bHideNoAmmo );
}
m_bHiddenNoAmmo = bHideNoAmmo;
}
}
void SFHudWeaponPanel::FireGameEvent( IGameEvent *event )
{
const char *type = event->GetName();
C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
if ( !pLocalPlayer )
return;
int nPlayerUserID = pLocalPlayer->GetUserID();
int nEventUserID = event->GetInt( "userid" );
if ( StringHasPrefix( type, "round_start" ) ||
( StringHasPrefix( type, "player_death" ) && nPlayerUserID == nEventUserID ) ||
( StringHasPrefix( type, "bot_takeover" ) && nEventUserID == nPlayerUserID ) )
{
// reset these when the reound restarts of if the player dies
m_bCarryingC4 = false;
m_bCarryingDefuse = false;
SAFECALL( m_BombHandle, m_pScaleformUI->Value_SetVisible( m_BombHandle, false ); );
SAFECALL( m_DefuseHandle, m_pScaleformUI->Value_SetVisible( m_DefuseHandle, false ); );
if ( ( StringHasPrefix( type, "player_death" ) && !CSGameRules()->IsWarmupPeriod() ) )
{
int nCurIndex = pLocalPlayer->GetPlayerGunGameWeaponIndex();
int nRequiredKills = 0;
if ( CSGameRules()->IsPlayingGunGameProgressive() )
nRequiredKills = CSGameRules()->GetGunGameNumKillsRequiredForWeapon( nCurIndex, pLocalPlayer->GetTeamNumber() );
WITH_SFVALUEARRAY_SLOT_LOCKED( args, 3 )
{
m_pScaleformUI->ValueArray_SetElement( args, 0, 0 );
m_pScaleformUI->ValueArray_SetElement( args, 1, 0 );
m_pScaleformUI->ValueArray_SetElement( args, 2, nRequiredKills );
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "setNumberKills", args, 3 );
}
}
if ( CSGameRules()->IsPlayingGunGameProgressive() )
{
m_LastNumRoundKills = -1;
}
}
}
static void GetTextBoxForElement( IScaleformUI *pScaleformUI, SFVALUE root, const char *elementName, const char *textElementName, SFVALUE &sfv )
{
SFVALUE TempHandle = pScaleformUI->Value_GetMember( root, elementName );
if ( TempHandle )
{
sfv = pScaleformUI->Value_GetMember( TempHandle, textElementName );
pScaleformUI->ReleaseValue( TempHandle );
}
}
void SFHudWeaponPanel::FlashReady( void )
{
m_PanelHandle = m_pScaleformUI->Value_GetMember( m_FlashAPI, "HudPanel" );
if ( m_PanelHandle )
{
SFVALUE AnimatedPanelHandle = m_pScaleformUI->Value_GetMember( m_PanelHandle, "WeaponPanel" );
if ( AnimatedPanelHandle )
{
m_CurrentWeaponImageHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "CurrentWeapon" );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "WeaponText", "TextBox", m_CurrentWeaponTextHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "AmmoCountClip", "TextBox", m_AmmoTextClipHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "AmmoCountTotal", "TextBox", m_AmmoTextTotalHandle );
GetTextBoxForElement( m_pScaleformUI, AnimatedPanelHandle, "WeaponName", "TextBox", m_WeaponItemName );
m_AmmoAnimationHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "AmmoAnim" );
m_BurstIcons_Burst = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "BurstTypeBurst" );
m_BurstIcons_Single = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "BurstTypeSingle" );
m_WeaponPenetration1 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Penetration1" );
m_WeaponPenetration2 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Penetration2" );
m_WeaponPenetration3 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Penetration3" );
m_UpgradeKill1 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Kill1" );
m_UpgradeKill2 = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "Kill2" );
m_UpgradeKillText = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "UpgradeText" );
m_BombHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "BombCarrierIcon" );
m_DefuseHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "DefuseKitIcon" );
m_BombZoneHandle = m_pScaleformUI->Value_GetMember( AnimatedPanelHandle, "InBombZoneIcon" );
SAFECALL( m_UpgradeKill1, m_pScaleformUI->Value_SetVisible( m_UpgradeKill1, false); );
SAFECALL( m_UpgradeKill2, m_pScaleformUI->Value_SetVisible( m_UpgradeKill2, false); );
SAFECALL( m_UpgradeKillText, m_pScaleformUI->Value_SetVisible( m_UpgradeKillText, false); );
SAFECALL( m_BombHandle, m_pScaleformUI->Value_SetVisible( m_BombHandle, false ); );
SAFECALL( m_DefuseHandle, m_pScaleformUI->Value_SetVisible( m_DefuseHandle, false ); );
SAFECALL( m_BombZoneHandle, m_pScaleformUI->Value_SetVisible( m_BombZoneHandle, false ); );
SAFECALL( m_WeaponItemName, m_pScaleformUI->Value_SetVisible( m_WeaponItemName, false ); );
m_pScaleformUI->ReleaseValue( AnimatedPanelHandle );
}
}
if ( m_FlashAPI && m_pScaleformUI )
{
ListenForGameEvent( "round_start" );
ListenForGameEvent( "player_death" );
ListenForGameEvent( "bot_takeover" );
}
// hide everything initially
SetVisible( false );
}
bool SFHudWeaponPanel::PreUnloadFlash( void )
{
SafeReleaseSFVALUE( m_PanelHandle );
SafeReleaseSFVALUE( m_CurrentWeaponImageHandle );
SafeReleaseSFVALUE( m_CurrentWeaponTextHandle );
SafeReleaseSFVALUE( m_AmmoTextClipHandle );
SafeReleaseSFVALUE( m_AmmoTextTotalHandle );
SafeReleaseSFVALUE( m_AmmoAnimationHandle );
SafeReleaseSFVALUE( m_BurstIcons_Burst );
SafeReleaseSFVALUE( m_BurstIcons_Single );
SafeReleaseSFVALUE( m_WeaponPenetration1 );
SafeReleaseSFVALUE( m_WeaponPenetration2 );
SafeReleaseSFVALUE( m_WeaponPenetration3 );
SafeReleaseSFVALUE( m_UpgradeKill1 );
SafeReleaseSFVALUE( m_UpgradeKill2 );
SafeReleaseSFVALUE( m_UpgradeKillText );
SafeReleaseSFVALUE( m_BombHandle );
SafeReleaseSFVALUE( m_DefuseHandle );
SafeReleaseSFVALUE( m_BombZoneHandle );
SafeReleaseSFVALUE( m_WeaponItemName );
return true;
}
void SFHudWeaponPanel::LevelInit( void )
{
if ( !FlashAPIIsValid() )
{
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudWeaponPanel, this, WeaponModule );
}
else
{
// When initially loaded, hide this panel
SetVisible( false );
}
// Reset all transient data
m_PrevAmmoClipCount = -1;
m_PrevAmmoTotalCount = -1;
m_PrevAmmoType = -1;
m_PrevWeaponID = -1;
m_PrevTRGunGameUpgradePoints = 0;
m_bHiddenNoAmmo = false;
}
void SFHudWeaponPanel::LevelShutdown( void )
{
if ( FlashAPIIsValid() )
{
RemoveFlashElement();
}
}
bool SFHudWeaponPanel::ShouldDraw( void )
{
return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
}
void SFHudWeaponPanel::SetActive( bool bActive )
{
// Do not show the panel if we have hidden it because of an ammo-less weapon
if ( bActive != m_bActive && !m_bHiddenNoAmmo )
{
ShowPanel( bActive );
}
CHudElement::SetActive( bActive );
}

View File

@@ -0,0 +1,79 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Displays HUD elements about health and armor
//
//=====================================================================================//
#ifndef SFHUDWEAPONPANEL_H_
#define SFHUDWEAPONPANEL_H_
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
class SFHudWeaponPanel : public SFHudFlashInterface
{
public:
explicit SFHudWeaponPanel( const char *value );
virtual ~SFHudWeaponPanel();
// These overload the CHudElement class
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
virtual void Init( void ) { SetVisible( true ); }
virtual void Reset( void ) { SetVisible( true ); }
// these overload the ScaleformFlashInterfaceMixin class
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual void FireGameEvent( IGameEvent *event );
protected:
void ShowPanel( bool value );
void SetVisible( bool bVisible );
void LockSlot( bool wantItLocked, bool& currentlyLocked );
protected:
SFVALUE m_PanelHandle;
SFVALUE m_CurrentWeaponImageHandle;
SFVALUE m_CurrentWeaponTextHandle;
SFVALUE m_AmmoTextClipHandle;
SFVALUE m_AmmoTextTotalHandle;
SFVALUE m_AmmoAnimationHandle;
SFVALUE m_BurstIcons_Burst;
SFVALUE m_BurstIcons_Single;
SFVALUE m_WeaponPenetration1;
SFVALUE m_WeaponPenetration2;
SFVALUE m_WeaponPenetration3;
SFVALUE m_UpgradeKill1;
SFVALUE m_UpgradeKill2;
SFVALUE m_UpgradeKillText;
SFVALUE m_BombHandle;
SFVALUE m_DefuseHandle;
SFVALUE m_BombZoneHandle;
SFVALUE m_WeaponItemName;
int m_PrevAmmoClipCount;
int m_PrevAmmoTotalCount;
int m_PrevAmmoType;
int m_PrevWeaponID;
int m_PrevTRGunGameUpgradePoints;
bool m_bHiddenNoAmmo; // we hid the panel because our current weapon has no ammo at all
bool m_bCarryingC4; // player is carrying the bomb
bool m_bCarryingDefuse; // player is carrying a defuse kit
bool m_bInBombZone ; // player is in the bomb zone
int m_lastEntityIndex;
int m_LastNumRoundKills;
int m_lastKillEaterCount;
};
#endif /* SFHUDWEAPONPANEL_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,111 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SFHUDWINPANEL_H
#define SFHUDWINPANEL_H
#pragma once
#include "hudelement.h"
#include "ehandle.h"
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include "weapon_csbase.h"
#include "takedamageinfo.h"
#include "weapon_csbase.h"
#include "ammodef.h"
#include <vgui_controls/Panel.h>
enum
{
WIN_EXTRATYPE_NONE = 0,
WIN_EXTRATYPE_AWARD,
WIN_EXTRATYPE_RANK,
WIN_EXTRATYPE_ELO,
WIN_EXTRATYPE_GGNEXT,
WIN_EXTRATYPE_SEASONRANK,
};
//-----------------------------------------------------------------------------
// Purpose: Used to draw the history of weapon / item pickups and purchases by the player
//-----------------------------------------------------------------------------
class SFHudWinPanel: public SFHudFlashInterface, public IShaderDeviceDependentObject
{
public:
explicit SFHudWinPanel( const char *value );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
virtual void ProcessInput( void );
virtual void FireGameEvent( IGameEvent * event );
virtual bool ShouldDraw( void );
// Offsets the Y location of the win panel
void ApplyYOffset( int nOffset );
bool IsVisible( void );
// IShaderDeviceDependentObject methods
virtual void DeviceLost( void ) { }
virtual void DeviceReset( void *pDevice, void *pPresentParameters, void *pHWnd );
virtual void ScreenSizeChanged( int width, int height ) { }
int m_iMVP;
protected:
void SetMVP( C_CSPlayer* pPlayer, CSMvpReason_t reason, int32 nMusicKitMVPs = 0 );
void SetFunFactLabel( const wchar *szFunFact );
void SetProgressBarText( int nAmount, const wchar *wszDescText );
//void MovieClipSetVisibility( SFVALUE panel, bool bShow );
//void TextPanelSetVisibility( ISFTextObject* panel, bool bShow );
private:
void ShowTeamWinPanel( int result, const char* winnerText );
void ShowGunGameWinPanel( void /*int nWinner, int nSecond, int nThird*/ );
void ShowWinExtraDataPanel( int nExtraPanelType );
void SetWinPanelExtraData( void );
void Hide( void );
SFVALUE m_hWinPanelParent;
ISFTextObject* m_hWinner;
ISFTextObject* m_hReason;
ISFTextObject* m_hMVP;
ISFTextObject* m_hSurrender;
ISFTextObject* m_hFunFact;
SFVALUE m_hEloPanel;
SFVALUE m_hRankPanel;
SFVALUE m_hItemPanel;
SFVALUE m_hMedalPanel;
SFVALUE m_hProgressText;
SFVALUE m_hNextWeaponPanel;
bool m_bVisible;
int m_nFunFactPlayer;
string_t m_nFunfactToken;
int m_nFunFactParam1;
int m_nFunFactParam2;
int m_nFunFactParam3;
int m_nRoundStartELO;
bool m_bShouldSetWinPanelExtraData;
float m_fSetWinPanelExtraDataTime;
};
#endif // SFHUDWINPANEL_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef SFWEAPONSELECTION_H
#define SFWEAPONSELECTION_H
#pragma once
#include "hudelement.h"
#include "ehandle.h"
#include "hud.h"
#include "hud_element_helper.h"
#include "scaleformui/scaleformui.h"
#include "sfhudflashinterface.h"
#include "cs_gamerules.h"
#include "c_cs_player.h"
#include "weapon_csbase.h"
#include "takedamageinfo.h"
#include "weapon_csbase.h"
#include "ammodef.h"
#include <vgui_controls/Panel.h>
#include "cs_hud_weaponselection.h"
#define MAX_WEP_SELECT_PANELS 5
#define MAX_WEP_SELECT_POSITIONS 6 // if we limit the grenades to three, this will go down
#define WEAPON_SELECTION_FADE_TIME_SEC 1.25
#define WEAPON_SELECTION_FADE_SPEED 100.0 / WEAPON_SELECTION_FADE_TIME_SEC
#define WEAPON_SELECTION_FADE_DELAY 1.5
#define WEAPON_SELECT_PANEL_HEIGHT 65
struct WeaponSelectPanel
{
SFVALUE handle;
double alpha;
EHANDLE hWeapon;
bool bSelected;
bool bJustPickedUp;
float fEndBlinkTime;
float fLastBlinkTime;
};
//-----------------------------------------------------------------------------
// Purpose: Used to draw the history of weapon / item pickups and purchases by the player
//-----------------------------------------------------------------------------
class SFWeaponSelection : public SFHudFlashInterface
{
public:
explicit SFWeaponSelection( const char *value );
C_CSPlayer* GetLocalOrHudPlayer( void );
void AddWeapon( C_BaseCombatWeapon *pWeapon, bool bSelected );
void UpdateGGNextPanel( bool bForceShowForTRBomb = false, bool bKnifeReached = false );
void HideWeapon( int nSlot, int nPos );
void RemoveWeapon( int nSlot, int nPos );
WeaponSelectPanel CreateNewPanel( C_BaseCombatWeapon *pWeapon = NULL, bool bSelected = false );
void CreateGGNextPanel( void );
void ShowAndUpdateSelection( int nType = WEPSELECT_SWITCH, C_BaseCombatWeapon *pWeapon = NULL, bool bGiveInitial = false );
void UpdatePanelPositions( void );
void DisplayLevelUpNextWeapon( void );
void RemoveItem( int nSlot, int nPos );
void RemoveAllItems( void );
virtual void ProcessInput( void );
virtual void LevelInit( void );
virtual void LevelShutdown( void );
virtual void SetActive( bool bActive );
virtual bool ShouldDraw( void );
void SetAlwaysShow( bool bAlwaysShow );
bool IsC4Visible( void ) { return m_bC4IsVisible; }
virtual void FlashReady( void );
virtual bool PreUnloadFlash( void );
// CGameEventListener methods
virtual void FireGameEvent( IGameEvent *event );
protected:
// Calls either Show or Hide
void ShowPanel( const bool bShow );
// Show the item history
void Show( void );
// Hide the item history
void Hide( void );
virtual C_WeaponCSBase *GetSelectedWeapon( void )
{
return dynamic_cast<C_WeaponCSBase*>(m_hSelectedWeapon.Get());
}
private:
SFVALUE m_anchorPanel;
float m_lastUpdate;
float m_flFadeStartTime;
//CUtlVector<WeaponSelectPanel> m_weaponPanels;
WeaponSelectPanel m_weaponPanels[MAX_WEP_SELECT_PANELS][MAX_WEP_SELECT_POSITIONS];
bool m_bVisible; // Element visibility flag
CHandle< C_BaseCombatWeapon > m_hSelectedWeapon;
WeaponSelectPanel m_selectedPanel;
bool m_bCreatedNextPanel;
WeaponSelectPanel m_ggNextPanel;
int m_nPrevWepAlignSlot;
int m_nPrevOccupiedWepSlot;
int m_nOrigXPos;
int m_nOrigYPos;
bool m_bInitPos;
bool m_bInitialized;
bool m_bAlwaysShow; // When true, will not fade out
bool m_bC4IsVisible;
int m_nLastTRKills;
int m_nLastGGWepIndex;
bool m_bUpdateGGNextPanel;
float m_flUpdateInventoryAt;
bool m_bUpdateInventoryReset;
int m_bSpectatorTargetIndex;
};
#endif // SFWEAPONSELECTION_H