Menus

Menus

Menus were a feature that was introduced in sa-mp 0.2, they can be very versatile in creating things such as weapon menus, teleport menus and many more things.

To start off I will show you how to make a simple 3 option menu, kill, heal, armour. To start we need to create an array at the top of your script like this

new Menu:Menu;

Next we have to actually create the menu under OnGameModeInit

Menu = CreateMenu("A menu",1,20,120,150,40); // Defines the name of the menu and the position on the screen
AddMenuItem(Menu,0,"Kill"); // Adds the option "Kill"
AddMenuItem(Menu,0,"Heal"); // Adds the option "Heal"
AddMenuItem(Menu,0,"Armour"); // Adds the option "Armour"

Next thing to do is create a command so we can see the menu, you can activate the menu for a player in anyway with this: ShowMenuForPlayer(Menu, playerid);
But for now we will use a command as it is the easiest way to activate it.

if(strcmp(cmd, "/command", true) == 0) // Menu opening command ^^   (change it. )
    {
        TogglePlayerControllable(playerid, false); // Freeze the player (or not)
        ShowMenuForPlayer(Menu, playerid); // Shows the menu we made earlier
        return 1;
    }

If you test that now your menu will do nothing, we better do something about that! Start off by finding (or adding if you dont have) this in your script

public OnPlayerSelectedMenuRow(playerid, row)
{
    return 1;
}

Once you have that paste this in to it

