New AMXX Menu System

For scripting examples for learning how to use AMXX.
User avatar
Archive-Poster
Posts: 1067
Gender:
United States of America

New AMXX Menu System

Post by Archive-Poster »

This tutorial should give you a deep understanding of the new AMXX menu system.

If you are having trouble following this tutorial, I suggest you read Pawn Picture Tutorial.

Basic Menu - for interacting within a plugin or having a player select between objects ( such as a weapon menu )
Player Menu - for interacting with a selected player ( such as a kick menu )
Basic Vote Menu - for getting a preference from players ( such as a mapvote menu )
Sub-Menu - for having a menu within a menu ( such as a multilayered admin menu )
Advanced Vote Menu - for getting a more advanced preference ( such as a Galileo's map menu )
Multiple Menus with 1 Handler - for having multiple menus and only using a single menu_handler
Menu Items with Callbacks - for enabling/disabling menu items ( such as a Shop menu that disables items if you don't have enough money )
newmenus.inc - some helpful things from newmenus.inc
End Notes - some tips with the new menus


Basic Menu

Code: Select all

#include <amxmodx>

 public plugin_init()
 {
    //..stuff for your plugin

    register_clcmd( "my_awesome_menu","AwesomeMenu" );
    //note that we do not need to register the menu anymore, but just a way to get to it
 }
 //lets make the function that will make the menu
 public AwesomeMenu( id )
 {
    //first we need to make a variable that will hold the menu
    new menu = menu_create( "\rLook at this awesome Menu!:", "menu_handler" );
    //Note - menu_create
    //The first parameter  is what the menu will be titled ( what is at the very top )
    //The second parameter is the function that will deal/handle with the menu ( which key was pressed, and what to do )

    //Now lets add some things to select from the menu
    menu_additem( menu, "\wI'm Selection #1", "", 0 );
    menu_additem( menu, "\wI'm Selection #2", "", 0 );
    menu_additem( menu, "\wI'm Secret Selection #3", "", ADMIN_ADMIN );
    //Note - menu_additem
    //The first parameter is which menu we will be adding this item/selection to
    //The second parameter is what text will appear on the menu ( Note that it is preceeded with a number of which item it is )
    //The third parameter is data that we want to send with this item
    //The fourth parameter is which admin flag we want to be able to access this item ( Refer to the admin flags from the amxconst.inc )
    //The fifth parameter is the callback for enabling/disabling items, by default we will omit this and use no callback ( default value of -1 ) Refer to the Menu Items with Callbacks section for more information.

    //Set a property on the menu
    menu_setprop( menu, MPROP_EXIT, MEXIT_ALL );
    //Note - menu_setprop
    //The first parameter is the menu to modify
    //The second parameter is what to modify ( found in amxconst.inc )
    //The third parameter is what to modify it to ( in this case, we are adding a option to the menu that will exit the menu. setting it to MEXIT_NEVER will disable this option )
    //Additional note - MEXIT_ALL is the default property for MPROP_EXIT, so this is redundant

    //Lets display the menu
    menu_display( id, menu, 0 );
    //Note - menu_display
    //The first parameter is which index to show it to ( you cannot show this to everyone at once )
    //The second parameter is which menu to show them ( in this case, the one we just made )
    //The third parameter is which page to start them on
 }
 //okay, we showed them the menu, now lets handle it ( looking back at menu_create, we are going to use that function )
 public menu_handler( id, menu, item )
 {
    //Because of the simplicity of this menu, we can switch for which item was pressed
    //Note - this is zero-based, so the first item is 0
    switch( item )
    {
        case 0:
        {
            client_print( id, print_chat, "Hooray! You selected the Awesome 1st Selection" );
            
            //Note that if we dont want to continue through the function, we can't just end with a return. We want to kill the menu first
            menu_destroy( menu );
            return PLUGIN_HANDLED;
        }
        case 1:
        {
            client_print( id, print_chat, "OH NO! You selected the Awesome 2nd Selection! BEWARE!" );
        }
        case 2:
        {
            client_print( id, print_chat, "You have selected the Awesome Admin Selection! Hail Teh Bail!" );
        }
        case MENU_EXIT:
        {
            client_print( id, print_chat, "You exited the menu... what a bummer!" );
        }
    }

    //lets finish up this function by destroying the menu with menu_destroy, and a return
    menu_destroy( menu );
    return PLUGIN_HANDLED;
 }
Player Menu
*Note - You should have an understanding of the Basic Menu first.

Code: Select all

#include <amxmodx>
 #include <fun>

 public plugin_init()
 {
    //Register a way to get to your menu...
    register_clcmd( "my_player_menu","AwesomeMenu" );
 }

 public AwesomeMenu( id )
 {
    //Create a variable to hold the menu
    new menu = menu_create( "\rLook at this Player Menu!:", "menu_handler" );

    //We will need to create some variables so we can loop through all the players
    new players[32], pnum, tempid;

    //Some variables to hold information about the players
    new szName[32], szUserId[32];

    //Fill players with available players
    get_players( players, pnum, "a" ); // flag "a" because we are going to add health to players, but this is just for this specific case

    //Start looping through all players
    for ( new i; i<pnum; i++ )
    {
        //Save a tempid so we do not re-index
        tempid = players[i];

        //Get the players name and userid as strings
        get_user_name( tempid, szName, charsmax( szName ) );
        //We will use the data parameter to send the userid, so we can identify which player was selected in the handler
        formatex( szUserId, charsmax( szUserId ), "%d", get_user_userid( tempid ) );

        //Add the item for this player
        menu_additem( menu, szName, szUserId, 0 );
    }

    //We now have all players in the menu, lets display the menu
    menu_display( id, menu, 0 );
 }

 public menu_handler( id, menu, item )
 {
    //Do a check to see if they exited because menu_item_getinfo ( see below ) will give an error if the item is MENU_EXIT
    if ( item == MENU_EXIT )
    {
        menu_destroy( menu );
        return PLUGIN_HANDLED;
    }

    //now lets create some variables that will give us information about the menu and the item that was pressed/chosen
    new szData[6], szName[64];
    new _access, item_callback;
    //heres the function that will give us that information ( since it doesnt magicaly appear )
    menu_item_getinfo( menu, item, _access, szData,charsmax( szData ), szName,charsmax( szName ), item_callback );

    //Get the userid of the player that was selected
    new userid = str_to_num( szData );

    //Try to retrieve player index from its userid
    new player = find_player( "k", userid ); // flag "k" : find player from userid

    //If player == 0, this means that the player's userid cannot be found
    //If the player is still alive ( we had retrieved alive players when formating the menu but some players may have died before id could select an item from the menu )
    if ( player && is_user_alive( player ) )
    {
        //Set their health to 100
        set_user_health( player, 100 );
    }

    menu_destroy( menu );
    return PLUGIN_HANDLED;
 }
Here is a generic player menu from ConnorMcLeod that you can use to easily add to your plugin

Code: Select all

#include <amxmodx>
#include <amxmisc>

#define VERSION "0.0.1"
#define PLUGIN "Players Menu Generic"

public plugin_init()
{
    register_plugin( PLUGIN, VERSION, "ConnorMcLeod" );
    register_clcmd( "say /players", "ClCmd_Menu", ADMIN_RCON );
}

public ClCmd_Menu( id, lvl, cid )
{
    if ( cmd_access( id, lvl, cid, 0 ) )
    {
        new iMenu = MakePlayerMenu( id, "Players Menu Misc", "PlayersMenuHandler" );
        menu_setprop( iMenu, MPROP_NUMBER_COLOR, "\y" );
        menu_display( id, iMenu );
    }
    return PLUGIN_HANDLED;
}

enum ( <<= 1 )
{
    PLMENU_OBEY_IMMUNITY = 1,
    PLMENU_ALLOW_SELF,
    PLMENU_ONLY_ALIVE,
    PLMENU_NO_BOTS
}

MakePlayerMenu( id, const szMenuTitle[], const szMenuHandler[], iFlags = PLMENU_OBEY_IMMUNITY )
{
    new iMenu = menu_create( szMenuTitle, szMenuHandler );
    new bool:bIsSuperAdmin;
    if ( iFlags & PLMENU_OBEY_IMMUNITY )
    {
        bIsSuperAdmin = !!( get_user_flags( id ) & ADMIN_RCON );
    }

    new iPlayers[32], iNum, iPlayer, szPlayerName[32], szUserId[32];
    new szFlags[4] = "h";
    if ( iFlags & PLMENU_ONLY_ALIVE )
    {
        szFlags[++iNum] = 'a';
    }
    if ( flags & PLMENU_NO_BOTS )
    {
        szFlags[++iNum] = 'c';
    }

    get_players( iPlayers, iNum, szFlags );

    for ( --iNum; iNum >= 0; iNum-- )
    {
        iPlayer = iPlayers[iNum];
        get_user_name( iPlayer, szPlayerName, charsmax( szPlayerName ) );

        if ( iFlags & PLMENU_OBEY_IMMUNITY && !bIsSuperAdmin
        && ( ( get_user_flags( iPlayer ) & ADMIN_IMMUNITY ) && 
             ( ( iFlags & PLMENU_ALLOW_SELF ) ? ( id != iPlayer ) : true ) )    )
        {
            menu_addtext( iMenu, szPlayerName );
        }
        else
        {
            formatex( szUserId, charsmax( szUserId ), "%d", get_user_userid( iPlayer ) );
            menu_additem( iMenu, szPlayerName, szUserId, 0 );
        }
    }

    return iMenu;
}

public PlayersMenuHandler_Sample( id, iMenu, iItem )
{
    if ( iItem == MENU_EXIT )
    {
        menu_destroy( iMenu );
        return PLUGIN_HANDLED;
    }

    new szUserId[32], szPlayerName[32], iPlayer, iAccess, iCallback;
    menu_item_getinfo( iMenu, iItem, iCallback, szUserId, charsmax( szUserId ), szPlayerName, charsmax( szPlayerName ), iCallback );

    if ( ( iPlayer = find_player( "k", str_to_num( szUserId ) ) )  )
    {
        new szName[32];
        get_user_name( iPlayer, szName, charsmax( szName ) );
        client_print( id, print_chat, "You have chosen #%s %s %s", szUserId, szPlayerName, szName );
    }
    else
    {
        client_print( id, print_chat, "Player %s<%s> seems to be disconnected", szPlayerName, szAuthid );
    }
    menu_destroy( iMenu );
    return PLUGIN_HANDLED;
}
Basic Vote Menu
*Note - You should have an understanding of the Basic Menu first.

Code: Select all

#include <amxmodx>

 //This will hold the VoteMenu
 new gVoteMenu;
 //This will hold the votes for each option
 new gVotes[2];
 //This determines if a vote is already happening
 new gVoting;

 public plugin_init()
 {
    //Register a way to get to your vote...
    register_clcmd( "start_vote","StartVote" );
 }
 public StartVote( id )
 {
    //If there is already a vote, don't start another
    if ( gVoting )
    {
        client_print( id, print_chat, "There is already a vote going." );
        //We return PLUGIN_HANDLED so the person does not get Unknown Command in console
        return PLUGIN_HANDLED;
    }

    //Reset vote counts from any previous votes
    gVotes[0] = gVotes[1] = 0;
    //Note that if you have more than 2 options, it would be better to use the line below:
    //arrayset( gVotes, 0, sizeof gVotes );

    //Store the menu in the global
    gVoteMenu = menu_create( "\rLook at this Vote Menu!:", "menu_handler" );

    //Add some vote options
    menu_additem( gVoteMenu, "Vote Option 1", "", 0 );
    menu_additem( gVoteMenu, "Vote Option 2", "", 0 );

    //We will need to create some variables so we can loop through all the players
    new players[32], pnum, tempid;

    //Fill players with available players
    get_players( players, pnum );

    //Start looping through all players to show the vote to
    for ( new i; i < pnum; i++ )
    {
        //Save a tempid so we do not re-index
        tempid = players[i];

        //Show the vote to this player
        menu_display( tempid, gVoteMenu, 0 );

        //Increase how many players are voting
        gVoting++;
    }

    //End the vote in 10 seconds
    set_task(10.0, "EndVote" );

    return PLUGIN_HANDLED;
 }
 public menu_handler( id, menu, item )
 {
    //If the menu was exited or if there is not a vote
    if ( item == MENU_EXIT || !gVoting )
    {
        //Note were not destroying the menu
        return PLUGIN_HANDLED;
    }

    //Increase the votes for what they selected
    gVotes[ item ]++;

    //Note were not destroying the menu
    return PLUGIN_HANDLED;
 }
 public EndVote()
 {
    //If the first option recieved the most votes
    if ( gVotes[0] > gVotes[1] )
        client_print(0, print_chat, "First option recieved most votes (%d )", gVotes[0] );

    //Else if the second option recieved the most votes
    else if ( gVotes[0] < gVotes[1] )
        client_print(0, print_chat, "Second option recieved most votes (%d )", gVotes[1] );

    //Otherwise the vote tied
    else
        client_print(0, print_chat, "The vote tied at %d votes each.", gVotes[0] );

    //Don't forget to destroy the menu now that we are completely done with it
    menu_destroy( gVoteMenu );

    //Reset that no players are voting
    gVoting = 0;
 }
Sub-Menu
*Note - You should have an understanding of the Basic Menu first.

Code: Select all

#include <amxmodx>

 public plugin_init()
 {
    register_clcmd( "my_awesome_menu","AwesomeMenu" );
 }
 public AwesomeMenu( id )
 {
    new menu = menu_create( "\rLook at this awesome Menu!:", "menu_handler" )

    menu_additem( menu, "\wI'm Selection #1", "", 0 );
    menu_additem( menu, "\wGo to SubMenu", "", 0 );

    menu_display( id, menu, 0 );
 }
 public menu_handler( id, menu, item )
 {
    switch( item )
    {
        case 0:
        {
            client_print( id, print_chat, "Hooray! You selected the Awesome 1st Selection" );
        }
        case 1:
        {
            //Send them to the submenu
            SubMenu( id );
        }
        case MENU_EXIT:
        {
            //Do nothing?
        }
    }

    menu_destroy( menu );
    return PLUGIN_HANDLED;
 }
 SubMenu( id )
 {
    //Note that we will be using a different menu handler
    new menu = menu_create( "\rLook at this awesome Sub-Menu!:", "submenu_handler" )

    menu_additem( menu, "\wI'm Sub-Selection #1", "", 0 );
    menu_additem( menu, "\wI'm Sub-Selection #2", "", 0 );

    menu_display( id, menu, 0 );
 }
 public submenu_handler( id, menu, item )
 {
    switch( item )
    {
        case 0:
        {
            client_print( id, print_chat, "Hooray! You selected the Awesome 1st Sub-Selection" );
        }
        case 1:
        {
            client_print( id, print_chat, "OH NO! You selected the Awesome 2nd Sub-Selection! BEWARE!" );
        }
        case MENU_EXIT:
        {
            //If they are still connected
            if ( is_user_connected( id ) )
                //Lets send them back to the top menu
                AwesomeMenu( id );
        }
    }

    menu_destroy( menu );
    return PLUGIN_HANDLED;
 }
Advanced Vote Menu
*Note - You should have an understanding of the Basic Menu and the Basic Vote Menu first.

Code: Select all

#include <amxmisc>
 #include <fun>

 //How many different votes there will be in the menu
 #define MAX_VOTEIDS 7

 //How much "weight" a normal player's vote is worth
 #define WEIGHT_PLAYER 1
 //How much "weight" an admin's vote is worth
 #define WEIGHT_ADMIN 2

 new gVoteMenu;
 new gVotes[MAX_VOTEIDS];
 new gVoting;

 //This will store the voteids
 new gVoteID[MAX_VOTEIDS];

 public plugin_init()
 {
    register_clcmd( "start_vote","StartVote" );
 }
 public StartVote( id )
 {
    if ( gVoting )
    {
        client_print( id, print_chat, "There is already a vote going." );
        return PLUGIN_HANDLED;
    }

    //Reset vote counts from any previous votes
    arrayset( gVotes, 0, sizeof gVotes );

    gVoteMenu = menu_create( "\rWho should get 255 Health?", "menu_handler" );

    //Here you can do whatever you want to add your voteids.
    //We are going to use players for the example
    new players[32], pnum, tempid;
    get_players( players, pnum, "a" );

    //Variable for if the player was added to the vote
    new bool:player_added[33], voteid_count;

    new szName[32], szVoteId[10];

    //Loop through until we get enough voteids or run out of players
    while( voteid_count < MAX_VOTEIDS && voteid_count < pnum )
    {
        //Get a random player
        tempid = players[ random( pnum ) ];

        //If they haven't been added yet
        if ( !player_added[tempid] )
        {
            get_user_name( tempid, szName, charsmax( szName ) );

            //We are setting the data to the voteid number
            num_to_str( voteid_count, szVoteId, charsmax( szVoteId ) );

            menu_additem( gVoteMenu, szName, szVoteId, 0 );

            //Make sure we do not add them again
            player_added[tempid] = true;

            //Save the voteid as the user id for the player
            gVoteID[voteid_count] = get_user_userid( tempid );

            //Go to the next voteid
            voteid_count++;
        }
    }

    //Now we have all the voteids

    for ( new i; i < pnum; i++ )
    {
        //Save a tempid so we do not re-index
        tempid = players[i];

        //Show the vote to this player
        menu_display( tempid, gVoteMenu, 0 );

        //Increase how many players are voting by their weight
        if ( is_user_admin( tempid ) )
            gVoting += WEIGHT_ADMIN;
        else
            gVoting += WEIGHT_PLAYER;
    }

    set_task(10.0, "EndVote" );

    return PLUGIN_HANDLED;
 }
 public menu_handler( id, menu, item )
 {
    //If the menu was exited or if there is not a vote
    if ( item == MENU_EXIT || !gVoting )
    {
        return PLUGIN_HANDLED;
    }

    new szData[6], szName[64];
    new item_access, item_callback;
    menu_item_getinfo( menu, item, item_access, szData,charsmax( szData ), szName,charsmax( szName ), item_callback );

    //Get the voteid number that was selected
    new voteid_num = str_to_num( szData );

    //Increase the votes for what they selected by weight
    if ( is_user_admin( id ) )
        gVotes[voteid_num] += WEIGHT_ADMIN;
    else
        gVotes[voteid_num] += WEIGHT_PLAYER;

    return PLUGIN_HANDLED;
 }
 public EndVote()
 {
    //This will hold how many different votes were selected
    new votes_select;

    //This will hold the top 3 votes
    new votes[3];

    //This will hold the top 3 selected voteids
    new voteid[3];

    new i, j;

    //Loop through all the voteids
    for ( i=0; i<MAX_VOTEIDS; i++ )
    {
        //If the voteid recieved any votes
        if ( gVotes[i] )
        {
            //If we are still trying to get the top 3
            if ( votes_select < 3 )
            {
                //Save the data for the current voteid selected
                votes[votes_select] = gVotes[i];
                voteid[votes_select] = i;

                //Go to the next voteid that might have been selected
                votes_select++;
            }
            else
            {
                //Loop through all the top votes, replace any that are lower than the selected voteid
                for ( j=0; j<3; j++ )
                {
                    //If this one recieved less votes
                    if ( votes[j] < gVotes[i] )
                    {
                        //Change the data to the voteid with more votes
                        votes[j] = gVotes[i];
                        voteid[j] = i;

                        //Don't need to bother looking for more
                        break;
                    }
                }
            }
        }
    }

    //If noone voted
    if ( !votes_select )
    {
        client_print(0, print_chat, "CRICKEY! No one voted!" );
    }
    //Else if one voteid recieved all the votes
    else if ( votes_select == 1 )
    {
        //Get the player id from the voteid
        new player = find_player( "k", voteid[0]);
        VoteGiveHealth( player );
    }
    //Else if two different voteids recieved all the votes
    else if ( votes_select == 2 )
    {
        //If they recieved even votes
        if ( votes[0] == votes[1] )
        {
            //Give it to a random one
            client_print(0, print_chat, "Vote has tied. Choosing random from tied votes." );
            new player = find_player( "k", voteid[ random(2 ) ] );
            VoteGiveHealth( player );
        }

        //Else if the first recieved the most
        else if ( votes[0] > votes[1] )
        {
            //Give it to the first
            new player = find_player( "k", voteid[ 0 ] );
            VoteGiveHealth( player );
        }

        //Else the second recieved the most
        else
        {
            //Give it to the second
            new player = find_player( "k", voteid[ 1 ] );
            VoteGiveHealth( player );
        }
    }
    //Else there were at least 3 different votes
    else
    {
        //Here you might want to do run-off voting, but well just select a random one
        new player = find_player( "k", voteid[ random( MAX_VOTEIDS ) ] );
        client_print(0, print_chat, "Could not determine a winner. Selecting random." );
        VoteGiveHealth( player );
    }

    menu_destroy( gVoteMenu );
    gVoting = 0;
 }
 VoteGiveHealth( id )
 {
    if ( is_user_alive( id ) )
    {
        set_user_health( id, 255 );
        new szName[32];
        get_user_name( id, szName, charsmax( szName ) );
        client_print(0, print_chat, "Look that Kangaroo %s has 255 Health!", szName );
    }
 }
Multiple Menus with 1 Handler
*Note - You should have a good understanding of the Sub Menu first.

Code: Select all

#include <amxmodx>

 public plugin_init()
 {
    register_clcmd( "my_awesome_menu","AwesomeMenu" );
 }
 public AwesomeMenu( id )
 {
    new menu = menu_create( "\rLook at this awesome Menu!:", "menu_handler" )

    //Note that our data is 'm' to know it is from the main menu
    menu_additem( menu, "\wI'm Selection #1", "m", 0 );
    menu_additem( menu, "\wGo to SubMenu", "m", 0 );

    menu_display( id, menu, 0 );
 }
 SubMenu( id )
 {
    new menu = menu_create( "\rLook at this awesome Sub-Menu!:", "menu_handler" )

    //Note that our data is 's' to know it is from the sub menu
    menu_additem( menu, "\wI'm Sub-Selection #1", "s", 0 );
    menu_additem( menu, "\wI'm Sub-Selection #2", "s", 0 );

    menu_display( id, menu, 0 );
 }
 public menu_handler( id, menu, item )
 {
    if ( item == MENU_EXIT )
    {
        menu_destroy( menu );
        return PLUGIN_HANDLED;
    }

    new szData[6], szName[64];
    new item_access, item_callback;
    menu_item_getinfo( menu, item, item_access, szData,charsmax( szData ), szName,charsmax( szName ), item_callback );

    //Switch based on the first character of the data ( the 'm' or the 's')
    switch( szData[0] )
    {
        //All our main menu data will be handled in this case
        case 'm':
        {
            switch( item )
            {
                case 0:
                {
                    client_print( id, print_chat, "Hooray! You selected the Awesome 1st Selection" );
                }
                case 1:
                {
                    SubMenu( id );
                }
            }
        }
        //All our sub menu data will be handled in this case
        case 's':
        {
            switch( item )
            {
                case 0:
                {
                    client_print( id, print_chat, "Hooray! You selected the Awesome 1st Sub-Selection" );
                }
                case 1:
                {
                    client_print( id, print_chat, "OH NO! You selected the Awesome 2nd Sub-Selection! BEWARE!" );
                }
            }

            //Note that this is still only for our sub menu
            AwesomeMenu( id );
        }
    }

    menu_destroy( menu );
    return PLUGIN_HANDLED;
 }
Menu Items with Callbacks
*Note - You should have a good understanding of the Player Menu first.
*Additional Note - This example uses a respawn function specific for Counter-Strike

Code: Select all

#include <amxmodx>
 #include <hamsandwich>

 //Create a global variable to hold our callback
 new g_MenuCallback;

 public plugin_init()
 {
    register_clcmd( "my_player_menu","RespawnMenu" );

    //Create our callback and save it to our variable
    g_MenuCallback = menu_makecallback( "menuitem_callback" );
    //The first parameter is the public function to be called when a menu item is being shown.
 }
 public RespawnMenu( id )
 {
    new menu = menu_create( "\rRevive Player Menu!:", "menu_handler" );

    new players[32], pnum, tempid;
    new szName[32], szUserId[10];
    get_players( players, pnum );

    for ( new i; i < pnum; i++ )
    {
        tempid = players[i];
        get_user_name( tempid, szName, charsmax( szName ) );
        formatex( szUserId, charsmax( szUserId ), "%d", get_user_userid( tempid ) );

        //Add the item for this player with the callback
        menu_additem( menu, szName, szUserId, 0, g_MenuCallback );
        //Note that the last parameter that we usually omit is now filled with the callback variable

    }

    menu_display( id, menu, 0 );
 }
 //This is our callback function. Return ITEM_ENABLED, ITEM_DISABLED, or ITEM_IGNORE.
 public menuitem_callback( id, menu, item )
 {
    //Create some variables to hold information about the menu item
    new szData[6], szName[64];
    new item_access, item_callback;

    //Get information about the menu item
    menu_item_getinfo( menu, item, item_access, szData,charsmax( szData ), szName,charsmax( szName ), item_callback );
    //Note - item_callback should be equal to g_MenuCallback

    //Get which player the item is for
    new userid = str_to_num( szData );
    new player = find_player( "k", userid ); // flag "k" : find player from userid

    //If the user is alive, we want to disable reviving them
    if ( is_user_alive( tempid ) )
    {
        return ITEM_DISABLED;
    }

    //Otherwise we can just ignore the return value
    return ITEM_IGNORE;
    //Note that returning ITEM_ENABLED will override the admin flag check from menu_additem
 }
 public menu_handler( id, menu, item )
 {
    if ( item == MENU_EXIT )
    {
        menu_destroy( menu );
        return PLUGIN_HANDLED;
    }

    new szData[6], szName[64];
    new item_access, item_callback;
    menu_item_getinfo( menu, item, item_access, szData,charsmax( szData ), szName,charsmax( szName ), item_callback );

    //Get the id of the player that was selected
    new userid = str_to_num( szData );
    new player = find_player( "k", userid ); // flag "k" : find player from userid

    //If the player is not alive
    //Note - you should check this again in the handler function because the player could have been revived after the menu was shown
    if ( !is_user_alive( player ) )
    {
        //Respawn them
        ExecuteHamB( Ham_CS_RoundRespawn, player );
    }

    menu_destroy( menu );
    return PLUGIN_HANDLED;
 }
newmenus.inc

Code: Select all

//The following defines are to be used with the native menu_setprop
#define MPROP_PERPAGE   1       /* Number of items per page ( param1 = number, 0=no paginating, 7=default ) */
#define MPROP_BACKNAME  2       /* Name of the back button ( param1 = string ) */
#define MPROP_NEXTNAME  3       /* Name of the next button ( param1 = string ) */
#define MPROP_EXITNAME  4       /* Name of the exit button ( param1 = string ) */
#define MPROP_TITLE     5       /* Menu title text ( param1 = string ) */
#define MPROP_EXIT      6       /* Exit functionality ( param1 = number, see MEXIT constants ) */
#define MPROP_NOCOLORS  8       /* Sets whether colors are not auto ( param1 = number, 0=default ) */
#define MPROP_NUMBER_COLOR  10  /* Color indicator to use for numbers ( param1 = string, "\r"=default ) */

//These two defines are to be used when changing a menu's MPROP_EXIT value
#define MEXIT_ALL       1       /* Menu will have an exit option ( default )*/
#define MEXIT_NEVER     -1      /* Menu will not have an exit option */

//For more details about the following natives, check your actual newmenus.inc
native menu_create( const title[], const handler[], ml=0 );
native menu_makecallback( const function[]);
native menu_additem( menu, const name[], const info[]="", paccess=0, callback=-1 );
native menu_pages( menu );
native menu_items( menu );
native menu_display( id, menu, page=0 );
native menu_find_id( menu, page, key );
native menu_item_getinfo( menu, item, &access, info[], infolen, name[]="", namelen=0, &callback );
native menu_item_setname( menu, item, const name[]);
native menu_item_setcmd( menu, item, const info[]);
native menu_item_setcall( menu, item, callback=-1 );
native menu_destroy( menu );
native player_menu_info( id, &menu, &newmenu, &menupage=0 );
native menu_addblank( menu, slot=1 );
native menu_addtext( menu, const text[], slot=1 );
native menu_setprop( menu, prop, ...);
native menu_cancel( player );
End Notes:
Most of the menu_* natives will throw errors if they are passed an invalid menu. A menu is invalid if it is -1.
You can expand on these in many ways, like only have one menu_handler to handle more than 1 menu
If you are using a constant menu ( doesn't change at all ) you do not need to create and destroy it each time. It is better to save it as a global.
These examples are not completely optimized, but they are for beginners and so they are simplified.
List of Colors for menus: ( there are no other colors available )
White - \w
Yellow - \y
Red - \r
Grey/Disabled - \d
To align text to the right - \R
A menu will not show if it does not have any items.
Text and blanks can only be added after an item.
To hide a menu ( new or old style ) one can do:

Code: Select all

show_menu( id, 0, "^n", 1 );
One can remove the Next, Back, and Exit buttons to show up to 10 items by using:

Code: Select all

menu_setprop( menu, MPROP_PERPAGE, 0 );
Anyway, Adios.

Who is online

Users browsing this forum: No registered users and 1 guest