mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-06-07 11:22:12 +03:00
game_menu entity and associated CHudMenu changes
This commit is contained in:
parent
985ebc0dbb
commit
cdafc1278e
@ -37,6 +37,9 @@ char g_szPrelocalisedMenuString[MAX_MENU_STRING];
|
|||||||
|
|
||||||
DECLARE_HUDELEMENT( CHudMenu );
|
DECLARE_HUDELEMENT( CHudMenu );
|
||||||
DECLARE_HUD_MESSAGE( CHudMenu, ShowMenu );
|
DECLARE_HUD_MESSAGE( CHudMenu, ShowMenu );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
DECLARE_HUD_MESSAGE( CHudMenu, ShowMenuComplex );
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
@ -71,6 +74,9 @@ CHudMenu::CHudMenu( const char *pElementName ) :
|
|||||||
void CHudMenu::Init( void )
|
void CHudMenu::Init( void )
|
||||||
{
|
{
|
||||||
HOOK_HUD_MESSAGE( CHudMenu, ShowMenu );
|
HOOK_HUD_MESSAGE( CHudMenu, ShowMenu );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
HOOK_HUD_MESSAGE( CHudMenu, ShowMenuComplex );
|
||||||
|
#endif
|
||||||
|
|
||||||
m_bMenuTakesInput = false;
|
m_bMenuTakesInput = false;
|
||||||
m_bMenuDisplayed = false;
|
m_bMenuDisplayed = false;
|
||||||
@ -81,6 +87,24 @@ void CHudMenu::Init( void )
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudMenu::LevelInit()
|
||||||
|
{
|
||||||
|
CHudElement::LevelInit();
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if (m_bMapDefinedMenu)
|
||||||
|
{
|
||||||
|
// Fixes menu retaining on level change/reload
|
||||||
|
// TODO: Would non-map menus benefit from this as well?
|
||||||
|
m_bMenuTakesInput = false;
|
||||||
|
m_bMenuDisplayed = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose:
|
// Purpose:
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -114,7 +138,11 @@ void CHudMenu::OnThink()
|
|||||||
float flSelectionTimeout = MENU_SELECTION_TIMEOUT;
|
float flSelectionTimeout = MENU_SELECTION_TIMEOUT;
|
||||||
|
|
||||||
// If we've been open for a while without input, hide
|
// If we've been open for a while without input, hide
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( m_bMenuDisplayed && ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout && !m_bMapDefinedMenu ) )
|
||||||
|
#else
|
||||||
if ( m_bMenuDisplayed && ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout ) )
|
if ( m_bMenuDisplayed && ( gpGlobals->curtime - m_flSelectionTime > flSelectionTimeout ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
m_bMenuDisplayed = false;
|
m_bMenuDisplayed = false;
|
||||||
}
|
}
|
||||||
@ -130,11 +158,24 @@ bool CHudMenu::ShouldDraw( void )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check for if menu is set to disappear
|
// check for if menu is set to disappear
|
||||||
if ( m_flShutoffTime > 0 && m_flShutoffTime <= gpGlobals->realtime )
|
if ( m_flShutoffTime > 0 )
|
||||||
{
|
{
|
||||||
// times up, shutoff
|
#ifdef MAPBASE
|
||||||
m_bMenuDisplayed = false;
|
if ( m_bMapDefinedMenu && !m_bPlayingFadeout && (m_flShutoffTime - m_flOpenCloseTime) <= GetMenuTime() )
|
||||||
return false;
|
{
|
||||||
|
// Begin closing the menu
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( "MenuClose" );
|
||||||
|
m_bMenuTakesInput = false;
|
||||||
|
m_bPlayingFadeout = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if ( m_flShutoffTime <= GetMenuTime() )
|
||||||
|
{
|
||||||
|
// times up, shutoff
|
||||||
|
m_bMenuDisplayed = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return draw;
|
return draw;
|
||||||
@ -169,23 +210,21 @@ void CHudMenu::Paint()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// center it
|
// center it
|
||||||
int x = 20;
|
int x = m_nBorder;
|
||||||
|
|
||||||
Color menuColor = m_MenuColor;
|
Color menuColor = m_MenuColor;
|
||||||
Color itemColor = m_ItemColor;
|
Color itemColor = m_ItemColor;
|
||||||
|
|
||||||
int c = m_Processed.Count();
|
int c = m_Processed.Count();
|
||||||
|
|
||||||
int border = 20;
|
int wide = m_nMaxPixels + m_nBorder;
|
||||||
|
int tall = m_nHeight + m_nBorder;
|
||||||
int wide = m_nMaxPixels + border;
|
|
||||||
int tall = m_nHeight + border;
|
|
||||||
|
|
||||||
int y = ( ScreenHeight() - tall ) * 0.5f;
|
int y = ( ScreenHeight() - tall ) * 0.5f;
|
||||||
|
|
||||||
DrawBox( x - border/2, y - border/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
DrawBox( x - m_nBorder/2, y - m_nBorder/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
||||||
|
|
||||||
//DrawTexturedBox( x - border/2, y - border/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
//DrawTexturedBox( x - m_nBorder/2, y - m_nBorder/2, wide, tall, m_BoxColor, m_flSelectionAlphaOverride / 255.0f );
|
||||||
|
|
||||||
menuColor[3] = menuColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
menuColor[3] = menuColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
||||||
itemColor[3] = itemColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
itemColor[3] = itemColor[3] * ( m_flSelectionAlphaOverride / 255.0f );
|
||||||
@ -195,7 +234,18 @@ void CHudMenu::Paint()
|
|||||||
ProcessedLine *line = &m_Processed[ i ];
|
ProcessedLine *line = &m_Processed[ i ];
|
||||||
Assert( line );
|
Assert( line );
|
||||||
|
|
||||||
Color clr = line->menuitem != 0 ? itemColor : menuColor;
|
#ifdef MAPBASE
|
||||||
|
bool isItem = true;
|
||||||
|
if (line->menuitem == 0 && line->startchar < (MAX_MENU_STRING-1) && g_szMenuString[ line->startchar ] != L'0' && g_szMenuString[ line->startchar+1 ] != L'.')
|
||||||
|
{
|
||||||
|
// Can't use 0 directly because it gets conflated with the cancel item
|
||||||
|
isItem = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool isItem = line->menuitem != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Color clr = isItem ? itemColor : menuColor;
|
||||||
|
|
||||||
bool canblur = false;
|
bool canblur = false;
|
||||||
if ( line->menuitem != 0 &&
|
if ( line->menuitem != 0 &&
|
||||||
@ -208,15 +258,15 @@ void CHudMenu::Paint()
|
|||||||
vgui::surface()->DrawSetTextColor( clr );
|
vgui::surface()->DrawSetTextColor( clr );
|
||||||
|
|
||||||
int drawLen = line->length;
|
int drawLen = line->length;
|
||||||
if ( line->menuitem != 0 )
|
if (isItem)
|
||||||
{
|
{
|
||||||
drawLen *= m_flTextScan;
|
drawLen *= m_flTextScan;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgui::surface()->DrawSetTextFont( line->menuitem != 0 ? m_hItemFont : m_hTextFont );
|
vgui::surface()->DrawSetTextFont( isItem ? m_hItemFont : m_hTextFont );
|
||||||
|
|
||||||
PaintString( &g_szMenuString[ line->startchar ], drawLen,
|
PaintString( &g_szMenuString[ line->startchar ], drawLen,
|
||||||
line->menuitem != 0 ? m_hItemFont : m_hTextFont, x, y );
|
isItem ? m_hItemFont : m_hTextFont, x, y );
|
||||||
|
|
||||||
if ( canblur )
|
if ( canblur )
|
||||||
{
|
{
|
||||||
@ -242,6 +292,20 @@ void CHudMenu::Paint()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
inline float CHudMenu::GetMenuTime( void )
|
||||||
|
{
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// In singleplayer, use the curtime instead. This fixes issues with menus disappearing after pausing
|
||||||
|
if (gpGlobals->maxClients <= 1)
|
||||||
|
return gpGlobals->curtime;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return gpGlobals->realtime;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: selects an item from the menu
|
// Purpose: selects an item from the menu
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -260,7 +324,7 @@ void CHudMenu::SelectMenuItem( int menu_item )
|
|||||||
|
|
||||||
// remove the menu quickly
|
// remove the menu quickly
|
||||||
m_bMenuTakesInput = false;
|
m_bMenuTakesInput = false;
|
||||||
m_flShutoffTime = gpGlobals->realtime + m_flOpenCloseTime;
|
m_flShutoffTime = GetMenuTime() + m_flOpenCloseTime;
|
||||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,8 +404,19 @@ void CHudMenu::ProcessText( void )
|
|||||||
ProcessedLine *l = &m_Processed[ i ];
|
ProcessedLine *l = &m_Processed[ i ];
|
||||||
Assert( l );
|
Assert( l );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
bool isItem = true;
|
||||||
|
if (l->menuitem == 0 && l->startchar < (MAX_MENU_STRING-1) && g_szMenuString[ l->startchar ] != L'0' && g_szMenuString[ l->startchar+1 ] != L'.')
|
||||||
|
{
|
||||||
|
// Can't use 0 directly because it gets conflated with the cancel item
|
||||||
|
isItem = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool isItem = l->menuitem != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
int pixels = 0;
|
int pixels = 0;
|
||||||
vgui::HFont font = l->menuitem != 0 ? m_hItemFont : m_hTextFont;
|
vgui::HFont font = isItem ? m_hItemFont : m_hTextFont;
|
||||||
|
|
||||||
for ( int ch = 0; ch < l->length; ch++ )
|
for ( int ch = 0; ch < l->length; ch++ )
|
||||||
{
|
{
|
||||||
@ -364,7 +439,7 @@ void CHudMenu::ProcessText( void )
|
|||||||
void CHudMenu::HideMenu( void )
|
void CHudMenu::HideMenu( void )
|
||||||
{
|
{
|
||||||
m_bMenuTakesInput = false;
|
m_bMenuTakesInput = false;
|
||||||
m_flShutoffTime = gpGlobals->realtime + m_flOpenCloseTime;
|
m_flShutoffTime = GetMenuTime() + m_flOpenCloseTime;
|
||||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuClose");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,6 +456,11 @@ void CHudMenu::ShowMenu( const char * menuName, int validSlots )
|
|||||||
m_flShutoffTime = -1;
|
m_flShutoffTime = -1;
|
||||||
m_bitsValidSlots = validSlots;
|
m_bitsValidSlots = validSlots;
|
||||||
m_fWaitingForMore = 0;
|
m_fWaitingForMore = 0;
|
||||||
|
m_nBorder = 20;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bMapDefinedMenu = false;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
Q_strncpy( g_szPrelocalisedMenuString, menuName, sizeof( g_szPrelocalisedMenuString ) );
|
Q_strncpy( g_szPrelocalisedMenuString, menuName, sizeof( g_szPrelocalisedMenuString ) );
|
||||||
|
|
||||||
@ -408,6 +488,11 @@ void CHudMenu::ShowMenu_KeyValueItems( KeyValues *pKV )
|
|||||||
m_flShutoffTime = -1;
|
m_flShutoffTime = -1;
|
||||||
m_fWaitingForMore = 0;
|
m_fWaitingForMore = 0;
|
||||||
m_bitsValidSlots = 0;
|
m_bitsValidSlots = 0;
|
||||||
|
m_nBorder = 20;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bMapDefinedMenu = false;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuOpen");
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuOpen");
|
||||||
m_nSelectedItem = -1;
|
m_nSelectedItem = -1;
|
||||||
@ -426,7 +511,11 @@ void CHudMenu::ShowMenu_KeyValueItems( KeyValues *pKV )
|
|||||||
const char *pszItem = item->GetName();
|
const char *pszItem = item->GetName();
|
||||||
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pszItem );
|
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pszItem );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"->%d. %ls\n", i+1, wLocalizedItem );
|
||||||
|
#else
|
||||||
nCount = _snwprintf( pWritePosition, nRemaining, L"%d. %ls\n", i+1, wLocalizedItem );
|
nCount = _snwprintf( pWritePosition, nRemaining, L"%d. %ls\n", i+1, wLocalizedItem );
|
||||||
|
#endif
|
||||||
nRemaining -= nCount;
|
nRemaining -= nCount;
|
||||||
pWritePosition += nCount;
|
pWritePosition += nCount;
|
||||||
|
|
||||||
@ -436,7 +525,11 @@ void CHudMenu::ShowMenu_KeyValueItems( KeyValues *pKV )
|
|||||||
// put a cancel on the end
|
// put a cancel on the end
|
||||||
m_bitsValidSlots |= (1<<9);
|
m_bitsValidSlots |= (1<<9);
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"->0. %ls\n", g_pVGuiLocalize->Find( "#Cancel" ) );
|
||||||
|
#else
|
||||||
nCount = _snwprintf( pWritePosition, nRemaining, L"0. %ls\n", g_pVGuiLocalize->Find( "#Cancel" ) );
|
nCount = _snwprintf( pWritePosition, nRemaining, L"0. %ls\n", g_pVGuiLocalize->Find( "#Cancel" ) );
|
||||||
|
#endif
|
||||||
nRemaining -= nCount;
|
nRemaining -= nCount;
|
||||||
pWritePosition += nCount;
|
pWritePosition += nCount;
|
||||||
|
|
||||||
@ -465,8 +558,7 @@ void CHudMenu::MsgFunc_ShowMenu( bf_read &msg)
|
|||||||
|
|
||||||
if ( DisplayTime > 0 )
|
if ( DisplayTime > 0 )
|
||||||
{
|
{
|
||||||
m_flShutoffTime = m_flOpenCloseTime + DisplayTime + gpGlobals->realtime;
|
m_flShutoffTime = m_flOpenCloseTime + DisplayTime + GetMenuTime();
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -511,8 +603,131 @@ void CHudMenu::MsgFunc_ShowMenu( bf_read &msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_fWaitingForMore = NeedMore;
|
m_fWaitingForMore = NeedMore;
|
||||||
|
m_nBorder = 20;
|
||||||
|
#ifdef MAPBASE
|
||||||
|
m_bMapDefinedMenu = false;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
ConVar hud_menu_complex_border( "hud_menu_complex_border", "30" );
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Message handler for ShowMenu message with more options for game_menu
|
||||||
|
// takes four values:
|
||||||
|
// short : a bitfield of keys that are valid input
|
||||||
|
// float : the duration, in seconds, the menu should stay up. -1 means it stays until something is chosen.
|
||||||
|
// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, false if it's the last string
|
||||||
|
// string: menu string to display
|
||||||
|
// if this message is never received, then scores will simply be the combined totals of the players.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CHudMenu::MsgFunc_ShowMenuComplex( bf_read &msg)
|
||||||
|
{
|
||||||
|
m_bitsValidSlots = (short)msg.ReadWord();
|
||||||
|
float DisplayTime = msg.ReadFloat();
|
||||||
|
int NeedMore = msg.ReadByte();
|
||||||
|
|
||||||
|
m_nBorder = hud_menu_complex_border.GetInt();
|
||||||
|
m_bMapDefinedMenu = true;
|
||||||
|
m_bPlayingFadeout = false;
|
||||||
|
|
||||||
|
if ( DisplayTime > 0 )
|
||||||
|
{
|
||||||
|
m_flShutoffTime = m_flOpenCloseTime + DisplayTime + GetMenuTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_flShutoffTime = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_bitsValidSlots > -1 )
|
||||||
|
{
|
||||||
|
char szString[2048];
|
||||||
|
msg.ReadString( szString, sizeof(szString) );
|
||||||
|
|
||||||
|
if ( !m_fWaitingForMore ) // this is the start of a new menu
|
||||||
|
{
|
||||||
|
Q_strncpy( g_szPrelocalisedMenuString, szString, sizeof( g_szPrelocalisedMenuString ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // append to the current menu string
|
||||||
|
Q_strncat( g_szPrelocalisedMenuString, szString, sizeof( g_szPrelocalisedMenuString ), COPY_ALL_CHARACTERS );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !NeedMore )
|
||||||
|
{
|
||||||
|
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence("MenuOpenFlash");
|
||||||
|
m_nSelectedItem = -1;
|
||||||
|
|
||||||
|
// we have the whole string, so we can localise it now
|
||||||
|
wchar_t *pWritePosition = g_szMenuString;
|
||||||
|
int nRemaining = sizeof( g_szMenuString ) / sizeof( wchar_t );
|
||||||
|
int nCount;
|
||||||
|
|
||||||
|
char *pszToken = strtok( szString, "\n" );
|
||||||
|
int nCurItem = 0;
|
||||||
|
for (; pszToken != NULL; pszToken = strtok( NULL, "\n" ), nCurItem++)
|
||||||
|
{
|
||||||
|
if (!*pszToken || *pszToken == ' ')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wchar_t wszMenuItem[128];
|
||||||
|
|
||||||
|
const wchar_t *wLocalizedItem = g_pVGuiLocalize->Find( pszToken );
|
||||||
|
if (wLocalizedItem)
|
||||||
|
{
|
||||||
|
V_wcsncpy( wszMenuItem, wLocalizedItem, sizeof( wszMenuItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_pVGuiLocalize->ConvertANSIToUnicode( pszToken, wszMenuItem, sizeof( wszMenuItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nCurItem == 0)
|
||||||
|
{
|
||||||
|
// First item is title
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"%ls\n", wszMenuItem );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If this item isn't valid, skip until it is
|
||||||
|
//while (!(m_bitsValidSlots & (1 << nCurItem)) && nCurItem < 10)
|
||||||
|
//{
|
||||||
|
// nCurItem++;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (nCurItem == 10)
|
||||||
|
nCurItem = 0;
|
||||||
|
|
||||||
|
nCount = _snwprintf( pWritePosition, nRemaining, L"->%d. %ls\n", nCurItem, wszMenuItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
nRemaining -= nCount;
|
||||||
|
pWritePosition += nCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessText();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bMenuDisplayed = true;
|
||||||
|
|
||||||
|
if (m_bitsValidSlots > 0)
|
||||||
|
m_bMenuTakesInput = true;
|
||||||
|
else
|
||||||
|
m_bMenuTakesInput = false;
|
||||||
|
|
||||||
|
m_flSelectionTime = gpGlobals->curtime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HideMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fWaitingForMore = NeedMore;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Purpose: hud scheme settings
|
// Purpose: hud scheme settings
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -26,10 +26,14 @@ class CHudMenu : public CHudElement, public vgui::Panel
|
|||||||
public:
|
public:
|
||||||
CHudMenu( const char *pElementName );
|
CHudMenu( const char *pElementName );
|
||||||
void Init( void );
|
void Init( void );
|
||||||
|
void LevelInit( void );
|
||||||
void VidInit( void );
|
void VidInit( void );
|
||||||
void Reset( void );
|
void Reset( void );
|
||||||
virtual bool ShouldDraw( void );
|
virtual bool ShouldDraw( void );
|
||||||
void MsgFunc_ShowMenu( bf_read &msg );
|
void MsgFunc_ShowMenu( bf_read &msg );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
void MsgFunc_ShowMenuComplex( bf_read &msg );
|
||||||
|
#endif
|
||||||
void HideMenu( void );
|
void HideMenu( void );
|
||||||
void ShowMenu( const char * menuName, int keySlot );
|
void ShowMenu( const char * menuName, int keySlot );
|
||||||
void ShowMenu_KeyValueItems( KeyValues *pKV );
|
void ShowMenu_KeyValueItems( KeyValues *pKV );
|
||||||
@ -42,6 +46,8 @@ private:
|
|||||||
virtual void Paint();
|
virtual void Paint();
|
||||||
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
virtual void ApplySchemeSettings(vgui::IScheme *pScheme);
|
||||||
private:
|
private:
|
||||||
|
float GetMenuTime( void );
|
||||||
|
|
||||||
void ProcessText( void );
|
void ProcessText( void );
|
||||||
|
|
||||||
void PaintString( const wchar_t *text, int textlen, vgui::HFont& font, int x, int y );
|
void PaintString( const wchar_t *text, int textlen, vgui::HFont& font, int x, int y );
|
||||||
@ -59,6 +65,7 @@ private:
|
|||||||
|
|
||||||
int m_nMaxPixels;
|
int m_nMaxPixels;
|
||||||
int m_nHeight;
|
int m_nHeight;
|
||||||
|
int m_nBorder;
|
||||||
|
|
||||||
bool m_bMenuDisplayed;
|
bool m_bMenuDisplayed;
|
||||||
int m_bitsValidSlots;
|
int m_bitsValidSlots;
|
||||||
@ -69,6 +76,12 @@ private:
|
|||||||
|
|
||||||
float m_flSelectionTime;
|
float m_flSelectionTime;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// Indicates this menu is defined by game_menu
|
||||||
|
bool m_bMapDefinedMenu;
|
||||||
|
bool m_bPlayingFadeout;
|
||||||
|
#endif
|
||||||
|
|
||||||
CPanelAnimationVar( float, m_flOpenCloseTime, "OpenCloseTime", "1" );
|
CPanelAnimationVar( float, m_flOpenCloseTime, "OpenCloseTime", "1" );
|
||||||
|
|
||||||
CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
|
CPanelAnimationVar( float, m_flBlur, "Blur", "0" );
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "entityoutput.h"
|
#include "entityoutput.h"
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
#include "eventqueue.h"
|
#include "eventqueue.h"
|
||||||
|
#include "saverestore_utlvector.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// memdbgon must be the last include file in a .cpp file!!!
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
@ -825,3 +826,449 @@ void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TY
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Displays a custom number menu for player(s)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
LINK_ENTITY_TO_CLASS( game_menu, CGameMenu );
|
||||||
|
|
||||||
|
BEGIN_DATADESC( CGameMenu )
|
||||||
|
|
||||||
|
DEFINE_UTLVECTOR( m_ActivePlayers, FIELD_EHANDLE ),
|
||||||
|
DEFINE_UTLVECTOR( m_ActivePlayerTimes, FIELD_TIME ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_flDisplayTime, FIELD_FLOAT, "holdtime" ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_iszTitle, FIELD_STRING, "Title" ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[0], FIELD_STRING, "Case01" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[1], FIELD_STRING, "Case02" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[2], FIELD_STRING, "Case03" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[3], FIELD_STRING, "Case04" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[4], FIELD_STRING, "Case05" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[5], FIELD_STRING, "Case06" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[6], FIELD_STRING, "Case07" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[7], FIELD_STRING, "Case08" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[8], FIELD_STRING, "Case09" ),
|
||||||
|
DEFINE_KEYFIELD( m_iszOption[9], FIELD_STRING, "Case10" ),
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "ShowMenu", InputShowMenu ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "HideMenu", InputHideMenu ),
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "__DoRestore", InputDoRestore ),
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
DEFINE_OUTPUT( m_OnCase[0], "OnCase01" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[1], "OnCase02" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[2], "OnCase03" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[3], "OnCase04" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[4], "OnCase05" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[5], "OnCase06" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[6], "OnCase07" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[7], "OnCase08" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[8], "OnCase09" ),
|
||||||
|
DEFINE_OUTPUT( m_OnCase[9], "OnCase10" ),
|
||||||
|
DEFINE_OUTPUT( m_OutValue, "OutValue" ),
|
||||||
|
DEFINE_OUTPUT( m_OnTimeout, "OnTimeout" ),
|
||||||
|
|
||||||
|
DEFINE_THINKFUNC( TimeoutThink ),
|
||||||
|
|
||||||
|
END_DATADESC()
|
||||||
|
|
||||||
|
IMPLEMENT_AUTO_LIST( IGameMenuAutoList );
|
||||||
|
|
||||||
|
static const char *s_pTimeoutContext = "TimeoutContext";
|
||||||
|
|
||||||
|
#define MENU_INFINITE_TIME -1.0f
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CGameMenu::CGameMenu()
|
||||||
|
{
|
||||||
|
m_flDisplayTime = 5.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::OnRestore()
|
||||||
|
{
|
||||||
|
BaseClass::OnRestore();
|
||||||
|
|
||||||
|
// Do this a bit after we restore since the HUD might not be ready yet
|
||||||
|
g_EventQueue.AddEvent( this, "__DoRestore", 0.4f, this, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::InputDoRestore( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
// Check if we should restore the menu on anyone
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get())
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
filter.AddRecipient( static_cast<CBasePlayer*>( m_ActivePlayers[i].Get() ) );
|
||||||
|
|
||||||
|
ShowMenu( filter, m_ActivePlayerTimes[i] - gpGlobals->curtime );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::TimeoutThink()
|
||||||
|
{
|
||||||
|
float flNextLowestTime = FLT_MAX;
|
||||||
|
FOR_EACH_VEC( m_ActivePlayerTimes, i )
|
||||||
|
{
|
||||||
|
// If the player is still in our list, then they must not have selected an option
|
||||||
|
if (m_ActivePlayerTimes[i] != MENU_INFINITE_TIME)
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] <= gpGlobals->curtime)
|
||||||
|
{
|
||||||
|
m_OnTimeout.FireOutput( m_ActivePlayers[i], this );
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (m_ActivePlayerTimes[i] < flNextLowestTime)
|
||||||
|
{
|
||||||
|
flNextLowestTime = m_ActivePlayerTimes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flNextLowestTime < FLT_MAX)
|
||||||
|
{
|
||||||
|
SetNextThink( flNextLowestTime, s_pTimeoutContext );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetContextThink( NULL, TICK_NEVER_THINK, s_pTimeoutContext );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::ShowMenu( CRecipientFilter &filter, float flDisplayTime )
|
||||||
|
{
|
||||||
|
// Before showing the menu, check each menu to see if there's already one being shown to one of our recipients
|
||||||
|
for ( int i = 0; i < IGameMenuAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
CGameMenu *pMenu = static_cast<CGameMenu*>( IGameMenuAutoList::AutoList()[i] );
|
||||||
|
if ( pMenu != this && pMenu->IsActive() )
|
||||||
|
{
|
||||||
|
for ( int j = 0; j < filter.GetRecipientCount(); j++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *ent = CBaseEntity::Instance( filter.GetRecipientIndex( j ) );
|
||||||
|
if ( pMenu->IsActiveOnTarget( ent ) )
|
||||||
|
{
|
||||||
|
Msg( "%s overriding menu %s for player %i\n", GetDebugName(), pMenu->GetDebugName(), j );
|
||||||
|
pMenu->RemoveTarget( ent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flDisplayTime == 0.0f)
|
||||||
|
{
|
||||||
|
flDisplayTime = m_flDisplayTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
char szString[512] = { 0 };
|
||||||
|
int nBitsValidSlots = 0;
|
||||||
|
|
||||||
|
if (m_iszTitle != NULL_STRING)
|
||||||
|
{
|
||||||
|
V_strncat( szString, STRING( m_iszTitle ), sizeof( szString ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert space to tell menu code to skip
|
||||||
|
V_strncat( szString, " ", sizeof( szString ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert newline even if there's no string
|
||||||
|
V_strncat( szString, "\n", sizeof( szString ) );
|
||||||
|
|
||||||
|
// Populate the options
|
||||||
|
for (int i = 0; i < MAX_MENU_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
if (m_iszOption[i] != NULL_STRING)
|
||||||
|
{
|
||||||
|
nBitsValidSlots |= (1 << i);
|
||||||
|
|
||||||
|
V_strncat( szString, STRING( m_iszOption[i] ), sizeof( szString ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert space to tell menu code to skip
|
||||||
|
V_strncat( szString, " ", sizeof( szString ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert newline even if there's no string
|
||||||
|
V_strncat( szString, "\n", sizeof( szString ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nBitsValidSlots <= 0 && m_iszTitle == NULL_STRING)
|
||||||
|
{
|
||||||
|
Warning( "%s ShowMenu: Can't show menu with no options or title\n", GetDebugName() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserMessageBegin( filter, "ShowMenuComplex" );
|
||||||
|
WRITE_WORD( nBitsValidSlots );
|
||||||
|
WRITE_FLOAT( flDisplayTime );
|
||||||
|
WRITE_BYTE( 0 );
|
||||||
|
WRITE_STRING( szString );
|
||||||
|
MessageEnd();
|
||||||
|
|
||||||
|
float flMenuTime;
|
||||||
|
if (flDisplayTime <= 0.0f)
|
||||||
|
{
|
||||||
|
flMenuTime = MENU_INFINITE_TIME;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flMenuTime = gpGlobals->curtime + flDisplayTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int j = 0; j < filter.GetRecipientCount(); j++ )
|
||||||
|
{
|
||||||
|
CBaseEntity *ent = CBaseEntity::Instance( filter.GetRecipientIndex( j ) );
|
||||||
|
|
||||||
|
// Check if we already track this player. If not, make a new one
|
||||||
|
bool bFound = false;
|
||||||
|
FOR_EACH_VEC( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == ent)
|
||||||
|
{
|
||||||
|
m_ActivePlayerTimes[i] = flMenuTime;
|
||||||
|
bFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bFound)
|
||||||
|
{
|
||||||
|
m_ActivePlayers.AddToTail( ent );
|
||||||
|
m_ActivePlayerTimes.AddToTail( flMenuTime );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetNextThink( s_pTimeoutContext ) == TICK_NEVER_THINK)
|
||||||
|
{
|
||||||
|
SetContextThink( &CGameMenu::TimeoutThink, gpGlobals->curtime + flDisplayTime, s_pTimeoutContext );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::HideMenu( CRecipientFilter &filter )
|
||||||
|
{
|
||||||
|
UserMessageBegin( filter, "ShowMenuComplex" );
|
||||||
|
WRITE_WORD( -1 );
|
||||||
|
WRITE_FLOAT( 0.0f );
|
||||||
|
WRITE_BYTE( 0 );
|
||||||
|
WRITE_STRING( "" );
|
||||||
|
MessageEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::MenuSelected( int nSlot, CBaseEntity *pActivator )
|
||||||
|
{
|
||||||
|
if (nSlot <= 0 || nSlot > MAX_MENU_OPTIONS)
|
||||||
|
{
|
||||||
|
Warning( "%s: Invalid slot %i\n", GetDebugName(), nSlot );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_OnCase[nSlot-1].FireOutput( pActivator, this );
|
||||||
|
m_OutValue.Set( nSlot, pActivator, this );
|
||||||
|
|
||||||
|
RemoveTarget( pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CGameMenu::IsActive()
|
||||||
|
{
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get())
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CGameMenu::IsActiveOnTarget( CBaseEntity *pPlayer )
|
||||||
|
{
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == pPlayer)
|
||||||
|
{
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Remove this player since it's no longer valid
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::RemoveTarget( CBaseEntity *pPlayer )
|
||||||
|
{
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == pPlayer)
|
||||||
|
{
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::InputShowMenu( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
if (HasSpawnFlags( SF_GAMEMENU_ALLPLAYERS ))
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
filter.AddAllPlayers();
|
||||||
|
|
||||||
|
ShowMenu( filter );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBasePlayer *pPlayer = NULL;
|
||||||
|
|
||||||
|
// If we're in singleplayer, show the message to the player.
|
||||||
|
if ( gpGlobals->maxClients == 1 )
|
||||||
|
{
|
||||||
|
pPlayer = UTIL_GetLocalPlayer();
|
||||||
|
}
|
||||||
|
// Otherwise show the message to the player that triggered us.
|
||||||
|
else if ( inputdata.pActivator && inputdata.pActivator->IsNetClient() )
|
||||||
|
{
|
||||||
|
pPlayer = ToBasePlayer( inputdata.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPlayer)
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
filter.AddRecipient( pPlayer );
|
||||||
|
|
||||||
|
ShowMenu( filter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose:
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void CGameMenu::InputHideMenu( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
if (HasSpawnFlags( SF_GAMEMENU_ALLPLAYERS ))
|
||||||
|
{
|
||||||
|
CRecipientFilter filter;
|
||||||
|
|
||||||
|
FOR_EACH_VEC_BACK( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
// Select all players in our list who are still active, and remove them
|
||||||
|
if (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME)
|
||||||
|
{
|
||||||
|
filter.AddRecipient( static_cast<CBasePlayer*>(m_ActivePlayers[i].Get()) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.GetRecipientCount() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HideMenu( filter );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBasePlayer *pPlayer = NULL;
|
||||||
|
|
||||||
|
// If we're in singleplayer, show the message to the player.
|
||||||
|
if ( gpGlobals->maxClients == 1 )
|
||||||
|
{
|
||||||
|
pPlayer = UTIL_GetLocalPlayer();
|
||||||
|
}
|
||||||
|
// Otherwise show the message to the player that triggered us.
|
||||||
|
else if ( inputdata.pActivator && inputdata.pActivator->IsNetClient() )
|
||||||
|
{
|
||||||
|
pPlayer = ToBasePlayer( inputdata.pActivator );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pPlayer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Verify that this player is in our list
|
||||||
|
CRecipientFilter filter;
|
||||||
|
FOR_EACH_VEC( m_ActivePlayers, i )
|
||||||
|
{
|
||||||
|
if (m_ActivePlayers[i].Get() == pPlayer && (m_ActivePlayerTimes[i] > gpGlobals->curtime || m_ActivePlayerTimes[i] == MENU_INFINITE_TIME))
|
||||||
|
{
|
||||||
|
filter.AddRecipient( pPlayer );
|
||||||
|
|
||||||
|
// Remove since the player won't have the menu anymore
|
||||||
|
m_ActivePlayers.Remove( i );
|
||||||
|
m_ActivePlayerTimes.Remove( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.GetRecipientCount() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
HideMenu( filter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,55 @@
|
|||||||
#ifndef MAPRULES_H
|
#ifndef MAPRULES_H
|
||||||
#define MAPRULES_H
|
#define MAPRULES_H
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
#define MAX_MENU_OPTIONS 10
|
||||||
|
|
||||||
|
#define SF_GAMEMENU_ALLPLAYERS 0x0001
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Purpose: Displays a custom number menu for player(s)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
DECLARE_AUTO_LIST( IGameMenuAutoList );
|
||||||
|
class CGameMenu : public CLogicalEntity, public IGameMenuAutoList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_CLASS( CGameMenu, CLogicalEntity );
|
||||||
|
DECLARE_DATADESC();
|
||||||
|
CGameMenu();
|
||||||
|
|
||||||
|
void OnRestore();
|
||||||
|
void InputDoRestore( inputdata_t &inputdata );
|
||||||
|
|
||||||
|
void TimeoutThink();
|
||||||
|
|
||||||
|
void ShowMenu( CRecipientFilter &filter, float flDisplayTime = 0.0f );
|
||||||
|
void HideMenu( CRecipientFilter &filter );
|
||||||
|
void MenuSelected( int nSlot, CBaseEntity *pActivator );
|
||||||
|
|
||||||
|
bool IsActive();
|
||||||
|
bool IsActiveOnTarget( CBaseEntity *pPlayer );
|
||||||
|
void RemoveTarget( CBaseEntity *pPlayer );
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
void InputShowMenu( inputdata_t &inputdata );
|
||||||
|
void InputHideMenu( inputdata_t &inputdata );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CUtlVector<EHANDLE> m_ActivePlayers;
|
||||||
|
CUtlVector<float> m_ActivePlayerTimes;
|
||||||
|
|
||||||
|
float m_flDisplayTime;
|
||||||
|
|
||||||
|
string_t m_iszTitle;
|
||||||
|
string_t m_iszOption[MAX_MENU_OPTIONS];
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
COutputEvent m_OnCase[MAX_MENU_OPTIONS]; // Fired for the option chosen
|
||||||
|
COutputInt m_OutValue; // Outputs the option chosen
|
||||||
|
COutputEvent m_OnTimeout; // Fires when no option was chosen in time
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // MAPRULES_H
|
#endif // MAPRULES_H
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
#include "player_resource.h"
|
#include "player_resource.h"
|
||||||
#include "tactical_mission.h"
|
#include "tactical_mission.h"
|
||||||
#include "gamestats.h"
|
#include "gamestats.h"
|
||||||
|
#ifdef MAPBASE
|
||||||
|
#include "maprules.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -619,6 +622,27 @@ bool CGameRules::ClientCommand( CBaseEntity *pEdict, const CCommand &args )
|
|||||||
{
|
{
|
||||||
if( GetVoiceGameMgr()->ClientCommand( static_cast<CBasePlayer*>(pEdict), args ) )
|
if( GetVoiceGameMgr()->ClientCommand( static_cast<CBasePlayer*>(pEdict), args ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( FStrEq( args[0], "menuselect" ) )
|
||||||
|
{
|
||||||
|
if ( args.ArgC() >= 2 )
|
||||||
|
{
|
||||||
|
int slot = atoi( args[1] );
|
||||||
|
|
||||||
|
// See if this is from a game_menu
|
||||||
|
for ( int i = 0; i < IGameMenuAutoList::AutoList().Count(); i++ )
|
||||||
|
{
|
||||||
|
CGameMenu *pMenu = static_cast<CGameMenu*>( IGameMenuAutoList::AutoList()[i] );
|
||||||
|
if ( pMenu->IsActiveOnTarget( pEdict ) )
|
||||||
|
{
|
||||||
|
pMenu->MenuSelected( slot, pEdict );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -20,6 +20,8 @@ void HookMapbaseUserMessages( void )
|
|||||||
{
|
{
|
||||||
// VScript
|
// VScript
|
||||||
//HOOK_MESSAGE( ScriptMsg ); // Hooked in CNetMsgScriptHelper
|
//HOOK_MESSAGE( ScriptMsg ); // Hooked in CNetMsgScriptHelper
|
||||||
|
|
||||||
|
//HOOK_MESSAGE( ShowMenuComplex ); // Hooked in CHudMenu
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -28,6 +30,8 @@ void RegisterMapbaseUserMessages( void )
|
|||||||
// VScript
|
// VScript
|
||||||
usermessages->Register( "ScriptMsg", -1 ); // CNetMsgScriptHelper
|
usermessages->Register( "ScriptMsg", -1 ); // CNetMsgScriptHelper
|
||||||
|
|
||||||
|
usermessages->Register( "ShowMenuComplex", -1 ); // CHudMenu
|
||||||
|
|
||||||
#ifdef CLIENT_DLL
|
#ifdef CLIENT_DLL
|
||||||
// TODO: Better placement?
|
// TODO: Better placement?
|
||||||
HookMapbaseUserMessages();
|
HookMapbaseUserMessages();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user