if(GetPlayerMenu(playerid) == Menu)
    {
    switch(row)
        {
        case 0: 
        {
        SetPlayerHealth(playerid, 0.0); // Because the option of row 1 was "kill"
        TogglePlayerControllable(playerid, true); // After they choose an option they are unfrozen
        HideMenuForPlayer(Menu, playerid); // Gets rid of the menu after they pick the option
        }

        case 1:
        {
        SetPlayerHealth(playerid, 100.0); // Because the option of row 2 was "heal"
        TogglePlayerControllable(playerid, true);
        HideMenuForPlayer(Menu, playerid);
        }

        case 2:
        {
        SetPlayerArmour(playerid, 100.0); // Because the option of row 3 was "armour"
        TogglePlayerControllable(playerid, true);
        HideMenuForPlayer(Menu, playerid);
        }
    }

So now the whole callback will look like

public OnPlayerSelectedMenuRow(playerid, row)
{
    if(GetPlayerMenu(playerid) == Menu)
    {
    switch(row)
        {
        case 0: 
        {
        SetPlayerHealth(playerid, 0.0);
        TogglePlayerControllable(playerid, true);
        }

        case 1:
        {
        SetPlayerHealth(playerid, 100.0);
        TogglePlayerControllable(playerid, true);
        }

        case 2:
        {
        SetPlayerArmour(playerid, 100.0);
        TogglePlayerControllable(playerid, true);
        }
    }
}

That will work fine and dandy, but what if the player changes their mind and does not want to choose any option? They press enter and the menu dissapears but they cant move! so we need to find this call back and change it so it looks like this:

public OnPlayerExitedMenu(playerid)
{
    TogglePlayerControllable(playerid, true); // Will let the player move again
}

And your done, go ingame and try it out! If it worked and you want to see a more advanced setup, check out Luxeons whole menu script, I wont explain it because its pretty easy to understand if you do it bit by bit.

/*------------------------------------------------------------------------------

                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     ~                          ~
                     ~   '/command'  Menu.       ~
                     ~                          ~
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

######################################
~> Copyright © 2007 LuxeoN

~> Type - Filterscript [FS]

~> Version 1.0a (Tested and released)

~> Contact LuxeoN: (sa-mp forum)
######################################

Thanks to sa-mp team/forum for Everything they made!

~~~~@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@~~~~~
NB! This script can be found at sa-mp forum.
This script cant be sold.
Dont remove text ,that is written up here (credits).
Even if you edited it more than 50% ,dont remove my credits.
You can just add:
edited by YourName.

,Thanks.
------------------------------------------------------------------------------*/

/* ~includes  */
#include <a_samp>
#include <float>

/* ~defines  */
#define red 0xFF0000AA
#define yellow 0xFFFF00AA

/* ~Menu start!:     [menu parts]  */

new Menu:Menu; 
new Menu:submenu1; 
new Menu:submenu2; 
new Menu:submenu3; 
new Menu:submenu4; 
new Menu:submenu5; 

public OnFilterScriptInit()
{
    print("\n--------------------------------------");
    print("   [FS] '/command' Menu by LuxeoN.    ");
    print("--------------------------------------\n");
    Menu = CreateMenu("MenuName",1,20,120,150,40); //main  menu start
    AddMenuItem(Menu,0,"Name1");     // 1 <~ submenu numbers
    AddMenuItem(Menu,0,"Name2");   // 2
    AddMenuItem(Menu,0,"Name3");  // 3
    AddMenuItem(Menu,0,"Name4");      // 4
    AddMenuItem(Menu,0,"Name5");    // 5
    submenu1 = CreateMenu("Name1",1,20,120,150,40); // << 1
    AddMenuItem(submenu1,0,"text1");
    AddMenuItem(submenu1,0,"text2");
    AddMenuItem(submenu1,0,"Back");  //                         <<<<<[ NB! Dont forget about 'Back' option! ,lol.
    submenu2 = CreateMenu("Name2",1,20,120,150,40); // << 2                  otherwise it will just close the menu ! ]
    AddMenuItem(submenu2,0,"text1");
    AddMenuItem(submenu2,0,"text2");
    AddMenuItem(submenu2,0,"text3");
    AddMenuItem(submenu2,0,"Back");
    submenu3 = CreateMenu("Name3",1,20,120,150,40); // << 3
    AddMenuItem(submenu3,0,"Text1");
    AddMenuItem(submenu3,0,"Text2");
    AddMenuItem(submenu3,0,"Text3");
    AddMenuItem(submenu3,0,"Back");
    submenu4 = CreateMenu("Name4",1,20,120,150,40); // << 4
    AddMenuItem(submenu4,0,"Text1");
    AddMenuItem(submenu4,0,"Back");
    submenu5 = CreateMenu("Name5",1,20,120,150,40); //<< 5
    AddMenuItem(submenu5,0,"Text1");
    AddMenuItem(submenu5,0,"Back");   // ...[ if you need more Things in submenu ,then do AddMenuItems ,
                                      // then  edit it in 'Case X' in 'OnPlayerSelectedMenuRow(playerid, row)' . ]...
    return 1;
}

public OnPlayerCommandText(playerid,cmdtext[])
{
    new cmd[256];
    new idx;
    cmd = strtok(cmdtext, idx);

    if(strcmp(cmd, "/command", true) == 0) // Menu opening command ^^   (change it. )
    {

            TogglePlayerControllable(playerid, false);//<~player will not be able to move when menu will be opened. I recommend to leave it!
            ShowMenuForPlayer(Menu, playerid); // anyways if you will remove it ,then remove it from 'OnPlayerExitedMenu(playerid)' to !
            return 1;
    }
    return 0;
}

public OnFilterScriptExit()
{
    DestroyMenu(Menu:Menu); //main    // numbers of submenus:
    DestroyMenu(Menu:submenu1); //1
    DestroyMenu(Menu:submenu2); //2
    DestroyMenu(Menu:submenu3); //3
    DestroyMenu(Menu:submenu4); //4
    DestroyMenu(Menu:submenu5); //5
    return 1;
}

strtok(const string[], &index)
{
    new length = strlen(string);
    while ((index < length) && (string[index] <= ' '))
    {
        index++;
    }

    new offset = index;
    new result[20];
    while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
    {
        result[index - offset] = string[index];
        index++;
    }
    result[index - offset] = EOS;
    return result;
}

public OnPlayerSelectedMenuRow(playerid, row)  // menu optiones:
{
    new Menu:Current = GetPlayerMenu(playerid); // Main Menu optiones :
    if(Current == Menu) {
    switch(row){
        case 0: //  NB! everything start from 'Case 0' ,not 'case 1'   !!!!
            if(IsPlayerConnected(playerid))
            {
                ShowMenuForPlayer(submenu1, playerid); // 'ShowMenuForPlayer' = opens that menu.
            }
        case 1:
            if(IsPlayerConnected(playerid))
            {
                ShowMenuForPlayer(submenu2, playerid);
            }
        case 2:
            if(IsPlayerConnected(playerid))
            {
                ShowMenuForPlayer(submenu3, playerid);
            }
        case 3:
            if(IsPlayerConnected(playerid))
            {
                ShowMenuForPlayer(submenu4, playerid);
            }
        case 4:
            if(IsPlayerConnected(playerid))
            {
                ShowMenuForPlayer(submenu5, playerid);
            }

    }
    }
    if(Current == submenu1) { // submenu1 optiones:
    switch(row){
        case 0:  // and again all start from 'Case 0 ' !
            if(GetPlayerMoney(playerid) >= 0) // ...[put here price if you want your menu to cost something.
            {                                         // (useful if you will remake this into weapon menu)]...
                SendClientMessage(playerid,yellow,"~~~~~Text1:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!"); //if you will add  line 169 with price ,then this will start working !
                ShowMenuForPlayer(Menu, playerid);
            }
        case 1: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~Text2:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }

        case 2:ShowMenuForPlayer(Menu, playerid); // <~ Thats 'back' option ;)
    }
    }
    if(Current == submenu2) { //submenu2 optiones:
    switch(row){
        case 0: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~Text1:~~~~~");
                 SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }
        case 1:
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~text2:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }
         case 2: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~text3:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }

        case 3:ShowMenuForPlayer(Menu, playerid);
    }
    }
    if(Current == submenu3) { // submenu3 optiones:
    switch(row){ 
        case 0: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~text1:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }
        case 1: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~Text2:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }

        case 2:ShowMenuForPlayer(Menu, playerid);
    }
    }
    if(Current == submenu4) { // submenu4 optiones:
    switch(row){
        case 0: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~Text1:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }

        case 1:ShowMenuForPlayer(Menu, playerid);
    }
    }
    if(Current == submenu5) { //submenu5 optiones:
    switch(row){
        case 0: 
            if(GetPlayerMoney(playerid) >= 0)
            {
                SendClientMessage(playerid,yellow,"~~~~~text1:~~~~~");
                SendClientMessage(playerid,yellow,"line1");
                SendClientMessage(playerid,yellow,"line2");
                SendClientMessage(playerid,yellow,"line3");
                ShowMenuForPlayer(Menu, playerid);
            }
            else
            {
                SendClientMessage(playerid,red,"Not enough money!");
                ShowMenuForPlayer(Menu, playerid);
            }

        case 1:ShowMenuForPlayer(Menu, playerid); 
    }
    }
 // you can add more submenus here ,after adding them in : 'OnFilterScriptInit()' ; 'OnFilterScriptExit()' and finally here.
}

public OnPlayerExitedMenu(playerid)
{
    TogglePlayerControllable(playerid, true); // after menu exiting Player will be controllable back!
}

public OnPlayerSpawn(playerid)
{
    SendClientMessage(playerid,red,"Be sure to check out our new generation '/command' menu !"); //this will send Message at player spawn.
}

Back | Home