<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mitchell</id>
	<title>AlliedModders Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mitchell"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Mitchell"/>
	<updated>2026-05-28T05:49:46Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10241</id>
		<title>Menus Step By Step (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menus_Step_By_Step_(SourceMod_Scripting)&amp;diff=10241"/>
		<updated>2017-01-18T16:09:39Z</updated>

		<summary type="html">&lt;p&gt;Mitchell: removed incorrect information&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The SourceMod [[Menu API (SourceMod)|Menu API]] is fairly useful for displaying an information panel, a menu, or a vote to users.  This document talks specifically about menus and how to create one.&lt;br /&gt;
&lt;br /&gt;
== The working menu example ==&lt;br /&gt;
&lt;br /&gt;
This is the working code example that we'll be talking about in the upcoming sections.  If you need to, you can come back and look at it as you read the rest of this page.&lt;br /&gt;
&lt;br /&gt;
We will be using PrintToServer to print text to the server console as we run through the events.&lt;br /&gt;
&lt;br /&gt;
Usage of the [[Translations (SourceMod Scripting)|Translations]] system is highly recommended and will be used in this example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;#define CHOICE1 &amp;quot;#choice1&amp;quot;&lt;br /&gt;
#define CHOICE2 &amp;quot;#choice2&amp;quot;&lt;br /&gt;
#define CHOICE3 &amp;quot;#choice3&amp;quot;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	switch(action)&lt;br /&gt;
	{&lt;br /&gt;
		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&lt;br /&gt;
	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&lt;br /&gt;
	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The translation file that goes with it... addons/sourcemod/translations/menu_test.phrases.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Choice 3&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Choice Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	&amp;quot;Menu Title&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;	&amp;quot;Menu Title Translated&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Step by Step ==&lt;br /&gt;
&lt;br /&gt;
=== OnPluginStart ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;menu_test.phrases&amp;quot;);&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This block is here to register the command /menu_test1 so that this menu can be tested.&lt;br /&gt;
&lt;br /&gt;
This block is beyond the scope of this page.  See: [[Introduction to SourceMod Plugins#Plugin Structure|Plugin Structure]] for OnPluginStart, [[Translations (SourceMod Scripting)|Translations]] for LoadTranslations, and [[Commands_(SourceMod_Scripting)|Commands]] for RegConsoleCmd.&lt;br /&gt;
&lt;br /&gt;
=== Menu_Test1 ===&lt;br /&gt;
&lt;br /&gt;
Menu_Test1 is a ConCmd, which is beyond the scope of this page.  See: [[Commands (SourceMod Scripting)|Commands]] for more details on that.  We're going to be talking about what's in it.&lt;br /&gt;
&lt;br /&gt;
==== Menu ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MENU_ACTIONS_ALL);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Menu takes two arguments.&lt;br /&gt;
&lt;br /&gt;
The first is a function that matches the [https://sm.alliedmods.net/new-api/menus/MenuHandler MenuHandler] callback signature.&lt;br /&gt;
&lt;br /&gt;
The second is a bitmask of which MenuAction events we are going to handle in our MenuHandler.  There are 7 that apply to standard menus: &lt;br /&gt;
* MenuAction_Start - Called once when a menu is displayed&lt;br /&gt;
* MenuAction_Display - Called once for each client a menu is displayed to&lt;br /&gt;
* MenuAction_Select - Called when a client makes a selection from the menu that isn't Previous, Next, Back, or Exit.&lt;br /&gt;
* MenuAction_Cancel - Called when a client closes a menu or it is closed on them&lt;br /&gt;
* MenuAction_End - Called once when all clients have closed the menu&lt;br /&gt;
* MenuAction_DrawItem - Called once for each item for each user a menu is displayed to. Can change the menu item style.&lt;br /&gt;
* MenuAction_DisplayIitem. - Called once for each item for each user a menu is displayed to. Can change the menu item text.&lt;br /&gt;
&lt;br /&gt;
These will be discussed in more detail in the MenuHandler1 section.&lt;br /&gt;
&lt;br /&gt;
Of those 7, 3 are called whether you specify them or not: MenuAction_Select, MenuAction_Cancel, and MenuAction_End.&lt;br /&gt;
&lt;br /&gt;
MENU_ACTIONS_DEFAULT sets just the 3 required fields, while MENU_ACTIONS_ALL specifies all 10 actions (including the 3 vote actions).&lt;br /&gt;
&lt;br /&gt;
To specify just a few of them, you can do this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	Menu menu = new Menu(MenuHandler1, MenuAction_Start|MenuAction_Select|MenuAction_Cancel|MenuAction_End);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== menu.SetTitle ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.SetTitle(&amp;quot;%T&amp;quot;, &amp;quot;Menu Title&amp;quot;, LANG_SERVER);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sets the menu's title.  This example uses the translation system and the server's default language.  This isn't strictly necessary as we will set the menu title again later.&lt;br /&gt;
&lt;br /&gt;
==== menu.AddItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;	menu.AddItem(CHOICE1, &amp;quot;Choice 1&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE2, &amp;quot;Choice 2&amp;quot;);&lt;br /&gt;
	menu.AddItem(CHOICE3, &amp;quot;Choice 3&amp;quot;);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A menu isn't useful without something in it!&lt;br /&gt;
menu.AddItem has 2 required arguments and one optional argument.&lt;br /&gt;
&lt;br /&gt;
The 3 required arguments are:&lt;br /&gt;
&lt;br /&gt;
The Info string, and the Display string.&lt;br /&gt;
&lt;br /&gt;
The Info String is a string that is used to uniquely identify this menu item.  It is never displayed to the user, but is used in various callbacks.&lt;br /&gt;
&lt;br /&gt;
The Display String is the default text to be used for this item on the menu.  It can be changed via the menu's MenuAction_DisplayItem callback.&lt;br /&gt;
&lt;br /&gt;
The optional argument is the menu's item draw style.  It can be one of these values:&lt;br /&gt;
* ITEMDRAW_DEFAULT - Displays text as normal.&lt;br /&gt;
* ITEMDRAW_DISABLED - Item is displayed and has a number, but can't be selected.&lt;br /&gt;
* ITEMDRAW_RAWLINE - Item is displayed, but doesn't have a number assigned to it and thus can't be selected&lt;br /&gt;
* ITEMDRAW_NOTEXT - Draws an item with no text.  Not very useful.&lt;br /&gt;
* ITEMDRAW_SPACER - Item is blank, but has a number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_IGNORE - Item is blank with no number.  Can't be selected.&lt;br /&gt;
* ITEMDRAW_CONTROL - Don't use this one.  It's used for the items SourceMod automatically adds.&lt;br /&gt;
&lt;br /&gt;
Be aware that if your CreateMenu second argument includes MenuAction_DrawItem or MENU_ACTIONS_ALL and you don't actually implement the MenuAction_DrawItem callback (or implement it and don't return the current item's style if you don't change it), your style here will be completely ignored.&lt;br /&gt;
&lt;br /&gt;
==== menu.ExitButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.ExitButton = false;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defaults to true.&lt;br /&gt;
&lt;br /&gt;
It set to false, the menu won't have an exit button.&lt;br /&gt;
&lt;br /&gt;
==== menu.ExitBackButton ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.ExitBackButton = false;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(This isn't in the code above, but it should be mentioned) &lt;br /&gt;
&lt;br /&gt;
Defaults to false.&lt;br /&gt;
&lt;br /&gt;
Should only be used if the menu is a submenu, with the menu set up to check the cancel reason to see if the ExitBack action was used.&lt;br /&gt;
&lt;br /&gt;
If set to true, replaces the Exit item with the Back item.  The Back item still cancels the menu, but has a separate cancel reason.&lt;br /&gt;
&lt;br /&gt;
This can be used to dynamically set if a menu is being called as its own menu or as a submenu.&lt;br /&gt;
&lt;br /&gt;
==== menu.Display ====&lt;br /&gt;
&amp;lt;pawn&amp;gt; 	menu.Display(client, 20);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DisplayMenu takes 2 arguments:&lt;br /&gt;
&lt;br /&gt;
A Menu handle, a client index, and the amount of time in seconds to show the menu.&lt;br /&gt;
&lt;br /&gt;
If you want the menu to show forever, pass MENU_TIME_FOREVER as the third argument.&lt;br /&gt;
&lt;br /&gt;
=== MenuHandler1 ===&lt;br /&gt;
&amp;lt;pawn&amp;gt;public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MenuHandler1 is a function whose signature matches the MenuHandler callback.  It can be named something other than MenuHandler1. It must always be public and it will always have these arguments: Handle, MenuAction, cell, and cell in that order.&lt;br /&gt;
&lt;br /&gt;
The Handle argument is always the menu that called the handler.&lt;br /&gt;
&lt;br /&gt;
The MenuAction argument is always one of 7 actions for a standard menu.  They are:  MenuAction_Start, MenuAction_Display, MenuAction_Select, MenuAction_Cancel, MenuAction_End, MenuAction_DrawItem, and MenuAction_DisplayIitem.  We will discuss each of these as we reach their code.&lt;br /&gt;
&lt;br /&gt;
The two cell arguments meaning depend on the MenuAction argument. '''A common mistake is to assume param1 is the client.''' This is incorrect for MenuAction_Start, MenuAction_End, MenuAction_VoteEnd, MenuAction_VoteStart, and MenuAction_VoteCancel.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Start ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Start:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Displaying menu&amp;quot;);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: not set&lt;br /&gt;
* param2: not set&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Start doesn't set param1 and param2.  It is fired when the menu is displayed to one or more users using DisplayMenu, DisplayMenuAtItem, VoteMenu, or VoteMenuToAll.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Display ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Display:&lt;br /&gt;
		{&lt;br /&gt;
	 		char buffer[255];&lt;br /&gt;
			Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Vote Nextmap&amp;quot;, param1);&lt;br /&gt;
&lt;br /&gt;
			Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
			panel.SetTitle(buffer);&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d was sent menu with panel %x&amp;quot;, param1, param2);&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuPanel Handle&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Display is called once for each user a menu is displayed to.  param1 is the client, param2 is the MenuPanel handle.&lt;br /&gt;
&lt;br /&gt;
SetPanelTitle is used to change the menu's title based on the language of the user viewing it using the Translations system.  Previous versions of this guide suggested using SetMenuTitle.  This is a ''bad'' idea, as it changes the title globally.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Select ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_Select:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetInfo(param2, info, sizeof(info));&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d somehow selected %s despite it being disabled&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				PrintToServer(&amp;quot;Client %d selected %s&amp;quot;, param1, info);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Select is called when a user selects a non-control item on the menu (something added using AddMenuItem). param1 is the client, param2 is the menu position of the item the client selected.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_Cancel ====&lt;br /&gt;
&lt;br /&gt;
		case MenuAction_Cancel:&lt;br /&gt;
		{&lt;br /&gt;
			PrintToServer(&amp;quot;Client %d's menu was cancelled for reason %d&amp;quot;, param1, param2);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_Cancel is called whenever a user closes a menu or it is closed for them for another reason.  param1 is the client, param2 is the close reason.&lt;br /&gt;
&lt;br /&gt;
The close reasons you can receive are:&lt;br /&gt;
&lt;br /&gt;
* MenuCancel_Disconnected - The client got disconnected from the server.&lt;br /&gt;
* MenuCancel_Interrupted - Another menu opened, automatically closing our menu.&lt;br /&gt;
* MenuCancel_Exit - The client selected Exit. Not called if SetMenuExitBack was set to true. Not called if SetMenuExit was set to false.&lt;br /&gt;
* MenuCancel_NoDisplay - Our menu never displayed to the client for whatever reason.&lt;br /&gt;
* MenuCancel_Timeout - The menu timed out. Not called if the menu time was MENU_TIME_FOREVER.&lt;br /&gt;
* MenuCancel_ExitBack - The client selected Back. Only called if SetMenuExitBack has been called and set to true before the menu was sent. Not called if SetMenuExit was set to false.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_End ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_End:&lt;br /&gt;
		{&lt;br /&gt;
			delete menu;&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: MenuEnd reason&lt;br /&gt;
* param2: If param1 is MenuEnd_Cancelled, the MenuCancel reason&lt;br /&gt;
* return: 0 (or don't return)&lt;br /&gt;
&lt;br /&gt;
MenuAction_End is called when ''all'' clients have closed a menu or vote.  For menus that are not going to be redisplayed, it is required that you call CloseHandle on the menu here.&lt;br /&gt;
&lt;br /&gt;
The parameters are rarely used in MenuAction_End.  param1 is the menu end reason. param2 depends on param1.&lt;br /&gt;
&lt;br /&gt;
The end reasons you can receive for normal menus are:&lt;br /&gt;
&lt;br /&gt;
* MenuEnd_Selected - The menu closed because an item was selected (MenuAction_Select was fired)&lt;br /&gt;
* MenuEnd_Cancelled - The menu was cancelled (MenuAction_Cancel was fired), cancel reason is in param2; cancel reason can be any of the ones listed in MenuAction_Cancel except MenuCancel_Exit or MenuCancel_ExitBack&lt;br /&gt;
* MenuEnd_Exit - The menu was exited via the Exit item (MenuAction_Cancel was fired with param2 set to MenuCancel_Exit)&lt;br /&gt;
* MenuEnd_ExitBack - The menu was exited via the ExitBack item (MenuAction_Cancel was fired with param 2 set to MenuCancel_ExitBack)&lt;br /&gt;
&lt;br /&gt;
Note: You do '''not''' have the client index during this callback, so it's far too late to do anything useful with this information.&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DrawItem ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DrawItem:&lt;br /&gt;
		{&lt;br /&gt;
			int style;&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info), style);&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				return ITEMDRAW_DISABLED;&lt;br /&gt;
			}&lt;br /&gt;
			else&lt;br /&gt;
			{&lt;br /&gt;
				return style;&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: new ITEMDRAW properties or style from GetMenuItem.  Since 0 is ITEMDRAW_DEFAULT, returning 0 clears all styles for this item.&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its draw style here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string and menu style.&lt;br /&gt;
&lt;br /&gt;
You should return the style you want the menu item to have.  In our example, if client 1 is viewing the menu, we want CHOICE3 to be disabled.&lt;br /&gt;
&lt;br /&gt;
the return value is a bitfield, so to apply multiple styles, you do something like this:&lt;br /&gt;
&lt;br /&gt;
		return ITEMDRAW_NOTEXT | ITEMDRAW_SPACER;&lt;br /&gt;
&lt;br /&gt;
'''Failing to return the current item's style if you don't change the style is a programmer error.'''&lt;br /&gt;
&lt;br /&gt;
==== MenuAction_DisplayItem ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;		case MenuAction_DisplayItem:&lt;br /&gt;
		{&lt;br /&gt;
			char info[32];&lt;br /&gt;
			menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
			&lt;br /&gt;
			char display[64];&lt;br /&gt;
			&lt;br /&gt;
			if (StrEqual(info, CHOICE3))&lt;br /&gt;
			{&lt;br /&gt;
				Format(display, sizeof(display), &amp;quot;%T&amp;quot;, &amp;quot;Choice 3&amp;quot;, param1);&lt;br /&gt;
				return RedrawMenuItem(display);&lt;br /&gt;
			}&lt;br /&gt;
		}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* param1: client index&lt;br /&gt;
* param2: item number for use with GetMenuItem&lt;br /&gt;
* return: return value from RedrawMenuItem or 0 for no change&lt;br /&gt;
&lt;br /&gt;
MenuAction_DrawItem is called once for each item on the menu for each user.  You can manipulate its text here. param1 is the client, param2 is the menu position.&lt;br /&gt;
&lt;br /&gt;
This callback is intended for use with the Translation system.&lt;br /&gt;
&lt;br /&gt;
Using the item position to check which item was selected is a bad idea, as item position is brittle and will break things if AddMenuItem or InsertMenuItem is used.  It is recommended that you instead use the Menu item's info string, as done in the code above.&lt;br /&gt;
&lt;br /&gt;
GetMenuItem is used here to fetch the info string.&lt;br /&gt;
&lt;br /&gt;
Once we have the info string, we compare our item to it and apply the appropriate translation string.&lt;br /&gt;
&lt;br /&gt;
If we change an item, we have to call RedrawMenuItem and return the value it returns.  If we do not change an item, we must return 0.&lt;br /&gt;
&lt;br /&gt;
==== return ====&lt;br /&gt;
&amp;lt;pawn&amp;gt;	return 0;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you handle MenuAction_DrawItem or MenuAction_DisplayItem, you will get the following warning if you fail to return 0 after the switch block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;warning 209: function &amp;quot;MenuHandler1&amp;quot; should return a value&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is because MenuAction_DrawItem and MenuAction_DisplayItem have return values, while the other actions only return 0.&lt;br /&gt;
&lt;br /&gt;
== The End ==&lt;br /&gt;
Hopefully this walk through a simple menu helped you understand why each call is being made where.  Menus have some options that we didn't explore here, such as disabling pagination (which is enabled by default).  You may want to refer to the main Menu documentation for more details.&lt;/div&gt;</summary>
		<author><name>Mitchell</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:Mitchell&amp;diff=10235</id>
		<title>User:Mitchell</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:Mitchell&amp;diff=10235"/>
		<updated>2017-01-04T21:35:59Z</updated>

		<summary type="html">&lt;p&gt;Mitchell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''~lick~''  &lt;br /&gt;
&lt;br /&gt;
[[File:Mitchell.gif]]&lt;/div&gt;</summary>
		<author><name>Mitchell</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=User:Mitchell&amp;diff=10234</id>
		<title>User:Mitchell</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=User:Mitchell&amp;diff=10234"/>
		<updated>2017-01-04T21:35:14Z</updated>

		<summary type="html">&lt;p&gt;Mitchell: Created page with &amp;quot;''~lick~'' File:Mitchell.gif&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''~lick~''&lt;br /&gt;
[[File:Mitchell.gif]]&lt;/div&gt;</summary>
		<author><name>Mitchell</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=File:Mitchell.gif&amp;diff=10233</id>
		<title>File:Mitchell.gif</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=File:Mitchell.gif&amp;diff=10233"/>
		<updated>2017-01-04T21:34:47Z</updated>

		<summary type="html">&lt;p&gt;Mitchell: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mitchell</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Menu_API_(SourceMod)&amp;diff=10232</id>
		<title>Menu API (SourceMod)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Menu_API_(SourceMod)&amp;diff=10232"/>
		<updated>2017-01-04T21:31:11Z</updated>

		<summary type="html">&lt;p&gt;Mitchell: Changed INVALID_HANDLE to null (1.7)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SourceMod has an extensive API for building and displaying menus to clients.  Unlike AMX Mod X, this API is highly state driven.  Menus are based on callbacks which are guaranteed to be fired.&lt;br /&gt;
&lt;br /&gt;
For C++, the Menu API can be found in &amp;lt;tt&amp;gt;public/IMenuManager.h&amp;lt;/tt&amp;gt;.  For SourcePawn, it is in &amp;lt;tt&amp;gt;scripting/include/menus.inc&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=Objects=&lt;br /&gt;
The SourceMod Menu System is based on an object oriented hierarchy.  Understanding this hierarchy, even for scripting, is critical to using menus effectively.&lt;br /&gt;
&lt;br /&gt;
==Styles==&lt;br /&gt;
The top level object is a ''MenuStyle'' (&amp;lt;tt&amp;gt;IMenuStyle&amp;lt;/tt&amp;gt; in C++).  Styles describe a unique menu system.  There are two such styles built into SourceMod:&lt;br /&gt;
*Valve Style, also called &amp;quot;ESC&amp;quot; menus; 8 items per page, no raw/disabled text can be rendered&lt;br /&gt;
*Radio Style, also called &amp;quot;AMX&amp;quot; menus; 10 items per page, raw/disabled text can be rendered&lt;br /&gt;
&lt;br /&gt;
Each MenuStyle has its own rules and properties.  You can think of them as existing on separate &amp;quot;channels.&amp;quot;  For example, two different menus can exist on a player's screen as both a Valve menu and a Radio menu at the same time, and SourceMod will be able to manage both without any problems.  This is because each style keeps track of its own menus separately.&lt;br /&gt;
&lt;br /&gt;
==Panels==&lt;br /&gt;
Menu displays are drawn with a lower level interface called ''Panels'' (&amp;lt;tt&amp;gt;IMenuPanel&amp;lt;/tt&amp;gt; in C++).  Panels describe exactly one chunk of display text.  Both selectable items and raw text can be added to a panel as long as its parent style supports the contents you're trying to draw.  For example, the Valve style does not support drawing raw text or disabled items.  But with a Radio-style Panel, you can display a large amount of on-screen data in your own format.&lt;br /&gt;
&lt;br /&gt;
Panels are considered temporary objects.  They are created, rendered, displayed, and destroyed.  Although they can be saved indefinitely, it is not necessary to do so.&lt;br /&gt;
&lt;br /&gt;
Valve Style drawing rules/limitations:&lt;br /&gt;
*Max items per page is 8.&lt;br /&gt;
*Disabled items cannot be drawn.&lt;br /&gt;
*Raw text cannot be drawn.&lt;br /&gt;
*Spacers do not add a space/newline, giving a &amp;quot;cramped&amp;quot; feel.&lt;br /&gt;
*Users must press &amp;quot;ESC&amp;quot; or be at their console to view the menu.&lt;br /&gt;
&lt;br /&gt;
Radio Style drawing rules/limitations:&lt;br /&gt;
*Max items per page is 10.&lt;br /&gt;
*Titles appear white; items appear yellow, unless disabled, in which case they are white.&lt;br /&gt;
*The 0th item is always white.  For consistency, this means navigational controls explained in the next section are always white, and simply not drawn if disabled.&lt;br /&gt;
&lt;br /&gt;
==Menus==&lt;br /&gt;
Lastly, there are plain ''Menus'' (&amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; in C++).  These are helper objects designed for storing a menu based on selectable items.  Unlike low-level panels, menus are containers for '''items''', and can only contain items which are selectable (i.e., do not contain raw text).  They fall into two categories:&lt;br /&gt;
*Non-paginated: The menu can only have a certain number of items on it, and no control/navigation options will be added, except for an &amp;quot;Exit&amp;quot; button which will always be in the last position supported by the style.&lt;br /&gt;
**Valve Style maximum items: 8&lt;br /&gt;
**Radio Style maximum items: 10&lt;br /&gt;
*Paginated: The menu can have any number of items.  When displayed, only a certain number of items will be drawn at a time.  Automatic navigation controls are added so players can easily move back and forth to different &amp;quot;pages&amp;quot; of items in the menu.&lt;br /&gt;
**&amp;quot;Previous&amp;quot; is always drawn as the first navigation item, third from the last supported position.  This will not be drawn if the menu only contains one page.  If there are no previous pages, the text will not be drawn on either style; if possible, the menu will be padded so spacing is consistent.&lt;br /&gt;
***Valve Style position: 6&lt;br /&gt;
***Radio Style position: 8&lt;br /&gt;
**&amp;quot;Next&amp;quot; is always drawn as the second navigation item, second from the last supported position.  This will not be drawn if the menu only contains one page.  If there are no further pages, the text will not be drawn on either style; if possible, the menu will be padded so spacing is consistent.&lt;br /&gt;
***Valve Style position: 7&lt;br /&gt;
***Radio Style position: 9&lt;br /&gt;
**&amp;quot;Exit&amp;quot; is drawn if the menu has the exit button property set.  It is always the last supported item position.&lt;br /&gt;
***Valve Style position: 8&lt;br /&gt;
***Radio Style position: 10&lt;br /&gt;
&lt;br /&gt;
The purpose of Menus is to simplify the procedure of storing, drawing, and calculating the selection of items.  Thus, menus do not allow for adding raw text, as that would considerably complicate the drawing algorithm.  ''Note: The C++ API supports hooking &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; drawing procedures and adding raw text; this will be added to the scripting API soon.''&lt;br /&gt;
&lt;br /&gt;
Internally, Menus are drawn via a ''RenderMenu'' algorithm.  This algorithm creates a temporary panel and fills it with items from menus.  This panel is then displayed to a client.  The algorithm attempts to create a consistent feel across all menus, and across all styles.  Thus any menu displayed via the &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; class, or &amp;lt;tt&amp;gt;Menu&amp;lt;/tt&amp;gt; Handles, will look and act the same, and the Menu API is based off the Panel API.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Callbacks=&lt;br /&gt;
==Overview==&lt;br /&gt;
Menus are a callback based system.  Each callback represents an action that occurs during a ''menu display cycle''.  A cycle consists of a number of notifications:&lt;br /&gt;
*Start notification.&lt;br /&gt;
**Display notification if the menu can be displayed to the client.&lt;br /&gt;
**Either an item select or menu cancel notification.&lt;br /&gt;
*End notification.&lt;br /&gt;
&lt;br /&gt;
Since ''End'' signifies the end of a full display cycle, it is usually used to destroy temporary menus.&lt;br /&gt;
&lt;br /&gt;
==Specification==&lt;br /&gt;
A detailed explanation of these events is below.  For C++, an &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; pointer is always available.  For SourcePawn, a &amp;lt;tt&amp;gt;Menu&amp;lt;/tt&amp;gt; Handle and a &amp;lt;tt&amp;gt;MenuAction&amp;lt;/tt&amp;gt; are always set in the &amp;lt;tt&amp;gt;MenuHandler&amp;lt;/tt&amp;gt; callback.  Unlike C++, the SourcePawn API allows certain actions to only be called if they are requested at menu creation time.  This is an optimization.  However, certain actions cannot be prevented from being called.&lt;br /&gt;
&lt;br /&gt;
*'''Start'''.  The menu has been acknowledged.  This does not mean it will be displayed; however, it guarantees that &amp;quot;OnMenuEnd&amp;quot; will be called.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuStart()&amp;lt;/tt&amp;gt; in C++.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Start&amp;lt;/tt&amp;gt; in SourcePawn.  This action is not triggered unless requested.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: Ignored (always 0).&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: Ignored (always 0).&lt;br /&gt;
*'''Display'''.  The menu is being displayed to a client.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuDisplay()&amp;lt;/tt&amp;gt; in C++.  An &amp;lt;tt&amp;gt;IMenuPanel&amp;lt;/tt&amp;gt; pointer and client index are available.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Display&amp;lt;/tt&amp;gt; in SourcePawn.  This action is not triggered unless requested.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: A Handle to a menu panel.&lt;br /&gt;
*'''Select'''.  An item on the menu has been selected.  The item position given will be the position in the menu, rather than the key pressed (unless the menu is a raw panel).  &lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuSelect()&amp;lt;/tt&amp;gt; in C++.  A client index and item position are passed.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Select&amp;lt;/tt&amp;gt; in SourcePawn.  This action is always triggerable, whether requested or not.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: An item position.&lt;br /&gt;
*'''Cancel'''.  The menu's display to one client has been cancelled.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuCancel()&amp;lt;/tt&amp;gt; in C++.  A reason for cancellation is provided.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Cancel&amp;lt;/tt&amp;gt; in SourcePawn.  This action is always triggerable, whether requested or not.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: A menu cancellation reason code.&lt;br /&gt;
*'''End'''.  The menu's display cycle has finished; this means that the &amp;quot;Start&amp;quot; action has occurred, and either &amp;quot;Select&amp;quot; or &amp;quot;Cancel&amp;quot; has occurred thereafter.  This is typically where menu resources are removed/deleted.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuEnd()&amp;lt;/tt&amp;gt; in C++.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt; in SourcePawn.  This action is always triggered, whether requested or not.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A menu end reason code.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: If param1 was MenuEnd_Cancelled, this contains a menu cancellation reason code.&lt;br /&gt;
&lt;br /&gt;
==Panels==&lt;br /&gt;
For panels, the callback rules change.  Panels only receive two of the above callbacks, and it is guaranteed that only one of them will be called for a given display cycle.  For C++, the &amp;lt;tt&amp;gt;IBaseMenu&amp;lt;/tt&amp;gt; pointer will always be &amp;lt;tt&amp;gt;NULL&amp;lt;/tt&amp;gt;.  For SourcePawn, the menu Handle will always be &amp;lt;tt&amp;gt;INVALID_HANDLE&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;null&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
*'''Select'''.  A key has been pressed.  This can be any number and should not be considered as reliably in bounds.  For example, even if you only had 2 items in your panel, a client could trigger a key press of &amp;quot;43.&amp;quot;&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuSelect()&amp;lt;/tt&amp;gt; in C++.  A client index and key number pressed are passed.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Select&amp;lt;/tt&amp;gt; in SourcePawn.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: Number of the key pressed.&lt;br /&gt;
*'''Cancel'''.  The menu's display to one client has been cancelled.&lt;br /&gt;
**&amp;lt;tt&amp;gt;OnMenuCancel()&amp;lt;/tt&amp;gt; in C++.  A reason for cancellation is provided.&lt;br /&gt;
**&amp;lt;tt&amp;gt;MenuAction_Cancel&amp;lt;/tt&amp;gt; in SourcePawn.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;: A client index.&lt;br /&gt;
***&amp;lt;tt&amp;gt;param2&amp;lt;/tt&amp;gt;: A menu cancellation reason code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Examples=&lt;br /&gt;
First, let's start off with a very basic menu.  We want the menu to look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Do you like apples?&lt;br /&gt;
1. Yes&lt;br /&gt;
2. No&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We'll draw this menu with both a basic Menu and a Panel to show the API differences.&lt;br /&gt;
&lt;br /&gt;
==Basic Menu==&lt;br /&gt;
First, let's write our example using the Menu building API.  For a more in-depth guide, see [[Menus Step By Step (SourceMod Scripting)]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_test1&amp;quot;, Menu_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int MenuHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	/* If an option was selected, tell the client about the item. */&lt;br /&gt;
	if (action == MenuAction_Select)&lt;br /&gt;
	{&lt;br /&gt;
		char info[32];&lt;br /&gt;
		bool found = menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
		PrintToConsole(param1, &amp;quot;You selected item: %d (found? %d info: %s)&amp;quot;, param2, found, info);&lt;br /&gt;
	}&lt;br /&gt;
	/* If the menu was cancelled, print a message to the server about it. */&lt;br /&gt;
	else if (action == MenuAction_Cancel)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToServer(&amp;quot;Client %d's menu was cancelled.  Reason: %d&amp;quot;, param1, param2);&lt;br /&gt;
	}&lt;br /&gt;
	/* If the menu has ended, destroy it */&lt;br /&gt;
	else if (action == MenuAction_End)&lt;br /&gt;
	{&lt;br /&gt;
		delete menu;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Menu_Test1(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	Menu menu = new Menu(MenuHandler1);&lt;br /&gt;
	menu.SetTitle(&amp;quot;Do you like apples?&amp;quot;);&lt;br /&gt;
	menu.AddItem(&amp;quot;yes&amp;quot;, &amp;quot;Yes&amp;quot;);&lt;br /&gt;
	menu.AddItem(&amp;quot;no&amp;quot;, &amp;quot;No&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.Display(client, 20);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note a few very important points from this example:&lt;br /&gt;
*One of either &amp;lt;tt&amp;gt;Select&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;Cancel&amp;lt;/tt&amp;gt; will always be sent to the action handler.&lt;br /&gt;
*&amp;lt;tt&amp;gt;End&amp;lt;/tt&amp;gt; will always be sent to the action handler.&lt;br /&gt;
*We destroy our Menu in the &amp;lt;tt&amp;gt;End&amp;lt;/tt&amp;gt; action, because our Handle is no longer needed.  If we had destroyed the Menu after &amp;lt;tt&amp;gt;DisplayMenu&amp;lt;/tt&amp;gt;, it would have canceled the menu's display to the client.&lt;br /&gt;
*Menus, by default, have an exit button.  We disabled this in our example.&lt;br /&gt;
*Our menu is set to display for 20 seconds.  That means that if the client does not select an item within 20 seconds, the menu will be canceled.  This is usually desired for menus that are for voting.  Note that unlike AMX Mod X, you do not need to set a timer to make sure the menu will be ended.&lt;br /&gt;
*Although we created and destroyed a new Menu Handle, we didn't need to.  It is perfectly acceptable to create the Handle once for the lifetime of the plugin.&lt;br /&gt;
&lt;br /&gt;
Our finished menu and attached console output looks like this (I selected &amp;quot;Yes&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
[[Image:Basic_menu_1.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Basic Panel==&lt;br /&gt;
Now, let's rewrite our example to use Panels instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;panel_test1&amp;quot;, Panel_Test1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int PanelHandler1(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_Select)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(param1, &amp;quot;You selected item: %d&amp;quot;, param2);&lt;br /&gt;
	} else if (action == MenuAction_Cancel) {&lt;br /&gt;
		PrintToServer(&amp;quot;Client %d's menu was cancelled.  Reason: %d&amp;quot;, param1, param2);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Panel_Test1(int client, intargs)&lt;br /&gt;
{&lt;br /&gt;
	Panel panel = new Panel();&lt;br /&gt;
	panel.SetTitle(&amp;quot;Do you like apples?&amp;quot;);&lt;br /&gt;
	panel.DrawItem(&amp;quot;Yes&amp;quot;);&lt;br /&gt;
	panel.DrawItem(&amp;quot;No&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
	panel.Send(client, PanelHandler1, 20);&lt;br /&gt;
&lt;br /&gt;
	delete panel;&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, Panels are significantly different.&lt;br /&gt;
*We can destroy the Panel as soon as we're done displaying it.  We can create the Panel once and keep re-using it, but we can destroy it at any time without interrupting client menus.&lt;br /&gt;
*The Handler function gets much less data.  Since panels are designed as a raw display, no &amp;quot;item&amp;quot; information is saved internally.  Thus, the handler function only knows whether the display was canceled or whether (and what) numerical key was pressed.&lt;br /&gt;
*There is no automation.  You cannot add more than a certain amount of selectable items to a Panel and get pagination.  Automated control functionality requires using the heftier Menu object API.&lt;br /&gt;
&lt;br /&gt;
Our finished display and console output looks like this (I selected &amp;quot;Yes&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
[[Image:Basic_panel_1.PNG]]&lt;br /&gt;
&lt;br /&gt;
==Basic Paginated Menu==&lt;br /&gt;
Now, let's take a more advanced example -- pagination. Let's say we want to build a menu for changing the map.  An easy way to do this is to read the &amp;lt;tt&amp;gt;maplist.txt&amp;lt;/tt&amp;gt; file at the start of a plugin and build a menu out of it.&lt;br /&gt;
&lt;br /&gt;
Since reading and parsing a file is an expensive operation, we only want to do this once per map.  Thus we'll build the menu in &amp;lt;tt&amp;gt;OnMapStart&amp;lt;/tt&amp;gt;, and we won't call &amp;lt;tt&amp;gt;CloseHandle&amp;lt;/tt&amp;gt; until &amp;lt;tt&amp;gt;OnMapEnd&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Source code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Menu g_MapMenu = null;&lt;br /&gt;
&lt;br /&gt;
public void OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegConsoleCmd(&amp;quot;menu_changemap&amp;quot;, Command_ChangeMap);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnMapStart()&lt;br /&gt;
{&lt;br /&gt;
	g_MapMenu = BuildMapMenu();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void OnMapEnd()&lt;br /&gt;
{&lt;br /&gt;
	if (g_MapMenu != null)&lt;br /&gt;
	{&lt;br /&gt;
		delete(g_MapMenu);&lt;br /&gt;
		g_MapMenu = null;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Menu BuildMapMenu()&lt;br /&gt;
{&lt;br /&gt;
	/* Open the file */&lt;br /&gt;
	File file = OpenFile(&amp;quot;maplist.txt&amp;quot;, &amp;quot;rt&amp;quot;);&lt;br /&gt;
	if (file == null)&lt;br /&gt;
	{&lt;br /&gt;
		return null;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* Create the menu Handle */&lt;br /&gt;
	Menu menu = new Menu(Menu_ChangeMap);&lt;br /&gt;
	char mapname[255];&lt;br /&gt;
	while (!file.EndOfFile() &amp;amp;&amp;amp; file.ReadLine(mapname, sizeof(mapname)))&lt;br /&gt;
	{&lt;br /&gt;
		if (mapname[0] == ';' || !IsCharAlpha(mapname[0]))&lt;br /&gt;
		{&lt;br /&gt;
			continue;&lt;br /&gt;
		}&lt;br /&gt;
		/* Cut off the name at any whitespace */&lt;br /&gt;
		int len = strlen(mapname);&lt;br /&gt;
		for (int i=0; i&amp;lt;len; i++)&lt;br /&gt;
		{&lt;br /&gt;
			if (IsCharSpace(mapname[i]))&lt;br /&gt;
			{&lt;br /&gt;
				mapname[i] = '\0';&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		/* Check if the map is valid */&lt;br /&gt;
		if (!IsMapValid(mapname))&lt;br /&gt;
		{&lt;br /&gt;
			continue;&lt;br /&gt;
		}&lt;br /&gt;
		/* Add it to the menu */&lt;br /&gt;
		menu.AddItem(mapname, mapname);&lt;br /&gt;
	}&lt;br /&gt;
	/* Make sure we close the file! */&lt;br /&gt;
	file.Close();&lt;br /&gt;
	&lt;br /&gt;
	/* Finally, set the title */&lt;br /&gt;
	menu.SetTitle(&amp;quot;Please select a map:&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	return menu;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public int Menu_ChangeMap(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_Select)&lt;br /&gt;
	{&lt;br /&gt;
		char info[32];&lt;br /&gt;
&lt;br /&gt;
		/* Get item info */&lt;br /&gt;
		bool found = menu.GetItem(param2, info, sizeof(info));&lt;br /&gt;
&lt;br /&gt;
		/* Tell the client */&lt;br /&gt;
		PrintToConsole(param1, &amp;quot;You selected item: %d (found? %d info: %s)&amp;quot;, param2, found, info);&lt;br /&gt;
&lt;br /&gt;
		/* Change the map */&lt;br /&gt;
		ServerCommand(&amp;quot;changelevel %s&amp;quot;, info);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action Command_ChangeMap(int client, int args)&lt;br /&gt;
{&lt;br /&gt;
	if (g_MapMenu == null)&lt;br /&gt;
	{&lt;br /&gt;
		PrintToConsole(client, &amp;quot;The maplist.txt file was not found!&amp;quot;);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}	&lt;br /&gt;
	&lt;br /&gt;
	g_MapMenu.Display(client, MENU_TIME_FOREVER);&lt;br /&gt;
	&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This menu results in many selections (my &amp;lt;tt&amp;gt;maplist.txt&amp;lt;/tt&amp;gt; file had around 18 maps).  So, our final menu has 3 pages, which side by side, look like:&lt;br /&gt;
&lt;br /&gt;
[[Image:Basic_menu_2_page1.PNG]]&lt;br /&gt;
[[Image:Basic_menu_2_page2.PNG]]&lt;br /&gt;
[[Image:Basic_menu_2_page3.PNG]]&lt;br /&gt;
&lt;br /&gt;
Finally, the console output printed this before the map changed to my selection, &amp;lt;tt&amp;gt;cs_office&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;You selected item: 8 (found? 1 info: cs_office)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Displaying and designing this Menu with a raw &amp;lt;tt&amp;gt;ShowMenu&amp;lt;/tt&amp;gt; message or &amp;lt;tt&amp;gt;Panel&amp;lt;/tt&amp;gt; API would be very time consuming and difficult.  We would have to keep track of all the items in an array of hardcoded size, pages which the user is viewing, and write a function which calculated item selection based on current page and key press.  The Menu system, thankfully, handles all of this for you.&lt;br /&gt;
&lt;br /&gt;
'''Notes:'''&lt;br /&gt;
*Control options which are not available are not drawn.  For example, in the first page, you cannot go &amp;quot;back,&amp;quot; and in the last page, you cannot go &amp;quot;next.&amp;quot;  Despite this, the menu API tries to keep each the interface as consistent as possible.  Thus, visually, each navigational control is always in the same position.  &lt;br /&gt;
*Although we specified no time out for our menu, if we had placed a timeout, flipping through pages does not affect the overall time.  For example, if we had a timeout of 20, each successive page flip would continue to detract from the overall display time, rather than restart the allowed hold time back to 20.&lt;br /&gt;
*If we had disabled the Exit button, options 8 and 9 would still be &amp;quot;Back&amp;quot; and &amp;quot;Next,&amp;quot; respectively.&lt;br /&gt;
*Again, we did not free the Menu Handle in &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;.  This is because our menu is global/static, and we don't want to rebuild it every time.&lt;br /&gt;
*These images show &amp;quot;Back.&amp;quot;  In SourceMod revisions 1011 and higher, &amp;quot;Back&amp;quot; is changed to &amp;quot;Previous,&amp;quot; and &amp;quot;Back&amp;quot; is reserved for the special &amp;quot;ExitBack&amp;quot; functionality.&lt;br /&gt;
&lt;br /&gt;
=Voting=&lt;br /&gt;
SourceMod also has API for displaying menus as votable choices to more than one client.  SourceMod automatically handles selecting an item and randomly picking a tie-breaker.  The voting API adds two new &amp;lt;tt&amp;gt;MenuAction&amp;lt;/tt&amp;gt; values, which for vote displays, are '''always''' passed:&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;tt&amp;gt;MenuAction_VoteStart&amp;lt;/tt&amp;gt;: Fired after &amp;lt;tt&amp;gt;MenuAction_Start&amp;lt;/tt&amp;gt; when the voting has officially started.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt;: Fired when all clients have either voted or cancelled their vote menu.  The chosen item is passed through &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;.  This is fired '''before''' &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;.  It is important to note that it does not supercede &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;, nor is it the same thing.  Menus should never be destroyed in &amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt;.  '''Note:''' This is not called if &amp;lt;tt&amp;gt;SetVoteResultCallback&amp;lt;/tt&amp;gt;() is used.&lt;br /&gt;
*&amp;lt;tt&amp;gt;MenuAction_VoteCancel&amp;lt;/tt&amp;gt;: Fired if the menu is cancelled while the vote is in progress.  If this is called, &amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt; or the result callback will not be called, but &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt; will be afterwards.  A vote cancellation reason is passed in &amp;lt;tt&amp;gt;param1&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The voting system extends overall menus with two additional properties:&lt;br /&gt;
*Only one vote can be active at a time.  You must call &amp;lt;tt&amp;gt;IsVoteInProgress&amp;lt;/tt&amp;gt;() or else &amp;lt;tt&amp;gt;VoteMenu&amp;lt;/tt&amp;gt;() will fail.&lt;br /&gt;
*If a client votes and then disconnects while the vote is still active, the client's vote will be invalidated.&lt;br /&gt;
&lt;br /&gt;
The example below shows has to create a function called &amp;lt;tt&amp;gt;DoVoteMenu()&amp;lt;/tt&amp;gt; which will ask all clients whether or not they would like to change to the given map.&lt;br /&gt;
&lt;br /&gt;
==Simple Vote==&lt;br /&gt;
&amp;lt;pawn&amp;gt;public int Handle_VoteMenu(Menu menu, MenuAction action, int param1,int param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_End)&lt;br /&gt;
	{&lt;br /&gt;
		/* This is called after VoteEnd */&lt;br /&gt;
		delete menu;&lt;br /&gt;
	} else if (action == MenuAction_VoteEnd) {&lt;br /&gt;
		/* 0=yes, 1=no */&lt;br /&gt;
		if (param1 == 0)&lt;br /&gt;
		{&lt;br /&gt;
			char map[64];&lt;br /&gt;
			menu.GetItem(param1, map, sizeof(map));&lt;br /&gt;
			ServerCommand(&amp;quot;changelevel %s&amp;quot;, map);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DoVoteMenu(const char[] map)&lt;br /&gt;
{&lt;br /&gt;
	if (IsVoteInProgress())&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Menu menu = new Menu(Handle_VoteMenu);&lt;br /&gt;
	menu.SetTitle(&amp;quot;Change map to: %s?&amp;quot;, map);&lt;br /&gt;
	menu.AddItem(map, &amp;quot;Yes&amp;quot;);&lt;br /&gt;
	menu.AddItem(&amp;quot;no&amp;quot;, &amp;quot;No&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.DisplayVoteToAll(20);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Advanced Voting==&lt;br /&gt;
If you need more information about voting results than &amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt; gives you, you can choose to have a different callback invoked.  The new callback will provide much more information, but at a price: &amp;lt;tt&amp;gt;MenuAction_VoteEnd&amp;lt;/tt&amp;gt; will not be called, and you will have to decide how to interpret the results.  This is done via &amp;lt;tt&amp;gt;SetVoteResultCallback&amp;lt;/tt&amp;gt;().&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;public int Handle_VoteMenu(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_End)&lt;br /&gt;
	{&lt;br /&gt;
		/* This is called after VoteEnd */&lt;br /&gt;
		delete menu;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void Handle_VoteResults(Menu menu, &lt;br /&gt;
			int num_votes, &lt;br /&gt;
			int num_clients, &lt;br /&gt;
			const int[][] client_info, &lt;br /&gt;
			int num_items, &lt;br /&gt;
			const int[][] item_info)&lt;br /&gt;
{&lt;br /&gt;
	/* See if there were multiple winners */&lt;br /&gt;
	int winner = 0;&lt;br /&gt;
	if (num_items &amp;gt; 1&lt;br /&gt;
	    &amp;amp;&amp;amp; (item_info[0][VOTEINFO_ITEM_VOTES] == item_info[1][VOTEINFO_ITEM_VOTES]))&lt;br /&gt;
	{&lt;br /&gt;
		winner = GetRandomInt(0, 1);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	char map[64];&lt;br /&gt;
	menu.GetItem(item_info[winner][VOTEINFO_ITEM_INDEX], map, sizeof(map));&lt;br /&gt;
	ServerCommand(&amp;quot;changelevel %s&amp;quot;, map);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DoVoteMenu(const char[] map)&lt;br /&gt;
{&lt;br /&gt;
	if (IsVoteInProgress())&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	Menu menu = new Menu(Handle_VoteMenu);&lt;br /&gt;
	menu.VoteResultCallback = Handle_VoteResults;&lt;br /&gt;
	menu.SetTitle(&amp;quot;Change map to: %s?&amp;quot;, map);&lt;br /&gt;
	menu.AddItem(map, &amp;quot;Yes&amp;quot;);&lt;br /&gt;
	menu.AddItem(&amp;quot;no&amp;quot;, &amp;quot;No&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.DisplayVoteToAll(20);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=ExitBack=&lt;br /&gt;
ExitBack is a special term to refer to the &amp;quot;ExitBack Button.&amp;quot;  This button is disabled by default.  Normally, paginated menus have no &amp;quot;Previous&amp;quot; item for the first page.  If the &amp;quot;ExitBack&amp;quot; button is enabled, the &amp;quot;Previous&amp;quot; item will show up as &amp;quot;Back.&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
Selecting the &amp;quot;ExitBack&amp;quot; option will exit the menu with &amp;lt;tt&amp;gt;MenuCancel_ExitBack&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;MenuEnd_ExitBack&amp;lt;/tt&amp;gt;.  The functionality of this is the same as a normal menu exit internally; extra functionality must be defined through the callbacks.&lt;br /&gt;
&lt;br /&gt;
=Closing Menu Handles=&lt;br /&gt;
It is only necessary to close a menu handle on &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt;.  The &amp;lt;tt&amp;gt;MenuAction_End&amp;lt;/tt&amp;gt; is done every time a menu is closed and no longer needed.&lt;br /&gt;
&lt;br /&gt;
=Translations=&lt;br /&gt;
It is possible to dynamically translate menus to each player through the &amp;lt;tt&amp;gt;MenuAction_DisplayItem&amp;lt;/tt&amp;gt; callback.  A special native, &amp;lt;tt&amp;gt;RedrawMenuItem&amp;lt;/tt&amp;gt;, is used to transform the text while inside the callback.  Let's redo the vote example from earlier to be translated:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public int Handle_VoteMenu(Menu menu, MenuAction action, int param1, int param2)&lt;br /&gt;
{&lt;br /&gt;
	if (action == MenuAction_End)&lt;br /&gt;
	{&lt;br /&gt;
		/* This is called after VoteEnd */&lt;br /&gt;
		delete menu;&lt;br /&gt;
	} else if (action == MenuAction_VoteEnd) {&lt;br /&gt;
		/* 0=yes, 1=no */&lt;br /&gt;
		if (param1 == 0)&lt;br /&gt;
		{&lt;br /&gt;
			char map[64];&lt;br /&gt;
			menu.GetItem(param1, map, sizeof(map));&lt;br /&gt;
			ServerCommand(&amp;quot;changelevel %s&amp;quot;, map);&lt;br /&gt;
		}&lt;br /&gt;
	} else if (action == MenuAction_DisplayItem) {&lt;br /&gt;
		/* Get the display string, we'll use it as a translation phrase */&lt;br /&gt;
		char display[64];&lt;br /&gt;
		menu.GetItem(param2, &amp;quot;&amp;quot;, 0, _, display, sizeof(display));&lt;br /&gt;
&lt;br /&gt;
		/* Translate the string to the client's language */&lt;br /&gt;
		char buffer[255];&lt;br /&gt;
		Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, display, param1);&lt;br /&gt;
&lt;br /&gt;
		/* Override the text */&lt;br /&gt;
		return RedrawMenuItem(buffer);&lt;br /&gt;
	} else if (action == MenuAction_Display) {&lt;br /&gt;
		/* Panel Handle is the second parameter */&lt;br /&gt;
		Panel panel = view_as&amp;lt;Panel&amp;gt;(param2);&lt;br /&gt;
		&lt;br /&gt;
		/* Get the map name we're changing to from the first item */&lt;br /&gt;
		char map[64];&lt;br /&gt;
		menu.GetItem(0, map, sizeof(map));&lt;br /&gt;
		&lt;br /&gt;
		/* Translate to our phrase */&lt;br /&gt;
		char buffer[255];&lt;br /&gt;
		Format(buffer, sizeof(buffer), &amp;quot;%T&amp;quot;, &amp;quot;Change map to?&amp;quot;, client, map);&lt;br /&gt;
&lt;br /&gt;
		panel.SetTitle(buffer);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void DoVoteMenu(const char[] map)&lt;br /&gt;
{&lt;br /&gt;
	if (IsVoteInProgress())&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
 &lt;br /&gt;
	Menu menu = new Menu(Handle_VoteMenu,MenuAction_DisplayItem|MenuAction_Display);&lt;br /&gt;
	menu.SetTitle(&amp;quot;Change map to: %s?&amp;quot;, map);&lt;br /&gt;
	menu.AddItem(map, &amp;quot;Yes&amp;quot;);&lt;br /&gt;
	menu.AddItem(&amp;quot;no&amp;quot;, &amp;quot;No&amp;quot;);&lt;br /&gt;
	menu.ExitButton = false;&lt;br /&gt;
	menu.DisplayVoteToAll(20);&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:SourceMod Development]]&lt;br /&gt;
[[Category:SourceMod Scripting]]&lt;br /&gt;
&lt;br /&gt;
{{LanguageSwitch}}&lt;/div&gt;</summary>
		<author><name>Mitchell</name></author>
		
	</entry>
</feed>