2008-03-30 09:00:22 +02:00
/**
* vim : set ts = 4 :
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* SourceMod
* Copyright ( C ) 2004 - 2008 AlliedModders LLC . All rights reserved .
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*
* This program is free software ; you can redistribute it and / or modify it under
* the terms of the GNU General Public License , version 3.0 , as published by the
* Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE . See the GNU General Public License for more
* details .
*
* You should have received a copy of the GNU General Public License along with
* this program . If not , see < http : //www.gnu.org/licenses/>.
*
* As a special exception , AlliedModders LLC gives you permission to link the
* code of this program ( as well as its derivative works ) to " Half-Life 2, " the
* " Source Engine, " the " SourcePawn JIT, " and any Game MODs that run on software
* by the Valve Corporation . You must obey the GNU General Public License in
* all respects for all other code used . Additionally , AlliedModders LLC grants
* this exception to all derivative works . AlliedModders LLC defines further
* exceptions , found in LICENSE . txt ( as of this writing , version JULY - 31 - 2007 ) ,
* or < http : //www.sourcemod.net/license.php>.
*
* Version : $ Id $
*/
# include "sm_globals.h"
# include <sh_stack.h>
# include "DebugReporter.h"
# include "MenuManager.h"
# include "MenuStyle_Valve.h"
# include "MenuStyle_Radio.h"
# include "HandleSys.h"
# include "PluginSys.h"
# include "PlayerManager.h"
# include "sm_stringutil.h"
# include "sourcemm_api.h"
# if defined MENU_DEBUG
# include "Logger.h"
# endif
# include "ChatTriggers.h"
# if defined CreateMenu
# undef CreateMenu
# endif
/**
* And God said , " let there be menus, " and behold , there were menus .
* God saw the menus and they were good . And the evening and the morning
* were the third day .
*/
enum MenuAction
{
MenuAction_Start = ( 1 < < 0 ) , /**< A menu has been started (nothing passed) */
MenuAction_Display = ( 1 < < 1 ) , /**< A menu is about to be displayed (param1=client, param2=MenuPanel Handle) */
MenuAction_Select = ( 1 < < 2 ) , /**< An item was selected (param1=client, param2=item) */
MenuAction_Cancel = ( 1 < < 3 ) , /**< The menu was cancelled (param1=client, param2=item) */
MenuAction_End = ( 1 < < 4 ) , /**< A menu's display/selection cycle is complete (nothing passed). */
MenuAction_VoteEnd = ( 1 < < 5 ) , /**< (VOTE ONLY): A vote sequence has ended (param1=chosen item) */
MenuAction_VoteStart = ( 1 < < 6 ) , /**< (VOTE ONLY): A vote sequence has started */
MenuAction_VoteCancel = ( 1 < < 7 ) , /**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */
MenuAction_DrawItem = ( 1 < < 8 ) , /**< A style is being drawn; return the new style (param1=client, param2=item) */
MenuAction_DisplayItem = ( 1 < < 9 ) , /**< the odd duck */
} ;
class CPanelHandler : public IMenuHandler
{
friend class MenuNativeHelpers ;
public :
CPanelHandler ( )
{
}
void OnMenuCancel ( IBaseMenu * menu , int client , MenuCancelReason reason ) ;
void OnMenuSelect ( IBaseMenu * menu , int client , unsigned int item ) ;
private :
IPluginFunction * m_pFunc ;
IPlugin * m_pPlugin ;
} ;
class CMenuHandler : public IMenuHandler
{
friend class MenuNativeHelpers ;
public :
CMenuHandler ( IPluginFunction * pBasic , int flags ) ;
public :
void OnMenuStart ( IBaseMenu * menu ) ;
void OnMenuDisplay ( IBaseMenu * menu , int client , IMenuPanel * display ) ;
void OnMenuSelect2 ( IBaseMenu * menu , int client , unsigned int item , unsigned int item_on_page ) ;
void OnMenuCancel ( IBaseMenu * menu , int client , MenuCancelReason reason ) ;
void OnMenuEnd ( IBaseMenu * menu , MenuEndReason reason ) ;
void OnMenuDestroy ( IBaseMenu * menu ) ;
void OnMenuVoteStart ( IBaseMenu * menu ) ;
void OnMenuVoteResults ( IBaseMenu * menu , const menu_vote_result_t * results ) ;
void OnMenuVoteCancel ( IBaseMenu * menu , VoteCancelReason reason ) ;
void OnMenuDrawItem ( IBaseMenu * menu , int client , unsigned int item , unsigned int & style ) ;
unsigned int OnMenuDisplayItem ( IBaseMenu * menu , int client , IMenuPanel * panel , unsigned int item , const ItemDrawInfo & dr ) ;
bool OnSetHandlerOption ( const char * option , const void * data ) ;
#if 0
void OnMenuDrawItem ( IBaseMenu * menu , int client , unsigned int item , unsigned int & style ) ;
void OnMenuDisplayItem ( IBaseMenu * menu , int client , unsigned int item , const char * * display ) ;
# endif
private :
cell_t DoAction ( IBaseMenu * menu , MenuAction action , cell_t param1 , cell_t param2 , cell_t def_res = 0 ) ;
private :
IPluginFunction * m_pBasic ;
int m_Flags ;
IPluginFunction * m_pVoteResults ;
cell_t m_fnVoteResult ;
} ;
/**
* GLOBAL CLASS FOR HELPERS
*/
class MenuNativeHelpers :
public SMGlobalClass ,
public IHandleTypeDispatch ,
public IPluginsListener
{
public :
virtual void OnSourceModAllInitialized ( )
{
m_PanelType = g_HandleSys . CreateType ( " IMenuPanel " , this , 0 , NULL , NULL , g_pCoreIdent , NULL ) ;
m_TempPanelType = g_HandleSys . CreateType ( " TempIMenuPanel " , this , m_PanelType , NULL , NULL , g_pCoreIdent , NULL ) ;
g_PluginSys . AddPluginsListener ( this ) ;
}
virtual void OnSourceModShutdown ( )
{
g_HandleSys . RemoveType ( m_TempPanelType , g_pCoreIdent ) ;
g_HandleSys . RemoveType ( m_PanelType , g_pCoreIdent ) ;
while ( ! m_FreePanelHandlers . empty ( ) )
{
delete m_FreePanelHandlers . front ( ) ;
m_FreePanelHandlers . pop ( ) ;
}
while ( ! m_FreeMenuHandlers . empty ( ) )
{
delete m_FreeMenuHandlers . front ( ) ;
m_FreeMenuHandlers . pop ( ) ;
}
}
virtual void OnHandleDestroy ( HandleType_t type , void * object )
{
if ( type = = m_TempPanelType )
{
return ;
}
IMenuPanel * panel = ( IMenuPanel * ) object ;
panel - > DeleteThis ( ) ;
}
virtual bool GetHandleApproxSize ( HandleType_t type , void * object , unsigned int * pSize )
{
* pSize = ( ( IMenuPanel * ) object ) - > GetApproxMemUsage ( ) ;
return true ;
}
/**
* It is extremely important that unloaded plugins don ' t crash .
* Thus , if a plugin unloads , we run through every handler we have .
* This means we do almost no runtime work for keeping track of
* our panel handlers ( we don ' t have to store a list of the running
* ones ) , but when push comes to shove , we have to scan them all
* in case any of them are active .
*/
virtual void OnPluginUnloaded ( IPlugin * plugin )
{
for ( size_t i = 0 ; i < m_PanelHandlers . size ( ) ; i + + )
{
if ( m_PanelHandlers [ i ] - > m_pPlugin = = plugin )
{
m_PanelHandlers [ i ] - > m_pPlugin = NULL ;
m_PanelHandlers [ i ] - > m_pFunc = NULL ;
}
}
}
inline HandleType_t GetPanelType ( )
{
return m_PanelType ;
}
inline HandleType_t GetTempPanelType ( )
{
return m_TempPanelType ;
}
CPanelHandler * GetPanelHandler ( IPluginFunction * pFunction )
{
CPanelHandler * handler ;
if ( m_FreePanelHandlers . empty ( ) )
{
handler = new CPanelHandler ;
m_PanelHandlers . push_back ( handler ) ;
} else {
handler = m_FreePanelHandlers . front ( ) ;
m_FreePanelHandlers . pop ( ) ;
}
handler - > m_pFunc = pFunction ;
handler - > m_pPlugin = g_PluginSys . GetPluginByCtx ( pFunction - > GetParentContext ( ) - > GetContext ( ) ) ;
return handler ;
}
void FreePanelHandler ( CPanelHandler * handler )
{
handler - > m_pFunc = NULL ;
handler - > m_pPlugin = NULL ;
m_FreePanelHandlers . push ( handler ) ;
}
CMenuHandler * GetMenuHandler ( IPluginFunction * pFunction , int flags )
{
CMenuHandler * handler ;
if ( m_FreeMenuHandlers . empty ( ) )
{
handler = new CMenuHandler ( pFunction , flags ) ;
} else {
handler = m_FreeMenuHandlers . front ( ) ;
m_FreeMenuHandlers . pop ( ) ;
handler - > m_pBasic = pFunction ;
handler - > m_Flags = flags ;
handler - > m_pVoteResults = NULL ;
}
return handler ;
}
void FreeMenuHandler ( CMenuHandler * handler )
{
m_FreeMenuHandlers . push ( handler ) ;
}
private :
HandleType_t m_PanelType ;
HandleType_t m_TempPanelType ;
CStack < CPanelHandler * > m_FreePanelHandlers ;
CStack < CMenuHandler * > m_FreeMenuHandlers ;
CVector < CPanelHandler * > m_PanelHandlers ;
} g_MenuHelpers ;
/**
* BASIC PANEL HANDLER WRAPPER
*/
void CPanelHandler : : OnMenuCancel ( IBaseMenu * menu , int client , MenuCancelReason reason )
{
if ( m_pFunc )
{
m_pFunc - > PushCell ( BAD_HANDLE ) ;
m_pFunc - > PushCell ( MenuAction_Cancel ) ;
m_pFunc - > PushCell ( client ) ;
m_pFunc - > PushCell ( reason ) ;
m_pFunc - > Execute ( NULL ) ;
}
g_MenuHelpers . FreePanelHandler ( this ) ;
}
void CPanelHandler : : OnMenuSelect ( IBaseMenu * menu , int client , unsigned int item )
{
if ( m_pFunc )
{
unsigned int old_reply = g_ChatTriggers . SetReplyTo ( SM_REPLY_CHAT ) ;
m_pFunc - > PushCell ( BAD_HANDLE ) ;
m_pFunc - > PushCell ( MenuAction_Select ) ;
m_pFunc - > PushCell ( client ) ;
m_pFunc - > PushCell ( item ) ;
m_pFunc - > Execute ( NULL ) ;
g_ChatTriggers . SetReplyTo ( old_reply ) ;
}
g_MenuHelpers . FreePanelHandler ( this ) ;
}
static IMenuPanel * s_pCurPanel = NULL ;
static unsigned int s_CurPanelReturn = 0 ;
static const ItemDrawInfo * s_CurDrawInfo = NULL ;
static unsigned int * s_CurSelectPosition = NULL ;
/**
* MENU HANDLER WRAPPER
*/
CMenuHandler : : CMenuHandler ( IPluginFunction * pBasic , int flags ) :
m_pBasic ( pBasic ) , m_Flags ( flags ) , m_pVoteResults ( NULL )
{
/* :TODO: We can probably cache the handle ahead of time */
}
void CMenuHandler : : OnMenuStart ( IBaseMenu * menu )
{
if ( ( m_Flags & ( int ) MenuAction_Start ) = = ( int ) MenuAction_Start )
{
DoAction ( menu , MenuAction_Start , 0 , 0 ) ;
}
}
void CMenuHandler : : OnMenuDisplay ( IBaseMenu * menu , int client , IMenuPanel * panel )
{
if ( ( m_Flags & ( int ) MenuAction_Display ) = = ( int ) MenuAction_Display )
{
HandleSecurity sec ;
sec . pIdentity = g_pCoreIdent ;
sec . pOwner = m_pBasic - > GetParentContext ( ) - > GetIdentity ( ) ;
HandleAccess access ;
g_HandleSys . InitAccessDefaults ( NULL , & access ) ;
access . access [ HandleAccess_Delete ] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER ;
Handle_t hndl = g_HandleSys . CreateHandleEx ( g_MenuHelpers . GetTempPanelType ( ) , panel , & sec , & access , NULL ) ;
DoAction ( menu , MenuAction_Display , client , hndl ) ;
g_HandleSys . FreeHandle ( hndl , & sec ) ;
}
}
void CMenuHandler : : OnMenuSelect2 ( IBaseMenu * menu , int client , unsigned int item , unsigned int item_on_page )
{
/* Save old position first. */
unsigned int first_item = item_on_page ;
unsigned int * old_pos = s_CurSelectPosition ;
s_CurSelectPosition = & first_item ;
unsigned int old_reply = g_ChatTriggers . SetReplyTo ( SM_REPLY_CHAT ) ;
DoAction ( menu , MenuAction_Select , client , item ) ;
g_ChatTriggers . SetReplyTo ( old_reply ) ;
s_CurSelectPosition = old_pos ;
}
void CMenuHandler : : OnMenuCancel ( IBaseMenu * menu , int client , MenuCancelReason reason )
{
unsigned int old_reply = g_ChatTriggers . SetReplyTo ( SM_REPLY_CHAT ) ;
DoAction ( menu , MenuAction_Cancel , client , ( cell_t ) reason ) ;
g_ChatTriggers . SetReplyTo ( old_reply ) ;
}
void CMenuHandler : : OnMenuEnd ( IBaseMenu * menu , MenuEndReason reason )
{
DoAction ( menu , MenuAction_End , reason , 0 ) ;
}
void CMenuHandler : : OnMenuDestroy ( IBaseMenu * menu )
{
g_MenuHelpers . FreeMenuHandler ( this ) ;
}
void CMenuHandler : : OnMenuVoteStart ( IBaseMenu * menu )
{
DoAction ( menu , MenuAction_VoteStart , 0 , 0 ) ;
}
void CMenuHandler : : OnMenuVoteCancel ( IBaseMenu * menu , VoteCancelReason reason )
{
DoAction ( menu , MenuAction_VoteCancel , reason , 0 ) ;
}
void CMenuHandler : : OnMenuDrawItem ( IBaseMenu * menu , int client , unsigned int item , unsigned int & style )
{
if ( ( m_Flags & ( int ) MenuAction_DrawItem ) = = ( int ) MenuAction_DrawItem )
{
cell_t result = DoAction ( menu , MenuAction_DrawItem , client , item , style ) ;
style = ( unsigned int ) result ;
}
}
unsigned int CMenuHandler : : OnMenuDisplayItem ( IBaseMenu * menu ,
int client ,
IMenuPanel * panel ,
unsigned int item ,
const ItemDrawInfo & dr )
{
if ( ( m_Flags & ( int ) MenuAction_DisplayItem ) = = ( int ) MenuAction_DisplayItem )
{
IMenuPanel * oldpanel = s_pCurPanel ;
unsigned int oldret = s_CurPanelReturn ;
const ItemDrawInfo * oldinfo = s_CurDrawInfo ;
s_pCurPanel = panel ;
s_CurPanelReturn = 0 ;
s_CurDrawInfo = & dr ;
cell_t res = DoAction ( menu , MenuAction_DisplayItem , client , item , 0 ) ;
if ( ! res )
{
res = s_CurPanelReturn ;
}
s_pCurPanel = oldpanel ;
s_CurPanelReturn = oldret ;
s_CurDrawInfo = oldinfo ;
return res ;
}
return 0 ;
}
cell_t CMenuHandler : : DoAction ( IBaseMenu * menu , MenuAction action , cell_t param1 , cell_t param2 , cell_t def_res )
{
# if defined MENU_DEBUG
g_Logger . LogMessage ( " [SM_MENU] CMenuHandler::DoAction() (menu %p/%08x) (action %d) (param1 %d) (param2 %d) " ,
menu ,
menu - > GetHandle ( ) ,
action ,
param1 ,
param2 ) ;
# endif
cell_t res = def_res ;
m_pBasic - > PushCell ( menu - > GetHandle ( ) ) ;
m_pBasic - > PushCell ( ( cell_t ) action ) ;
m_pBasic - > PushCell ( param1 ) ;
m_pBasic - > PushCell ( param2 ) ;
m_pBasic - > Execute ( & res ) ;
return res ;
}
void CMenuHandler : : OnMenuVoteResults ( IBaseMenu * menu , const menu_vote_result_t * results )
{
if ( ! m_pVoteResults )
{
/* Call MenuAction_VoteEnd instead. See if there are any extra winners. */
unsigned int num_items = 1 ;
for ( unsigned int i = 1 ; i < results - > num_items ; i + + )
{
if ( results - > item_list [ i ] . count ! = results - > item_list [ 0 ] . count )
{
break ;
}
num_items + + ;
}
/* See if we need to pick a random winner. */
unsigned int winning_item ;
if ( num_items > 1 )
{
/* Yes, we do. */
srand ( time ( NULL ) ) ;
winning_item = rand ( ) % num_items ;
winning_item = results - > item_list [ winning_item ] . item ;
} else {
/* No, take the first. */
winning_item = results - > item_list [ 0 ] . item ;
}
unsigned int total_votes = results - > num_votes ;
unsigned int winning_votes = results - > item_list [ 0 ] . count ;
DoAction ( menu , MenuAction_VoteEnd , winning_item , ( total_votes < < 16 ) | ( winning_votes & 0xFFFF ) ) ;
} else {
IPluginContext * pContext = m_pVoteResults - > GetParentContext ( ) ;
bool no_call = false ;
int err ;
/* First array */
cell_t client_array_address = - 1 ;
cell_t * client_array_base = NULL ;
cell_t client_array_size = results - > num_clients + ( results - > num_clients * 2 ) ;
if ( client_array_size )
{
if ( ( err = pContext - > HeapAlloc ( client_array_size , & client_array_address , & client_array_base ) )
! = SP_ERROR_NONE )
{
g_DbgReporter . GenerateError ( pContext , m_fnVoteResult , err , " Menu callback could not allocate %d bytes for client list. " , client_array_size * sizeof ( cell_t ) ) ;
no_call = true ;
} else {
cell_t target_offs = sizeof ( cell_t ) * results - > num_clients ;
cell_t * cur_index = client_array_base ;
cell_t * cur_array ;
for ( unsigned int i = 0 ; i < results - > num_clients ; i + + )
{
/* Copy the array index */
* cur_index = target_offs ;
/* Get the current array address */
cur_array = ( cell_t * ) ( ( char * ) cur_index + target_offs ) ;
/* Store information */
cur_array [ 0 ] = results - > client_list [ i ] . client ;
cur_array [ 1 ] = results - > client_list [ i ] . item ;
/* Adjust for the new target by subtracting one indirection
* and adding one array .
*/
target_offs + = ( sizeof ( cell_t ) * 2 ) - sizeof ( cell_t ) ;
cur_index + + ;
}
}
}
/* Second array */
cell_t item_array_address = - 1 ;
cell_t * item_array_base = NULL ;
cell_t item_array_size = results - > num_items + ( results - > num_items * 2 ) ;
if ( item_array_size )
{
if ( ( err = pContext - > HeapAlloc ( item_array_size , & item_array_address , & item_array_base ) )
! = SP_ERROR_NONE )
{
g_DbgReporter . GenerateError ( pContext , m_fnVoteResult , err , " Menu callback could not allocate %d bytes for item list. " , item_array_size ) ;
no_call = true ;
} else {
cell_t target_offs = sizeof ( cell_t ) * results - > num_items ;
cell_t * cur_index = item_array_base ;
cell_t * cur_array ;
for ( unsigned int i = 0 ; i < results - > num_items ; i + + )
{
/* Copy the array index */
* cur_index = target_offs ;
/* Get the current array address */
cur_array = ( cell_t * ) ( ( char * ) cur_index + target_offs ) ;
/* Store information */
cur_array [ 0 ] = results - > item_list [ i ] . item ;
cur_array [ 1 ] = results - > item_list [ i ] . count ;
/* Adjust for the new target by subtracting one indirection
* and adding one array .
*/
target_offs + = ( sizeof ( cell_t ) * 2 ) - sizeof ( cell_t ) ;
cur_index + + ;
}
}
}
/* Finally, push everything */
if ( ! no_call )
{
m_pVoteResults - > PushCell ( menu - > GetHandle ( ) ) ;
m_pVoteResults - > PushCell ( results - > num_votes ) ;
m_pVoteResults - > PushCell ( results - > num_clients ) ;
m_pVoteResults - > PushCell ( client_array_address ) ;
m_pVoteResults - > PushCell ( results - > num_items ) ;
m_pVoteResults - > PushCell ( item_array_address ) ;
m_pVoteResults - > Execute ( NULL ) ;
}
/* Free what we allocated, in reverse order as required */
if ( item_array_address ! = - 1 )
{
pContext - > HeapPop ( item_array_address ) ;
}
if ( client_array_address ! = - 1 )
{
pContext - > HeapPop ( client_array_address ) ;
}
}
}
bool CMenuHandler : : OnSetHandlerOption ( const char * option , const void * data )
{
if ( strcmp ( option , " set_vote_results_handler " ) = = 0 )
{
void * * array = ( void * * ) data ;
m_pVoteResults = ( IPluginFunction * ) array [ 0 ] ;
m_fnVoteResult = * ( cell_t * ) ( ( cell_t * ) array [ 1 ] ) ;
return true ;
}
return false ;
}
/**
* INLINE FUNCTIONS FOR NATIVES
*/
inline Handle_t MakePanelHandle ( IMenuPanel * panel , IPluginContext * pContext )
{
return g_HandleSys . CreateHandle ( g_MenuHelpers . GetPanelType ( ) , panel , pContext - > GetIdentity ( ) , g_pCoreIdent , NULL ) ;
}
inline HandleError ReadPanelHandle ( Handle_t hndl , IMenuPanel * * panel )
{
HandleSecurity sec ;
sec . pIdentity = g_pCoreIdent ;
sec . pOwner = NULL ;
return g_HandleSys . ReadHandle ( hndl , g_MenuHelpers . GetPanelType ( ) , & sec , ( void * * ) panel ) ;
}
inline IMenuStyle * GetStyleFromCell ( cell_t cell )
{
enum MenuStyle
{
MenuStyle_Default = 0 , /**< The "default" menu style for the mod */
MenuStyle_Valve = 1 , /**< The Valve provided menu style (Used on HL2DM) */
MenuStyle_Radio = 2 , /**< The simpler menu style commonly used on CS:S */
} ;
if ( cell = = MenuStyle_Valve )
{
return & g_ValveMenuStyle ;
} else if ( cell = = MenuStyle_Radio
& & g_RadioMenuStyle . IsSupported ( ) )
{
return & g_RadioMenuStyle ;
}
return g_Menus . GetDefaultStyle ( ) ;
}
/***********************************
* * * * NATIVE DEFINITIONS * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static cell_t CreateMenu ( IPluginContext * pContext , const cell_t * params )
{
IMenuStyle * style = g_Menus . GetDefaultStyle ( ) ;
IPluginFunction * pFunction ;
if ( ( pFunction = pContext - > GetFunctionById ( params [ 1 ] ) ) = = NULL )
{
return pContext - > ThrowNativeError ( " Function id %x is invalid " , params [ 1 ] ) ;
}
CMenuHandler * handler = g_MenuHelpers . GetMenuHandler ( pFunction , params [ 2 ] ) ;
IBaseMenu * menu = style - > CreateMenu ( handler , pContext - > GetIdentity ( ) ) ;
Handle_t hndl = menu - > GetHandle ( ) ;
if ( ! hndl )
{
menu - > Destroy ( ) ;
return BAD_HANDLE ;
}
return hndl ;
}
static cell_t DisplayMenu ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > Display ( params [ 2 ] , params [ 3 ] ) ? 1 : 0 ;
}
static cell_t DisplayMenuAtItem ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > DisplayAtItem ( params [ 2 ] , params [ 4 ] , params [ 3 ] ) ? 1 : 0 ;
}
static cell_t VoteMenu ( IPluginContext * pContext , const cell_t * params )
{
if ( g_Menus . IsVoteInProgress ( ) )
{
return pContext - > ThrowNativeError ( " A vote is already in progress " ) ;
}
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
cell_t * addr ;
pContext - > LocalToPhysAddr ( params [ 2 ] , & addr ) ;
2009-05-31 01:59:55 +02:00
cell_t flags = 0 ;
if ( params [ 0 ] > = 5 )
{
flags = params [ 5 ] ;
}
if ( ! g_Menus . StartVote ( menu , params [ 3 ] , addr , params [ 4 ] , flags ) )
2008-03-30 09:00:22 +02:00
{
return 0 ;
}
return 1 ;
}
static cell_t AddMenuItem ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
char * info ;
ItemDrawInfo dr ;
pContext - > LocalToString ( params [ 2 ] , & info ) ;
pContext - > LocalToString ( params [ 3 ] , ( char * * ) & dr . display ) ;
dr . style = params [ 4 ] ;
return menu - > AppendItem ( info , dr ) ? 1 : 0 ;
}
static cell_t InsertMenuItem ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
char * info ;
ItemDrawInfo dr ;
pContext - > LocalToString ( params [ 3 ] , & info ) ;
pContext - > LocalToString ( params [ 4 ] , ( char * * ) & dr . display ) ;
dr . style = params [ 5 ] ;
return menu - > InsertItem ( params [ 2 ] , info , dr ) ? 1 : 0 ;
}
static cell_t RemoveMenuItem ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > RemoveItem ( params [ 2 ] ) ? 1 : 0 ;
}
static cell_t RemoveAllMenuItems ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
menu - > RemoveAllItems ( ) ;
return 1 ;
}
static cell_t GetMenuItem ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
ItemDrawInfo dr ;
const char * info ;
if ( ( info = menu - > GetItemInfo ( params [ 2 ] , & dr ) ) = = NULL )
{
return 0 ;
}
pContext - > StringToLocalUTF8 ( params [ 3 ] , params [ 4 ] , info , NULL ) ;
pContext - > StringToLocalUTF8 ( params [ 6 ] , params [ 7 ] , dr . display ? dr . display : " " , NULL ) ;
cell_t * addr ;
pContext - > LocalToPhysAddr ( params [ 5 ] , & addr ) ;
* addr = dr . style ;
return 1 ;
}
static cell_t SetMenuPagination ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > SetPagination ( params [ 2 ] ) ? 1 : 0 ;
}
static cell_t GetMenuPagination ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > GetPagination ( ) ;
}
static cell_t GetMenuItemCount ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > GetItemCount ( ) ;
}
static cell_t SetMenuTitle ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
2008-05-10 11:23:55 +02:00
g_SourceMod . SetGlobalTarget ( SOURCEMOD_SERVER_LANGUAGE ) ;
2008-03-30 09:00:22 +02:00
char buffer [ 1024 ] ;
g_SourceMod . FormatString ( buffer , sizeof ( buffer ) , pContext , params , 2 ) ;
menu - > SetDefaultTitle ( buffer ) ;
return 1 ;
}
static cell_t GetMenuTitle ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
size_t written ;
const char * title = menu - > GetDefaultTitle ( ) ;
pContext - > StringToLocalUTF8 ( params [ 2 ] , params [ 3 ] , title , & written ) ;
return ( cell_t ) written ;
}
static cell_t CreatePanelFromMenu ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
IMenuPanel * panel = menu - > CreatePanel ( ) ;
hndl = MakePanelHandle ( panel , pContext ) ;
if ( ! hndl )
{
panel - > DeleteThis ( ) ;
}
return hndl ;
}
static cell_t GetMenuExitButton ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return ( ( menu - > GetMenuOptionFlags ( ) & MENUFLAG_BUTTON_EXIT ) = = MENUFLAG_BUTTON_EXIT ) ? 1 : 0 ;
}
static cell_t GetMenuExitBackButton ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return ( ( menu - > GetMenuOptionFlags ( ) & MENUFLAG_BUTTON_EXITBACK ) = = MENUFLAG_BUTTON_EXIT ) ? 1 : 0 ;
}
static cell_t SetMenuExitButton ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
unsigned int flags = menu - > GetMenuOptionFlags ( ) ;
if ( params [ 2 ] )
{
flags | = MENUFLAG_BUTTON_EXIT ;
} else {
flags & = ~ MENUFLAG_BUTTON_EXIT ;
}
menu - > SetMenuOptionFlags ( flags ) ;
unsigned int new_flags = menu - > GetMenuOptionFlags ( ) ;
return ( flags = = new_flags ) ;
}
2010-02-27 02:56:02 +01:00
static cell_t SetMenuNoVoteButton ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
unsigned int flags = menu - > GetMenuOptionFlags ( ) ;
if ( params [ 2 ] )
{
flags | = MENUFLAG_BUTTON_NOVOTE ;
} else {
flags & = ~ MENUFLAG_BUTTON_NOVOTE ;
}
menu - > SetMenuOptionFlags ( flags ) ;
unsigned int new_flags = menu - > GetMenuOptionFlags ( ) ;
return ( flags = = new_flags ) ;
}
2008-03-30 09:00:22 +02:00
static cell_t SetMenuExitBackButton ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
unsigned int flags = menu - > GetMenuOptionFlags ( ) ;
if ( params [ 2 ] )
{
flags | = MENUFLAG_BUTTON_EXITBACK ;
} else {
flags & = ~ MENUFLAG_BUTTON_EXITBACK ;
}
menu - > SetMenuOptionFlags ( flags ) ;
return 1 ;
}
static cell_t CancelMenu ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
g_Menus . CancelMenu ( menu ) ;
return 1 ;
}
static cell_t IsVoteInProgress ( IPluginContext * pContext , const cell_t * params )
{
return g_Menus . IsVoteInProgress ( ) ? 1 : 0 ;
}
static cell_t GetMenuStyle ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > GetDrawStyle ( ) - > GetHandle ( ) ;
}
static cell_t GetMenuStyleHandle ( IPluginContext * pContext , const cell_t * params )
{
IMenuStyle * style = GetStyleFromCell ( params [ 1 ] ) ;
if ( ! style )
{
return BAD_HANDLE ;
}
return style - > GetHandle ( ) ;
}
static cell_t CreatePanel ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuStyle * style ;
if ( hndl ! = 0 )
{
if ( ( err = g_Menus . ReadStyleHandle ( params [ 1 ] , & style ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " MenuStyle handle %x is invalid (error %d) " , hndl , err ) ;
}
} else {
style = g_Menus . GetDefaultStyle ( ) ;
}
IMenuPanel * panel = style - > CreatePanel ( ) ;
hndl = MakePanelHandle ( panel , pContext ) ;
if ( ! hndl )
{
panel - > DeleteThis ( ) ;
return BAD_HANDLE ;
}
return hndl ;
}
static cell_t CreateMenuEx ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuStyle * style ;
if ( hndl ! = 0 )
{
if ( ( err = g_Menus . ReadStyleHandle ( params [ 1 ] , & style ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " MenuStyle handle %x is invalid (error %d) " , hndl , err ) ;
}
} else {
style = g_Menus . GetDefaultStyle ( ) ;
}
IPluginFunction * pFunction ;
if ( ( pFunction = pContext - > GetFunctionById ( params [ 2 ] ) ) = = NULL )
{
return pContext - > ThrowNativeError ( " Function id %x is invalid " , params [ 2 ] ) ;
}
CMenuHandler * handler = g_MenuHelpers . GetMenuHandler ( pFunction , params [ 3 ] ) ;
IBaseMenu * pMenu = style - > CreateMenu ( handler , pContext - > GetIdentity ( ) ) ;
hndl = pMenu - > GetHandle ( ) ;
if ( ! hndl )
{
pMenu - > Destroy ( ) ;
return BAD_HANDLE ;
}
return hndl ;
}
static cell_t GetClientMenu ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 2 ] ;
HandleError err ;
IMenuStyle * style ;
if ( hndl ! = 0 )
{
if ( ( err = g_Menus . ReadStyleHandle ( params [ 1 ] , & style ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " MenuStyle handle %x is invalid (error %d) " , hndl , err ) ;
}
} else {
style = g_Menus . GetDefaultStyle ( ) ;
}
return style - > GetClientMenu ( params [ 1 ] , NULL ) ;
}
static cell_t CancelClientMenu ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 3 ] ;
HandleError err ;
IMenuStyle * style ;
if ( hndl ! = 0 )
{
if ( ( err = g_Menus . ReadStyleHandle ( params [ 1 ] , & style ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " MenuStyle handle %x is invalid (error %d) " , hndl , err ) ;
}
} else {
style = g_Menus . GetDefaultStyle ( ) ;
}
return style - > CancelClientMenu ( params [ 1 ] , params [ 2 ] ? true : false ) ? 1 : 0 ;
}
static cell_t GetMaxPageItems ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuStyle * style ;
if ( hndl ! = 0 )
{
if ( ( err = g_Menus . ReadStyleHandle ( params [ 1 ] , & style ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " MenuStyle handle %x is invalid (error %d) " , hndl , err ) ;
}
} else {
style = g_Menus . GetDefaultStyle ( ) ;
}
return style - > GetMaxPageItems ( ) ;
}
static cell_t GetPanelStyle ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return panel - > GetParentStyle ( ) - > GetHandle ( ) ;
}
static cell_t SetPanelTitle ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
char * text ;
pContext - > LocalToString ( params [ 2 ] , & text ) ;
panel - > DrawTitle ( text , params [ 3 ] ? true : false ) ;
return 1 ;
}
static cell_t DrawPanelItem ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
ItemDrawInfo dr ;
pContext - > LocalToString ( params [ 2 ] , ( char * * ) & dr . display ) ;
dr . style = params [ 3 ] ;
return panel - > DrawItem ( dr ) ;
}
static cell_t DrawPanelText ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
char * text ;
pContext - > LocalToString ( params [ 2 ] , & text ) ;
return panel - > DrawRawLine ( text ) ? 1 : 0 ;
}
static cell_t CanPanelDrawFlags ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return panel - > CanDrawItem ( params [ 2 ] ) ;
}
static cell_t SendPanelToClient ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
IPluginFunction * pFunction ;
if ( ( pFunction = pContext - > GetFunctionById ( params [ 3 ] ) ) = = NULL )
{
return pContext - > ThrowNativeError ( " Function id %x is invalid " , params [ 3 ] ) ;
}
CPanelHandler * handler = g_MenuHelpers . GetPanelHandler ( pFunction ) ;
if ( ! panel - > SendDisplay ( params [ 2 ] , handler , params [ 4 ] ) )
{
g_MenuHelpers . FreePanelHandler ( handler ) ;
}
return 1 ;
}
static cell_t SetPanelKeys ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return panel - > SetSelectableKeys ( params [ 2 ] ) ;
}
static cell_t GetPanelCurrentKey ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return panel - > GetCurrentKey ( ) ;
}
static cell_t GetPanelTextRemaining ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return panel - > GetAmountRemaining ( ) ;
}
static cell_t SetPanelCurrentKey ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IMenuPanel * panel ;
if ( ( err = ReadPanelHandle ( hndl , & panel ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return panel - > SetCurrentKey ( params [ 2 ] ) ? 1 : 0 ;
}
static cell_t RedrawMenuItem ( IPluginContext * pContext , const cell_t * params )
{
if ( ! s_pCurPanel )
{
return pContext - > ThrowNativeError ( " You can only call this once from a MenuAction_DisplayItem callback " ) ;
}
char * str ;
pContext - > LocalToString ( params [ 1 ] , & str ) ;
ItemDrawInfo dr = * s_CurDrawInfo ;
dr . display = str ;
if ( ( s_CurPanelReturn = s_pCurPanel - > DrawItem ( dr ) ) ! = 0 )
{
s_pCurPanel = NULL ;
}
return s_CurPanelReturn ;
}
static cell_t GetMenuOptionFlags ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
return menu - > GetMenuOptionFlags ( ) ;
}
static cell_t SetMenuOptionFlags ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
menu - > SetMenuOptionFlags ( params [ 2 ] ) ;
return 1 ;
}
static cell_t CancelVote ( IPluginContext * pContxt , const cell_t * params )
{
if ( ! g_Menus . IsVoteInProgress ( ) )
{
return pContxt - > ThrowNativeError ( " No vote is in progress " ) ;
}
g_Menus . CancelVoting ( ) ;
return 1 ;
}
static cell_t SetVoteResultCallback ( IPluginContext * pContext , const cell_t * params )
{
Handle_t hndl = ( Handle_t ) params [ 1 ] ;
HandleError err ;
IBaseMenu * menu ;
if ( ( err = g_Menus . ReadMenuHandle ( params [ 1 ] , & menu ) ) ! = HandleError_None )
{
return pContext - > ThrowNativeError ( " Menu handle %x is invalid (error %d) " , hndl , err ) ;
}
IPluginFunction * pFunction = pContext - > GetFunctionById ( params [ 2 ] ) ;
if ( ! pFunction )
{
return pContext - > ThrowNativeError ( " Invalid function %x " , params [ 2 ] ) ;
}
void * array [ 2 ] ;
array [ 0 ] = pFunction ;
array [ 1 ] = ( void * ) & params [ 2 ] ;
IMenuHandler * pHandler = menu - > GetHandler ( ) ;
if ( ! pHandler - > OnSetHandlerOption ( " set_vote_results_handler " , ( const void * ) array ) )
{
return pContext - > ThrowNativeError ( " The given menu does not support this option " ) ;
}
return 1 ;
}
static cell_t CheckVoteDelay ( IPluginContext * pContext , const cell_t * params )
{
return g_Menus . GetRemainingVoteDelay ( ) ;
}
static cell_t GetMenuSelectionPosition ( IPluginContext * pContext , const cell_t * params )
{
if ( ! s_CurSelectPosition )
{
return pContext - > ThrowNativeError ( " Can only be called from inside a MenuAction_Select callback " ) ;
}
return * s_CurSelectPosition ;
}
2008-05-17 07:12:52 +02:00
static cell_t IsClientInVotePool ( IPluginContext * pContext , const cell_t * params )
{
int client ;
IGamePlayer * pPlayer ;
client = params [ 1 ] ;
if ( ( pPlayer = g_Players . GetPlayerByIndex ( client ) ) = = NULL )
{
return pContext - > ThrowNativeError ( " Invalid client index %d " , client ) ;
}
if ( ! g_Menus . IsVoteInProgress ( ) )
{
return pContext - > ThrowNativeError ( " No vote is in progress " ) ;
}
return g_Menus . IsClientInVotePool ( client ) ? 1 : 0 ;
}
static cell_t RedrawClientVoteMenu ( IPluginContext * pContext , const cell_t * params )
{
int client ;
IGamePlayer * pPlayer ;
client = params [ 1 ] ;
if ( ( pPlayer = g_Players . GetPlayerByIndex ( client ) ) = = NULL )
{
return pContext - > ThrowNativeError ( " Invalid client index %d " , client ) ;
}
if ( ! g_Menus . IsVoteInProgress ( ) )
{
return pContext - > ThrowNativeError ( " No vote is in progress " ) ;
}
if ( ! g_Menus . IsClientInVotePool ( client ) )
{
return pContext - > ThrowNativeError ( " Client is not in the voting pool " ) ;
}
2009-05-31 01:59:55 +02:00
bool revote = true ;
if ( params [ 0 ] > = 2 & & ! params [ 2 ] )
{
revote = false ;
}
return g_Menus . RedrawClientVoteMenu2 ( client , revote ) ? 1 : 0 ;
2008-05-17 07:12:52 +02:00
}
2008-03-30 09:00:22 +02:00
class EmptyMenuHandler : public IMenuHandler
{
public :
} s_EmptyMenuHandler ;
static cell_t InternalShowMenu ( IPluginContext * pContext , const cell_t * params )
{
int client = params [ 1 ] ;
CPlayer * pPlayer = g_Players . GetPlayerByIndex ( client ) ;
if ( pPlayer = = NULL )
{
return pContext - > ThrowNativeError ( " Invalid client index %d " , client ) ;
}
else if ( ! pPlayer - > IsInGame ( ) )
{
return pContext - > ThrowNativeError ( " Client %d is not in game " , client ) ;
}
if ( ! g_RadioMenuStyle . IsSupported ( ) )
{
return pContext - > ThrowNativeError ( " Radio menus are not supported on this mod " ) ;
}
char * str ;
pContext - > LocalToString ( params [ 2 ] , & str ) ;
IMenuPanel * pPanel = g_RadioMenuStyle . MakeRadioDisplay ( str , params [ 4 ] ) ;
if ( pPanel = = NULL )
{
return 0 ;
}
IMenuHandler * pHandler ;
CPanelHandler * pActualHandler = NULL ;
if ( params [ 5 ] ! = - 1 )
{
IPluginFunction * pFunction = pContext - > GetFunctionById ( params [ 5 ] ) ;
if ( pFunction = = NULL )
{
return pContext - > ThrowNativeError ( " Invalid function index %x " , params [ 5 ] ) ;
}
pActualHandler = g_MenuHelpers . GetPanelHandler ( pFunction ) ;
}
if ( pActualHandler = = NULL )
{
pHandler = & s_EmptyMenuHandler ;
}
else
{
pHandler = pActualHandler ;
}
bool bSuccess = pPanel - > SendDisplay ( client , pHandler , params [ 3 ] ) ;
pPanel - > DeleteThis ( ) ;
if ( ! bSuccess & & pActualHandler ! = NULL )
{
g_MenuHelpers . FreePanelHandler ( pActualHandler ) ;
}
return bSuccess ? 1 : 0 ;
}
REGISTER_NATIVES ( menuNatives )
{
{ " AddMenuItem " , AddMenuItem } ,
{ " CanPanelDrawFlags " , CanPanelDrawFlags } ,
{ " CancelClientMenu " , CancelClientMenu } ,
{ " CancelMenu " , CancelMenu } ,
{ " CancelVote " , CancelVote } ,
{ " CheckVoteDelay " , CheckVoteDelay } ,
{ " CreateMenu " , CreateMenu } ,
{ " CreateMenuEx " , CreateMenuEx } ,
{ " CreatePanel " , CreatePanel } ,
{ " CreatePanelFromMenu " , CreatePanelFromMenu } ,
{ " DisplayMenu " , DisplayMenu } ,
{ " DisplayMenuAtItem " , DisplayMenuAtItem } ,
{ " DrawPanelItem " , DrawPanelItem } ,
{ " DrawPanelText " , DrawPanelText } ,
{ " GetClientMenu " , GetClientMenu } ,
{ " GetMaxPageItems " , GetMaxPageItems } ,
{ " GetMenuExitBackButton " , GetMenuExitBackButton } ,
{ " GetMenuExitButton " , GetMenuExitButton } ,
{ " GetMenuItem " , GetMenuItem } ,
{ " GetMenuItemCount " , GetMenuItemCount } ,
{ " GetMenuOptionFlags " , GetMenuOptionFlags } ,
{ " GetMenuPagination " , GetMenuPagination } ,
{ " GetMenuSelectionPosition " , GetMenuSelectionPosition } ,
{ " GetMenuStyle " , GetMenuStyle } ,
{ " GetMenuStyleHandle " , GetMenuStyleHandle } ,
{ " GetMenuTitle " , GetMenuTitle } ,
{ " GetPanelTextRemaining " , GetPanelTextRemaining } ,
{ " GetPanelCurrentKey " , GetPanelCurrentKey } ,
{ " GetPanelStyle " , GetPanelStyle } ,
{ " InsertMenuItem " , InsertMenuItem } ,
{ " InternalShowMenu " , InternalShowMenu } ,
2008-05-17 07:12:52 +02:00
{ " IsClientInVotePool " , IsClientInVotePool } ,
2008-03-30 09:00:22 +02:00
{ " IsVoteInProgress " , IsVoteInProgress } ,
2008-05-17 07:12:52 +02:00
{ " RedrawClientVoteMenu " , RedrawClientVoteMenu } ,
2008-03-30 09:00:22 +02:00
{ " RedrawMenuItem " , RedrawMenuItem } ,
{ " RemoveAllMenuItems " , RemoveAllMenuItems } ,
{ " RemoveMenuItem " , RemoveMenuItem } ,
{ " SendPanelToClient " , SendPanelToClient } ,
{ " SetMenuExitBackButton " , SetMenuExitBackButton } ,
{ " SetMenuExitButton " , SetMenuExitButton } ,
{ " SetMenuOptionFlags " , SetMenuOptionFlags } ,
{ " SetMenuPagination " , SetMenuPagination } ,
{ " SetMenuTitle " , SetMenuTitle } ,
{ " SetPanelCurrentKey " , SetPanelCurrentKey } ,
{ " SetPanelTitle " , SetPanelTitle } ,
{ " SetPanelKeys " , SetPanelKeys } ,
{ " SetVoteResultCallback " , SetVoteResultCallback } ,
{ " VoteMenu " , VoteMenu } ,
2010-02-27 02:56:02 +01:00
{ " SetMenuNoVoteButton " , SetMenuNoVoteButton } ,
2008-03-30 09:00:22 +02:00
{ NULL , NULL } ,
} ;
2009-05-31 01:59:55 +02:00