core/smn_menus.cpp
branchsourcemod-1.1.0
changeset 2283 03a67e41afbc
parent 1951 c7b4237fff50
child 2287 017a725c9d17
     1.1 --- a/core/smn_menus.cpp	Fri Mar 28 06:21:34 2008 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1518 +0,0 @@
     1.4 -/**
     1.5 - * vim: set ts=4 :
     1.6 - * =============================================================================
     1.7 - * SourceMod
     1.8 - * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     1.9 - * =============================================================================
    1.10 - *
    1.11 - * This program is free software; you can redistribute it and/or modify it under
    1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
    1.13 - * Free Software Foundation.
    1.14 - * 
    1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
    1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    1.18 - * details.
    1.19 - *
    1.20 - * You should have received a copy of the GNU General Public License along with
    1.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
    1.22 - *
    1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
    1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
    1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    1.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
    1.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
    1.28 - * this exception to all derivative works.  AlliedModders LLC defines further
    1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    1.30 - * or <http://www.sourcemod.net/license.php>.
    1.31 - *
    1.32 - * Version: $Id$
    1.33 - */
    1.34 -
    1.35 -#include "sm_globals.h"
    1.36 -#include <sh_stack.h>
    1.37 -#include "DebugReporter.h"
    1.38 -#include "MenuManager.h"
    1.39 -#include "MenuStyle_Valve.h"
    1.40 -#include "MenuStyle_Radio.h"
    1.41 -#include "HandleSys.h"
    1.42 -#include "PluginSys.h"
    1.43 -#include "PlayerManager.h"
    1.44 -#include "sm_stringutil.h"
    1.45 -#include "sourcemm_api.h"
    1.46 -#if defined MENU_DEBUG
    1.47 -#include "Logger.h"
    1.48 -#endif
    1.49 -#include "ChatTriggers.h"
    1.50 -
    1.51 -#if defined CreateMenu
    1.52 -#undef CreateMenu
    1.53 -#endif
    1.54 -
    1.55 -/**
    1.56 - * And God said, "let there be menus," and behold, there were menus.  
    1.57 - * God saw the menus and they were good.  And the evening and the morning
    1.58 - * were the third day.
    1.59 - */
    1.60 -
    1.61 -enum MenuAction
    1.62 -{
    1.63 -	MenuAction_Start = (1<<0),		/**< A menu has been started (nothing passed) */
    1.64 -	MenuAction_Display = (1<<1),	/**< A menu is about to be displayed (param1=client, param2=MenuPanel Handle) */
    1.65 -	MenuAction_Select = (1<<2),		/**< An item was selected (param1=client, param2=item) */
    1.66 -	MenuAction_Cancel = (1<<3),		/**< The menu was cancelled (param1=client, param2=item) */
    1.67 -	MenuAction_End = (1<<4),		/**< A menu's display/selection cycle is complete (nothing passed). */
    1.68 -	MenuAction_VoteEnd = (1<<5),	/**< (VOTE ONLY): A vote sequence has ended (param1=chosen item) */
    1.69 -	MenuAction_VoteStart = (1<<6), 	/**< (VOTE ONLY): A vote sequence has started */
    1.70 -	MenuAction_VoteCancel = (1<<7),	/**< (VOTE ONLY): A vote sequence has been cancelled (nothing passed) */
    1.71 -	MenuAction_DrawItem = (1<<8),	/**< A style is being drawn; return the new style (param1=client, param2=item) */
    1.72 -	MenuAction_DisplayItem = (1<<9),	/**< the odd duck */
    1.73 -};
    1.74 -
    1.75 -class CPanelHandler : public IMenuHandler
    1.76 -{
    1.77 -	friend class MenuNativeHelpers;
    1.78 -public:
    1.79 -	CPanelHandler()
    1.80 -	{
    1.81 -	}
    1.82 -	void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
    1.83 -	void OnMenuSelect(IBaseMenu *menu, int client, unsigned int item);
    1.84 -private:
    1.85 -	IPluginFunction *m_pFunc;
    1.86 -	IPlugin *m_pPlugin;
    1.87 -};
    1.88 -
    1.89 -class CMenuHandler : public IMenuHandler
    1.90 -{
    1.91 -	friend class MenuNativeHelpers;
    1.92 -public:
    1.93 -	CMenuHandler(IPluginFunction *pBasic, int flags);
    1.94 -public:
    1.95 -	void OnMenuStart(IBaseMenu *menu);
    1.96 -	void OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display);
    1.97 -	void OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page);
    1.98 -	void OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason);
    1.99 -	void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason);
   1.100 -	void OnMenuDestroy(IBaseMenu *menu);
   1.101 -	void OnMenuVoteStart(IBaseMenu *menu);
   1.102 -	void OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *results);
   1.103 -	void OnMenuVoteCancel(IBaseMenu *menu, VoteCancelReason reason);
   1.104 -	void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
   1.105 -	unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
   1.106 -	bool OnSetHandlerOption(const char *option, const void *data);
   1.107 -#if 0
   1.108 -	void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
   1.109 -	void OnMenuDisplayItem(IBaseMenu *menu, int client, unsigned int item, const char **display);
   1.110 -#endif
   1.111 -private:
   1.112 -	cell_t DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res=0);
   1.113 -private:
   1.114 -	IPluginFunction *m_pBasic;
   1.115 -	int m_Flags;
   1.116 -	IPluginFunction *m_pVoteResults;
   1.117 -	cell_t m_fnVoteResult;
   1.118 -};
   1.119 -
   1.120 -/**
   1.121 - * GLOBAL CLASS FOR HELPERS
   1.122 - */
   1.123 -
   1.124 -class MenuNativeHelpers : 
   1.125 -	public SMGlobalClass,
   1.126 -	public IHandleTypeDispatch,
   1.127 -	public IPluginsListener
   1.128 -{
   1.129 -public:
   1.130 -	virtual void OnSourceModAllInitialized()
   1.131 -	{
   1.132 -		m_PanelType = g_HandleSys.CreateType("IMenuPanel", this, 0, NULL, NULL, g_pCoreIdent, NULL);
   1.133 -		m_TempPanelType = g_HandleSys.CreateType("TempIMenuPanel", this, m_PanelType, NULL, NULL, g_pCoreIdent, NULL);
   1.134 -		g_PluginSys.AddPluginsListener(this);
   1.135 -	}
   1.136 -
   1.137 -	virtual void OnSourceModShutdown()
   1.138 -	{
   1.139 -		g_HandleSys.RemoveType(m_TempPanelType, g_pCoreIdent);
   1.140 -		g_HandleSys.RemoveType(m_PanelType, g_pCoreIdent);
   1.141 -
   1.142 -		while (!m_FreePanelHandlers.empty())
   1.143 -		{
   1.144 -			delete m_FreePanelHandlers.front();
   1.145 -			m_FreePanelHandlers.pop();
   1.146 -		}
   1.147 -
   1.148 -		while (!m_FreeMenuHandlers.empty())
   1.149 -		{
   1.150 -			delete m_FreeMenuHandlers.front();
   1.151 -			m_FreeMenuHandlers.pop();
   1.152 -		}
   1.153 -	}
   1.154 -
   1.155 -	virtual void OnHandleDestroy(HandleType_t type, void *object)
   1.156 -	{
   1.157 -		if (type == m_TempPanelType)
   1.158 -		{
   1.159 -			return;
   1.160 -		}
   1.161 -
   1.162 -		IMenuPanel *panel = (IMenuPanel *)object;
   1.163 -		panel->DeleteThis();
   1.164 -	}
   1.165 -
   1.166 -	/**
   1.167 -	 * It is extremely important that unloaded plugins don't crash.
   1.168 -	 * Thus, if a plugin unloads, we run through every handler we have.
   1.169 -	 * This means we do almost no runtime work for keeping track of
   1.170 -	 * our panel handlers (we don't have to store a list of the running 
   1.171 -	 * ones), but when push comes to shove, we have to scan them all
   1.172 -	 * in case any of them are active.
   1.173 -	 */
   1.174 -	virtual void OnPluginUnloaded(IPlugin *plugin)
   1.175 -	{
   1.176 -		for (size_t i = 0; i < m_PanelHandlers.size(); i++)
   1.177 -		{
   1.178 -			if (m_PanelHandlers[i]->m_pPlugin == plugin)
   1.179 -			{
   1.180 -				m_PanelHandlers[i]->m_pPlugin = NULL;
   1.181 -				m_PanelHandlers[i]->m_pFunc = NULL;
   1.182 -			}
   1.183 -		}
   1.184 -	}
   1.185 -
   1.186 -	inline HandleType_t GetPanelType()
   1.187 -	{
   1.188 -		return m_PanelType;
   1.189 -	}
   1.190 -
   1.191 -	inline HandleType_t GetTempPanelType()
   1.192 -	{
   1.193 -		return m_TempPanelType;
   1.194 -	}
   1.195 -
   1.196 -	CPanelHandler *GetPanelHandler(IPluginFunction *pFunction)
   1.197 -	{
   1.198 -		CPanelHandler *handler;
   1.199 -		if (m_FreePanelHandlers.empty())
   1.200 -		{
   1.201 -			handler = new CPanelHandler;
   1.202 -			m_PanelHandlers.push_back(handler);
   1.203 -		} else {
   1.204 -			handler = m_FreePanelHandlers.front();
   1.205 -			m_FreePanelHandlers.pop();
   1.206 -		}
   1.207 -		handler->m_pFunc = pFunction;
   1.208 -		handler->m_pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
   1.209 -		return handler;
   1.210 -	}
   1.211 -
   1.212 -	void FreePanelHandler(CPanelHandler *handler)
   1.213 -	{
   1.214 -		handler->m_pFunc = NULL;
   1.215 -		handler->m_pPlugin = NULL;
   1.216 -		m_FreePanelHandlers.push(handler);
   1.217 -	}
   1.218 -
   1.219 -	CMenuHandler *GetMenuHandler(IPluginFunction *pFunction, int flags)
   1.220 -	{
   1.221 -		CMenuHandler *handler;
   1.222 -		if (m_FreeMenuHandlers.empty())
   1.223 -		{
   1.224 -			handler = new CMenuHandler(pFunction, flags);
   1.225 -		} else {
   1.226 -			handler = m_FreeMenuHandlers.front();
   1.227 -			m_FreeMenuHandlers.pop();
   1.228 -			handler->m_pBasic = pFunction;
   1.229 -			handler->m_Flags = flags;
   1.230 -			handler->m_pVoteResults = NULL;
   1.231 -		}
   1.232 -		return handler;
   1.233 -	}
   1.234 -
   1.235 -	void FreeMenuHandler(CMenuHandler *handler)
   1.236 -	{
   1.237 -		m_FreeMenuHandlers.push(handler);
   1.238 -	}
   1.239 -
   1.240 -private:
   1.241 -	HandleType_t m_PanelType;
   1.242 -	HandleType_t m_TempPanelType;
   1.243 -	CStack<CPanelHandler *> m_FreePanelHandlers;
   1.244 -	CStack<CMenuHandler *> m_FreeMenuHandlers;
   1.245 -	CVector<CPanelHandler *> m_PanelHandlers;
   1.246 -} g_MenuHelpers;
   1.247 -
   1.248 -/**
   1.249 - * BASIC PANEL HANDLER WRAPPER
   1.250 - */
   1.251 -
   1.252 -void CPanelHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
   1.253 -{
   1.254 -	if (m_pFunc)
   1.255 -	{
   1.256 -		m_pFunc->PushCell(BAD_HANDLE);
   1.257 -		m_pFunc->PushCell(MenuAction_Cancel);
   1.258 -		m_pFunc->PushCell(client);
   1.259 -		m_pFunc->PushCell(reason);
   1.260 -		m_pFunc->Execute(NULL);
   1.261 -	}
   1.262 -	g_MenuHelpers.FreePanelHandler(this);
   1.263 -}
   1.264 -
   1.265 -void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
   1.266 -{
   1.267 -	if (m_pFunc)
   1.268 -	{
   1.269 -		unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
   1.270 -		m_pFunc->PushCell(BAD_HANDLE);
   1.271 -		m_pFunc->PushCell(MenuAction_Select);
   1.272 -		m_pFunc->PushCell(client);
   1.273 -		m_pFunc->PushCell(item);
   1.274 -		m_pFunc->Execute(NULL);
   1.275 -		g_ChatTriggers.SetReplyTo(old_reply);
   1.276 -	}
   1.277 -	g_MenuHelpers.FreePanelHandler(this);
   1.278 -}
   1.279 -
   1.280 -static IMenuPanel *s_pCurPanel = NULL;
   1.281 -static unsigned int s_CurPanelReturn = 0;
   1.282 -static const ItemDrawInfo *s_CurDrawInfo = NULL;
   1.283 -static unsigned int *s_CurSelectPosition = NULL;
   1.284 -
   1.285 -/**
   1.286 - * MENU HANDLER WRAPPER
   1.287 - */
   1.288 -CMenuHandler::CMenuHandler(IPluginFunction *pBasic, int flags) : 
   1.289 -	m_pBasic(pBasic), m_Flags(flags), m_pVoteResults(NULL)
   1.290 -{
   1.291 -	/* :TODO: We can probably cache the handle ahead of time */
   1.292 -}
   1.293 -
   1.294 -void CMenuHandler::OnMenuStart(IBaseMenu *menu)
   1.295 -{
   1.296 -	if ((m_Flags & (int)MenuAction_Start) == (int)MenuAction_Start)
   1.297 -	{
   1.298 -		DoAction(menu, MenuAction_Start, 0, 0);
   1.299 -	}
   1.300 -}
   1.301 -
   1.302 -void CMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *panel)
   1.303 -{
   1.304 -	if ((m_Flags & (int)MenuAction_Display) == (int)MenuAction_Display)
   1.305 -	{
   1.306 -		HandleSecurity sec;
   1.307 -		sec.pIdentity = g_pCoreIdent;
   1.308 -		sec.pOwner = m_pBasic->GetParentContext()->GetIdentity();
   1.309 -	
   1.310 -		HandleAccess access;
   1.311 -		g_HandleSys.InitAccessDefaults(NULL, &access);
   1.312 -		access.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
   1.313 -
   1.314 -		Handle_t hndl = g_HandleSys.CreateHandleEx(g_MenuHelpers.GetTempPanelType(), panel, &sec, &access, NULL);
   1.315 -
   1.316 -		DoAction(menu, MenuAction_Display, client, hndl);
   1.317 -
   1.318 -		g_HandleSys.FreeHandle(hndl, &sec);
   1.319 -	}
   1.320 -}
   1.321 -
   1.322 -void CMenuHandler::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item, unsigned int item_on_page)
   1.323 -{
   1.324 -	/* Save old position first. */
   1.325 -	unsigned int first_item = item_on_page;
   1.326 -	unsigned int *old_pos = s_CurSelectPosition;
   1.327 -
   1.328 -	s_CurSelectPosition = &first_item;
   1.329 -
   1.330 -	unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
   1.331 -	DoAction(menu, MenuAction_Select, client, item);
   1.332 -	g_ChatTriggers.SetReplyTo(old_reply);
   1.333 -
   1.334 -	s_CurSelectPosition = old_pos;
   1.335 -}
   1.336 -
   1.337 -void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
   1.338 -{
   1.339 -	unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
   1.340 -	DoAction(menu, MenuAction_Cancel, client, (cell_t)reason);
   1.341 -	g_ChatTriggers.SetReplyTo(old_reply);
   1.342 -}
   1.343 -
   1.344 -void CMenuHandler::OnMenuEnd(IBaseMenu *menu, MenuEndReason reason)
   1.345 -{
   1.346 -	DoAction(menu, MenuAction_End, reason, 0);
   1.347 -}
   1.348 -
   1.349 -void CMenuHandler::OnMenuDestroy(IBaseMenu *menu)
   1.350 -{
   1.351 -	g_MenuHelpers.FreeMenuHandler(this);
   1.352 -}
   1.353 -
   1.354 -void CMenuHandler::OnMenuVoteStart(IBaseMenu *menu)
   1.355 -{
   1.356 -	DoAction(menu, MenuAction_VoteStart, 0, 0);
   1.357 -}
   1.358 -
   1.359 -void CMenuHandler::OnMenuVoteCancel(IBaseMenu *menu, VoteCancelReason reason)
   1.360 -{
   1.361 -	DoAction(menu, MenuAction_VoteCancel, reason, 0);
   1.362 -}
   1.363 -
   1.364 -void CMenuHandler::OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style)
   1.365 -{
   1.366 -	if ((m_Flags & (int)MenuAction_DrawItem) == (int)MenuAction_DrawItem)
   1.367 -	{
   1.368 -		cell_t result = DoAction(menu, MenuAction_DrawItem, client, item, style);
   1.369 -		style = (unsigned int)result;
   1.370 -	}
   1.371 -}
   1.372 -
   1.373 -unsigned int CMenuHandler::OnMenuDisplayItem(IBaseMenu *menu,
   1.374 -									 int client,
   1.375 -									 IMenuPanel *panel,
   1.376 -									 unsigned int item,
   1.377 -									 const ItemDrawInfo &dr)
   1.378 -{
   1.379 -	if ((m_Flags & (int)MenuAction_DisplayItem) == (int)MenuAction_DisplayItem)
   1.380 -	{
   1.381 -		IMenuPanel *oldpanel = s_pCurPanel;
   1.382 -		unsigned int oldret = s_CurPanelReturn;
   1.383 -		const ItemDrawInfo *oldinfo = s_CurDrawInfo;
   1.384 -		s_pCurPanel = panel;
   1.385 -		s_CurPanelReturn = 0;
   1.386 -		s_CurDrawInfo = &dr;
   1.387 -
   1.388 -		cell_t res = DoAction(menu, MenuAction_DisplayItem, client, item, 0);
   1.389 -
   1.390 -		if (!res)
   1.391 -		{
   1.392 -			res = s_CurPanelReturn;
   1.393 -		}
   1.394 -
   1.395 -		s_pCurPanel = oldpanel;
   1.396 -		s_CurPanelReturn = oldret;
   1.397 -		s_CurDrawInfo = oldinfo;
   1.398 -
   1.399 -		return res;
   1.400 -	}
   1.401 -
   1.402 -	return 0;
   1.403 -}
   1.404 -
   1.405 -cell_t CMenuHandler::DoAction(IBaseMenu *menu, MenuAction action, cell_t param1, cell_t param2, cell_t def_res)
   1.406 -{
   1.407 -#if defined MENU_DEBUG
   1.408 -	g_Logger.LogMessage("[SM_MENU] CMenuHandler::DoAction() (menu %p/%08x) (action %d) (param1 %d) (param2 %d)",
   1.409 -		menu,
   1.410 -		menu->GetHandle(),
   1.411 -		action,
   1.412 -		param1,
   1.413 -		param2);
   1.414 -#endif
   1.415 -	cell_t res = def_res;
   1.416 -	m_pBasic->PushCell(menu->GetHandle());
   1.417 -	m_pBasic->PushCell((cell_t)action);
   1.418 -	m_pBasic->PushCell(param1);
   1.419 -	m_pBasic->PushCell(param2);
   1.420 -	m_pBasic->Execute(&res);
   1.421 -	return res;
   1.422 -}
   1.423 -
   1.424 -void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *results)
   1.425 -{
   1.426 -	if (!m_pVoteResults)
   1.427 -	{
   1.428 -		/* Call MenuAction_VoteEnd instead.  See if there are any extra winners. */
   1.429 -		unsigned int num_items = 1;
   1.430 -		for (unsigned int i=1; i<results->num_items; i++)
   1.431 -		{
   1.432 -			if (results->item_list[i].count != results->item_list[0].count)
   1.433 -			{
   1.434 -				break;
   1.435 -			}
   1.436 -			num_items++;
   1.437 -		}
   1.438 -
   1.439 -		/* See if we need to pick a random winner. */
   1.440 -		unsigned int winning_item;
   1.441 -		if (num_items > 1)
   1.442 -		{
   1.443 -			/* Yes, we do. */
   1.444 -			srand(time(NULL));
   1.445 -			winning_item = rand() % num_items;
   1.446 -			winning_item = results->item_list[winning_item].item;
   1.447 -		} else {
   1.448 -			/* No, take the first. */
   1.449 -			winning_item = results->item_list[0].item;
   1.450 -		}
   1.451 -
   1.452 -		unsigned int total_votes = results->num_votes;
   1.453 -		unsigned int winning_votes = results->item_list[0].count;
   1.454 -
   1.455 -		DoAction(menu, MenuAction_VoteEnd, winning_item, (total_votes << 16) | (winning_votes & 0xFFFF));
   1.456 -	} else {
   1.457 -		IPluginContext *pContext = m_pVoteResults->GetParentContext();
   1.458 -		bool no_call = false;
   1.459 -		int err;
   1.460 -
   1.461 -		/* First array */
   1.462 -		cell_t client_array_address = -1;
   1.463 -		cell_t *client_array_base = NULL;
   1.464 -		cell_t client_array_size = results->num_clients + (results->num_clients * 2);
   1.465 -		if (client_array_size)
   1.466 -		{
   1.467 -			if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base))
   1.468 -				!= SP_ERROR_NONE)
   1.469 -			{
   1.470 -				g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
   1.471 -				no_call = true;
   1.472 -			} else {
   1.473 -				cell_t target_offs = sizeof(cell_t) * results->num_clients;
   1.474 -				cell_t *cur_index = client_array_base;
   1.475 -				cell_t *cur_array;
   1.476 -				for (unsigned int i=0; i<results->num_clients; i++)
   1.477 -				{
   1.478 -					/* Copy the array index */
   1.479 -					*cur_index = target_offs;
   1.480 -					/* Get the current array address */
   1.481 -					cur_array = (cell_t *)((char *)cur_index + target_offs);
   1.482 -					/* Store information */
   1.483 -					cur_array[0] = results->client_list[i].client;
   1.484 -					cur_array[1] = results->client_list[i].item;
   1.485 -					/* Adjust for the new target by subtracting one indirection
   1.486 -					 * and adding one array.
   1.487 -					 */
   1.488 -					target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
   1.489 -					cur_index++;
   1.490 -				}
   1.491 -			}
   1.492 -		}
   1.493 -
   1.494 -		/* Second array */
   1.495 -		cell_t item_array_address = -1;
   1.496 -		cell_t *item_array_base = NULL;
   1.497 -		cell_t item_array_size = results->num_items + (results->num_items * 2);
   1.498 -		if (item_array_size)
   1.499 -		{
   1.500 -			if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base))
   1.501 -				!= SP_ERROR_NONE)
   1.502 -			{
   1.503 -				g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
   1.504 -				no_call = true;
   1.505 -			} else {
   1.506 -				cell_t target_offs = sizeof(cell_t) * results->num_items;
   1.507 -				cell_t *cur_index = item_array_base;
   1.508 -				cell_t *cur_array;
   1.509 -				for (unsigned int i=0; i<results->num_items; i++)
   1.510 -				{
   1.511 -					/* Copy the array index */
   1.512 -					*cur_index = target_offs;
   1.513 -					/* Get the current array address */
   1.514 -					cur_array = (cell_t *)((char *)cur_index + target_offs);
   1.515 -					/* Store information */
   1.516 -					cur_array[0] = results->item_list[i].item;
   1.517 -					cur_array[1] = results->item_list[i].count;
   1.518 -					/* Adjust for the new target by subtracting one indirection
   1.519 -					 * and adding one array.
   1.520 -					 */
   1.521 -					target_offs += (sizeof(cell_t) * 2) - sizeof(cell_t);
   1.522 -					cur_index++;
   1.523 -				}
   1.524 -			}
   1.525 -		}
   1.526 -
   1.527 -		/* Finally, push everything */
   1.528 -		if (!no_call)
   1.529 -		{
   1.530 -			m_pVoteResults->PushCell(menu->GetHandle());
   1.531 -			m_pVoteResults->PushCell(results->num_votes);
   1.532 -			m_pVoteResults->PushCell(results->num_clients);
   1.533 -			m_pVoteResults->PushCell(client_array_address);
   1.534 -			m_pVoteResults->PushCell(results->num_items);
   1.535 -			m_pVoteResults->PushCell(item_array_address);
   1.536 -			m_pVoteResults->Execute(NULL);
   1.537 -		}
   1.538 -
   1.539 -		/* Free what we allocated, in reverse order as required */
   1.540 -		if (item_array_address != -1)
   1.541 -		{
   1.542 -			pContext->HeapPop(item_array_address);
   1.543 -		}
   1.544 -		if (client_array_address != -1)
   1.545 -		{
   1.546 -			pContext->HeapPop(client_array_address);
   1.547 -		}
   1.548 -	}
   1.549 -}
   1.550 -
   1.551 -bool CMenuHandler::OnSetHandlerOption(const char *option, const void *data)
   1.552 -{
   1.553 -	if (strcmp(option, "set_vote_results_handler") == 0)
   1.554 -	{
   1.555 -		void **array = (void **)data;
   1.556 -		m_pVoteResults = (IPluginFunction *)array[0];
   1.557 -		m_fnVoteResult = *(cell_t *)((cell_t *)array[1]);
   1.558 -		return true;
   1.559 -	}
   1.560 -
   1.561 -	return false;
   1.562 -}
   1.563 -
   1.564 -/**
   1.565 - * INLINE FUNCTIONS FOR NATIVES
   1.566 - */
   1.567 -
   1.568 -inline Handle_t MakePanelHandle(IMenuPanel *panel, IPluginContext *pContext)
   1.569 -{
   1.570 -	return g_HandleSys.CreateHandle(g_MenuHelpers.GetPanelType(), panel, pContext->GetIdentity(), g_pCoreIdent, NULL);
   1.571 -}
   1.572 -
   1.573 -inline HandleError ReadPanelHandle(Handle_t hndl, IMenuPanel **panel)
   1.574 -{
   1.575 -	HandleSecurity sec;
   1.576 -	sec.pIdentity = g_pCoreIdent;
   1.577 -	sec.pOwner = NULL;
   1.578 -	return g_HandleSys.ReadHandle(hndl, g_MenuHelpers.GetPanelType(), &sec, (void **)panel);
   1.579 -}
   1.580 -
   1.581 -inline IMenuStyle *GetStyleFromCell(cell_t cell)
   1.582 -{
   1.583 -	enum MenuStyle
   1.584 -	{
   1.585 -		MenuStyle_Default = 0,		/**< The "default" menu style for the mod */
   1.586 -		MenuStyle_Valve = 1,		/**< The Valve provided menu style (Used on HL2DM) */
   1.587 -		MenuStyle_Radio = 2,		/**< The simpler menu style commonly used on CS:S */
   1.588 -	};
   1.589 -
   1.590 -	if (cell == MenuStyle_Valve)
   1.591 -	{
   1.592 -		return &g_ValveMenuStyle;
   1.593 -	} else if (cell == MenuStyle_Radio
   1.594 -			   && g_RadioMenuStyle.IsSupported())
   1.595 -	{
   1.596 -		return &g_RadioMenuStyle;
   1.597 -	}
   1.598 -
   1.599 -	return g_Menus.GetDefaultStyle();
   1.600 -}
   1.601 -
   1.602 -/***********************************
   1.603 - **** NATIVE DEFINITIONS ***********
   1.604 - ***********************************/
   1.605 -
   1.606 -static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
   1.607 -{
   1.608 -	IMenuStyle *style = g_Menus.GetDefaultStyle();
   1.609 -	IPluginFunction *pFunction;
   1.610 -
   1.611 -	if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
   1.612 -	{
   1.613 -		return pContext->ThrowNativeError("Function id %x is invalid", params[1]);
   1.614 -	}
   1.615 -
   1.616 -	CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[2]);
   1.617 -	IBaseMenu *menu = style->CreateMenu(handler, pContext->GetIdentity());
   1.618 -
   1.619 -	Handle_t hndl = menu->GetHandle();
   1.620 -	if (!hndl)
   1.621 -	{
   1.622 -		menu->Destroy();
   1.623 -		return BAD_HANDLE;
   1.624 -	}
   1.625 -
   1.626 -	return hndl;
   1.627 -}
   1.628 -
   1.629 -static cell_t DisplayMenu(IPluginContext *pContext, const cell_t *params)
   1.630 -{
   1.631 -	Handle_t hndl = (Handle_t)params[1];
   1.632 -	HandleError err;
   1.633 -	IBaseMenu *menu;
   1.634 -
   1.635 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.636 -	{
   1.637 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.638 -	}
   1.639 -
   1.640 -	return menu->Display(params[2], params[3]) ? 1 : 0;
   1.641 -}
   1.642 -
   1.643 -static cell_t DisplayMenuAtItem(IPluginContext *pContext, const cell_t *params)
   1.644 -{
   1.645 -	Handle_t hndl = (Handle_t)params[1];
   1.646 -	HandleError err;
   1.647 -	IBaseMenu *menu;
   1.648 -
   1.649 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.650 -	{
   1.651 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.652 -	}
   1.653 -
   1.654 -	return menu->DisplayAtItem(params[2], params[4], params[3]) ? 1 : 0;
   1.655 -}
   1.656 -
   1.657 -static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
   1.658 -{
   1.659 -	if (g_Menus.IsVoteInProgress())
   1.660 -	{
   1.661 -		return pContext->ThrowNativeError("A vote is already in progress");
   1.662 -	}
   1.663 -
   1.664 -	Handle_t hndl = (Handle_t)params[1];
   1.665 -	HandleError err;
   1.666 -	IBaseMenu *menu;
   1.667 -
   1.668 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.669 -	{
   1.670 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.671 -	}
   1.672 -
   1.673 -	cell_t *addr;
   1.674 -	pContext->LocalToPhysAddr(params[2], &addr);
   1.675 -
   1.676 -	if (!g_Menus.StartVote(menu, params[3], addr, params[4]))
   1.677 -	{
   1.678 -		return 0;
   1.679 -	}
   1.680 -
   1.681 -	return 1;
   1.682 -}
   1.683 -
   1.684 -static cell_t AddMenuItem(IPluginContext *pContext, const cell_t *params)
   1.685 -{
   1.686 -	Handle_t hndl = (Handle_t)params[1];
   1.687 -	HandleError err;
   1.688 -	IBaseMenu *menu;
   1.689 -
   1.690 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.691 -	{
   1.692 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.693 -	}
   1.694 -
   1.695 -	char *info;
   1.696 -	ItemDrawInfo dr;
   1.697 -
   1.698 -	pContext->LocalToString(params[2], &info);
   1.699 -	pContext->LocalToString(params[3], (char **)&dr.display);
   1.700 -	dr.style = params[4];
   1.701 -
   1.702 -	return menu->AppendItem(info, dr) ? 1 : 0;
   1.703 -}
   1.704 -
   1.705 -static cell_t InsertMenuItem(IPluginContext *pContext, const cell_t *params)
   1.706 -{
   1.707 -	Handle_t hndl = (Handle_t)params[1];
   1.708 -	HandleError err;
   1.709 -	IBaseMenu *menu;
   1.710 -
   1.711 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.712 -	{
   1.713 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.714 -	}
   1.715 -
   1.716 -	char *info;
   1.717 -	ItemDrawInfo dr;
   1.718 -
   1.719 -	pContext->LocalToString(params[3], &info);
   1.720 -	pContext->LocalToString(params[4], (char **)&dr.display);
   1.721 -	dr.style = params[5];
   1.722 -
   1.723 -	return menu->InsertItem(params[2], info, dr) ? 1 : 0;
   1.724 -}
   1.725 -
   1.726 -static cell_t RemoveMenuItem(IPluginContext *pContext, const cell_t *params)
   1.727 -{
   1.728 -	Handle_t hndl = (Handle_t)params[1];
   1.729 -	HandleError err;
   1.730 -	IBaseMenu *menu;
   1.731 -
   1.732 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.733 -	{
   1.734 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.735 -	}
   1.736 -
   1.737 -	return menu->RemoveItem(params[2]) ? 1 : 0;
   1.738 -}
   1.739 -
   1.740 -static cell_t RemoveAllMenuItems(IPluginContext *pContext, const cell_t *params)
   1.741 -{
   1.742 -	Handle_t hndl = (Handle_t)params[1];
   1.743 -	HandleError err;
   1.744 -	IBaseMenu *menu;
   1.745 -
   1.746 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.747 -	{
   1.748 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.749 -	}
   1.750 -
   1.751 -	menu->RemoveAllItems();
   1.752 -
   1.753 -	return 1;
   1.754 -}
   1.755 -
   1.756 -static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
   1.757 -{
   1.758 -	Handle_t hndl = (Handle_t)params[1];
   1.759 -	HandleError err;
   1.760 -	IBaseMenu *menu;
   1.761 -
   1.762 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.763 -	{
   1.764 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.765 -	}
   1.766 -
   1.767 -	ItemDrawInfo dr;
   1.768 -	const char *info;
   1.769 -
   1.770 -	if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
   1.771 -	{
   1.772 -		return 0;
   1.773 -	}
   1.774 -
   1.775 -	pContext->StringToLocalUTF8(params[3], params[4], info, NULL);
   1.776 -	pContext->StringToLocalUTF8(params[6], params[7], dr.display ? dr.display : "", NULL);
   1.777 -
   1.778 -	cell_t *addr;
   1.779 -	pContext->LocalToPhysAddr(params[5], &addr);
   1.780 -	*addr = dr.style;
   1.781 -
   1.782 -	return 1;
   1.783 -}
   1.784 -
   1.785 -static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
   1.786 -{
   1.787 -	Handle_t hndl = (Handle_t)params[1];
   1.788 -	HandleError err;
   1.789 -	IBaseMenu *menu;
   1.790 -
   1.791 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.792 -	{
   1.793 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.794 -	}
   1.795 -
   1.796 -	return menu->SetPagination(params[2]) ? 1 : 0;
   1.797 -}
   1.798 -
   1.799 -static cell_t GetMenuPagination(IPluginContext *pContext, const cell_t *params)
   1.800 -{
   1.801 -	Handle_t hndl = (Handle_t)params[1];
   1.802 -	HandleError err;
   1.803 -	IBaseMenu *menu;
   1.804 -
   1.805 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.806 -	{
   1.807 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.808 -	}
   1.809 -
   1.810 -	return menu->GetPagination();
   1.811 -}
   1.812 -
   1.813 -static cell_t GetMenuItemCount(IPluginContext *pContext, const cell_t *params)
   1.814 -{
   1.815 -	Handle_t hndl = (Handle_t)params[1];
   1.816 -	HandleError err;
   1.817 -	IBaseMenu *menu;
   1.818 -
   1.819 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.820 -	{
   1.821 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.822 -	}
   1.823 -
   1.824 -	return menu->GetItemCount();
   1.825 -}
   1.826 -
   1.827 -static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
   1.828 -{
   1.829 -	Handle_t hndl = (Handle_t)params[1];
   1.830 -	HandleError err;
   1.831 -	IBaseMenu *menu;
   1.832 -
   1.833 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.834 -	{
   1.835 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.836 -	}
   1.837 -
   1.838 -	g_SourceMod.SetGlobalTarget(LANG_SERVER);
   1.839 -
   1.840 -	char buffer[1024];
   1.841 -	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
   1.842 -
   1.843 -	menu->SetDefaultTitle(buffer);
   1.844 -
   1.845 -	return 1;
   1.846 -}
   1.847 -
   1.848 -static cell_t GetMenuTitle(IPluginContext *pContext, const cell_t *params)
   1.849 -{
   1.850 -	Handle_t hndl = (Handle_t)params[1];
   1.851 -	HandleError err;
   1.852 -	IBaseMenu *menu;
   1.853 -
   1.854 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.855 -	{
   1.856 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.857 -	}
   1.858 -
   1.859 -	size_t written;
   1.860 -	const char *title = menu->GetDefaultTitle();
   1.861 -	pContext->StringToLocalUTF8(params[2], params[3], title, &written);
   1.862 -
   1.863 -	return (cell_t)written;
   1.864 -}
   1.865 -
   1.866 -
   1.867 -static cell_t CreatePanelFromMenu(IPluginContext *pContext, const cell_t *params)
   1.868 -{
   1.869 -	Handle_t hndl = (Handle_t)params[1];
   1.870 -	HandleError err;
   1.871 -	IBaseMenu *menu;
   1.872 -
   1.873 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.874 -	{
   1.875 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.876 -	}
   1.877 -
   1.878 -	IMenuPanel *panel = menu->CreatePanel();
   1.879 -	hndl = MakePanelHandle(panel, pContext);
   1.880 -	if (!hndl)
   1.881 -	{
   1.882 -		panel->DeleteThis();
   1.883 -	}
   1.884 -
   1.885 -	return hndl;
   1.886 -}
   1.887 -
   1.888 -static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params)
   1.889 -{
   1.890 -	Handle_t hndl = (Handle_t)params[1];
   1.891 -	HandleError err;
   1.892 -	IBaseMenu *menu;
   1.893 -
   1.894 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.895 -	{
   1.896 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.897 -	}
   1.898 -
   1.899 -	return ((menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT) ? 1 : 0;
   1.900 -}
   1.901 -
   1.902 -static cell_t GetMenuExitBackButton(IPluginContext *pContext, const cell_t *params)
   1.903 -{
   1.904 -	Handle_t hndl = (Handle_t)params[1];
   1.905 -	HandleError err;
   1.906 -	IBaseMenu *menu;
   1.907 -
   1.908 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.909 -	{
   1.910 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.911 -	}
   1.912 -
   1.913 -	return ((menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXITBACK) == MENUFLAG_BUTTON_EXIT) ? 1 : 0;
   1.914 -}
   1.915 -
   1.916 -static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params)
   1.917 -{
   1.918 -	Handle_t hndl = (Handle_t)params[1];
   1.919 -	HandleError err;
   1.920 -	IBaseMenu *menu;
   1.921 -
   1.922 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.923 -	{
   1.924 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.925 -	}
   1.926 -
   1.927 -	unsigned int flags = menu->GetMenuOptionFlags();
   1.928 -
   1.929 -	if (params[2])
   1.930 -	{
   1.931 -		flags |= MENUFLAG_BUTTON_EXIT;
   1.932 -	} else {
   1.933 -		flags &= ~MENUFLAG_BUTTON_EXIT;
   1.934 -	}
   1.935 -
   1.936 -	menu->SetMenuOptionFlags(flags);
   1.937 -	unsigned int new_flags = menu->GetMenuOptionFlags();
   1.938 -
   1.939 -	return (flags == new_flags);
   1.940 -}
   1.941 -
   1.942 -static cell_t SetMenuExitBackButton(IPluginContext *pContext, const cell_t *params)
   1.943 -{
   1.944 -	Handle_t hndl = (Handle_t)params[1];
   1.945 -	HandleError err;
   1.946 -	IBaseMenu *menu;
   1.947 -
   1.948 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.949 -	{
   1.950 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.951 -	}
   1.952 -
   1.953 -	unsigned int flags = menu->GetMenuOptionFlags();
   1.954 -
   1.955 -	if (params[2])
   1.956 -	{
   1.957 -		flags |= MENUFLAG_BUTTON_EXITBACK;
   1.958 -	} else {
   1.959 -		flags &= ~MENUFLAG_BUTTON_EXITBACK;
   1.960 -	}
   1.961 -
   1.962 -	menu->SetMenuOptionFlags(flags);
   1.963 -
   1.964 -	return 1;
   1.965 -}
   1.966 -
   1.967 -static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params)
   1.968 -{
   1.969 -	Handle_t hndl = (Handle_t)params[1];
   1.970 -	HandleError err;
   1.971 -	IBaseMenu *menu;
   1.972 -
   1.973 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.974 -	{
   1.975 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.976 -	}
   1.977 -
   1.978 -	g_Menus.CancelMenu(menu);
   1.979 -
   1.980 -	return 1;
   1.981 -}
   1.982 -
   1.983 -static cell_t IsVoteInProgress(IPluginContext *pContext, const cell_t *params)
   1.984 -{
   1.985 -	return g_Menus.IsVoteInProgress() ? 1 : 0;
   1.986 -}
   1.987 -
   1.988 -static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
   1.989 -{
   1.990 -	Handle_t hndl = (Handle_t)params[1];
   1.991 -	HandleError err;
   1.992 -	IBaseMenu *menu;
   1.993 -
   1.994 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
   1.995 -	{
   1.996 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
   1.997 -	}
   1.998 -
   1.999 -	return menu->GetDrawStyle()->GetHandle();
  1.1000 -}
  1.1001 -
  1.1002 -static cell_t GetMenuStyleHandle(IPluginContext *pContext, const cell_t *params)
  1.1003 -{
  1.1004 -	IMenuStyle *style = GetStyleFromCell(params[1]);
  1.1005 -	if (!style)
  1.1006 -	{
  1.1007 -		return BAD_HANDLE;
  1.1008 -	}
  1.1009 -
  1.1010 -	return style->GetHandle();
  1.1011 -}
  1.1012 -
  1.1013 -static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
  1.1014 -{
  1.1015 -	Handle_t hndl = (Handle_t)params[1];
  1.1016 -	HandleError err;
  1.1017 -	IMenuStyle *style;
  1.1018 -
  1.1019 -	if (hndl != 0)
  1.1020 -	{
  1.1021 -		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
  1.1022 -		{
  1.1023 -			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
  1.1024 -		}
  1.1025 -	} else {
  1.1026 -		style = g_Menus.GetDefaultStyle();
  1.1027 -	}
  1.1028 -
  1.1029 -	IMenuPanel *panel = style->CreatePanel();
  1.1030 -
  1.1031 -	hndl = MakePanelHandle(panel, pContext);
  1.1032 -	if (!hndl)
  1.1033 -	{
  1.1034 -		panel->DeleteThis();
  1.1035 -		return BAD_HANDLE;
  1.1036 -	}
  1.1037 -
  1.1038 -	return hndl;
  1.1039 -}
  1.1040 -
  1.1041 -static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
  1.1042 -{
  1.1043 -	Handle_t hndl = (Handle_t)params[1];
  1.1044 -	HandleError err;
  1.1045 -	IMenuStyle *style;
  1.1046 -
  1.1047 -	if (hndl != 0)
  1.1048 -	{
  1.1049 -		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
  1.1050 -		{
  1.1051 -			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
  1.1052 -		}
  1.1053 -	} else {
  1.1054 -		style = g_Menus.GetDefaultStyle();
  1.1055 -	}
  1.1056 -
  1.1057 -	IPluginFunction *pFunction;
  1.1058 -	if ((pFunction=pContext->GetFunctionById(params[2])) == NULL)
  1.1059 -	{
  1.1060 -		return pContext->ThrowNativeError("Function id %x is invalid", params[2]);
  1.1061 -	}
  1.1062 -
  1.1063 -	CMenuHandler *handler = g_MenuHelpers.GetMenuHandler(pFunction, params[3]);
  1.1064 -
  1.1065 -	IBaseMenu *pMenu = style->CreateMenu(handler, pContext->GetIdentity());
  1.1066 -	hndl = pMenu->GetHandle();
  1.1067 -	if (!hndl)
  1.1068 -	{
  1.1069 -		pMenu->Destroy();
  1.1070 -		return BAD_HANDLE;
  1.1071 -	}
  1.1072 -
  1.1073 -	return hndl;
  1.1074 -}
  1.1075 -
  1.1076 -static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
  1.1077 -{
  1.1078 -	Handle_t hndl = (Handle_t)params[2];
  1.1079 -	HandleError err;
  1.1080 -	IMenuStyle *style;
  1.1081 -
  1.1082 -	if (hndl != 0)
  1.1083 -	{
  1.1084 -		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
  1.1085 -		{
  1.1086 -			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
  1.1087 -		}
  1.1088 -	} else {
  1.1089 -		style = g_Menus.GetDefaultStyle();
  1.1090 -	}
  1.1091 -
  1.1092 -	return style->GetClientMenu(params[1], NULL);
  1.1093 -}
  1.1094 -
  1.1095 -static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
  1.1096 -{
  1.1097 -	Handle_t hndl = (Handle_t)params[3];
  1.1098 -	HandleError err;
  1.1099 -	IMenuStyle *style;
  1.1100 -
  1.1101 -	if (hndl != 0)
  1.1102 -	{
  1.1103 -		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
  1.1104 -		{
  1.1105 -			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
  1.1106 -		}
  1.1107 -	} else {
  1.1108 -		style = g_Menus.GetDefaultStyle();
  1.1109 -	}
  1.1110 -
  1.1111 -	return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
  1.1112 -}
  1.1113 -
  1.1114 -static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
  1.1115 -{
  1.1116 -	Handle_t hndl = (Handle_t)params[1];
  1.1117 -	HandleError err;
  1.1118 -	IMenuStyle *style;
  1.1119 -
  1.1120 -	if (hndl != 0)
  1.1121 -	{
  1.1122 -		if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
  1.1123 -		{
  1.1124 -			return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
  1.1125 -		}
  1.1126 -	} else {
  1.1127 -		style = g_Menus.GetDefaultStyle();
  1.1128 -	}
  1.1129 -
  1.1130 -	return style->GetMaxPageItems();
  1.1131 -}
  1.1132 -
  1.1133 -static cell_t GetPanelStyle(IPluginContext *pContext, const cell_t *params)
  1.1134 -{
  1.1135 -	Handle_t hndl = (Handle_t)params[1];
  1.1136 -	HandleError err;
  1.1137 -	IMenuPanel *panel;
  1.1138 -
  1.1139 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1140 -	{
  1.1141 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1142 -	}
  1.1143 -
  1.1144 -	return panel->GetParentStyle()->GetHandle();
  1.1145 -}
  1.1146 -
  1.1147 -static cell_t SetPanelTitle(IPluginContext *pContext, const cell_t *params)
  1.1148 -{
  1.1149 -	Handle_t hndl = (Handle_t)params[1];
  1.1150 -	HandleError err;
  1.1151 -	IMenuPanel *panel;
  1.1152 -
  1.1153 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1154 -	{
  1.1155 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1156 -	}
  1.1157 -
  1.1158 -	char *text;
  1.1159 -	pContext->LocalToString(params[2], &text);
  1.1160 -
  1.1161 -	panel->DrawTitle(text, params[3] ? true : false);
  1.1162 -
  1.1163 -	return 1;
  1.1164 -}
  1.1165 -
  1.1166 -static cell_t DrawPanelItem(IPluginContext *pContext, const cell_t *params)
  1.1167 -{
  1.1168 -	Handle_t hndl = (Handle_t)params[1];
  1.1169 -	HandleError err;
  1.1170 -	IMenuPanel *panel;
  1.1171 -
  1.1172 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1173 -	{
  1.1174 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1175 -	}
  1.1176 -
  1.1177 -	ItemDrawInfo dr;
  1.1178 -	pContext->LocalToString(params[2], (char **)&dr.display);
  1.1179 -	dr.style = params[3];
  1.1180 -
  1.1181 -	return panel->DrawItem(dr);
  1.1182 -}
  1.1183 -
  1.1184 -static cell_t DrawPanelText(IPluginContext *pContext, const cell_t *params)
  1.1185 -{
  1.1186 -	Handle_t hndl = (Handle_t)params[1];
  1.1187 -	HandleError err;
  1.1188 -	IMenuPanel *panel;
  1.1189 -
  1.1190 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1191 -	{
  1.1192 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1193 -	}
  1.1194 -
  1.1195 -	char *text;
  1.1196 -	pContext->LocalToString(params[2], &text);
  1.1197 -
  1.1198 -	return panel->DrawRawLine(text) ? 1 : 0;
  1.1199 -}
  1.1200 -
  1.1201 -static cell_t CanPanelDrawFlags(IPluginContext *pContext, const cell_t *params)
  1.1202 -{
  1.1203 -	Handle_t hndl = (Handle_t)params[1];
  1.1204 -	HandleError err;
  1.1205 -	IMenuPanel *panel;
  1.1206 -
  1.1207 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1208 -	{
  1.1209 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1210 -	}
  1.1211 -
  1.1212 -	return panel->CanDrawItem(params[2]);
  1.1213 -}
  1.1214 -
  1.1215 -static cell_t SendPanelToClient(IPluginContext *pContext, const cell_t *params)
  1.1216 -{
  1.1217 -	Handle_t hndl = (Handle_t)params[1];
  1.1218 -	HandleError err;
  1.1219 -	IMenuPanel *panel;
  1.1220 -
  1.1221 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1222 -	{
  1.1223 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1224 -	}
  1.1225 -
  1.1226 -	IPluginFunction *pFunction;
  1.1227 -	if ((pFunction=pContext->GetFunctionById(params[3])) == NULL)
  1.1228 -	{
  1.1229 -		return pContext->ThrowNativeError("Function id %x is invalid", params[3]);
  1.1230 -	}
  1.1231 -
  1.1232 -	CPanelHandler *handler = g_MenuHelpers.GetPanelHandler(pFunction);
  1.1233 -	if (!panel->SendDisplay(params[2], handler, params[4]))
  1.1234 -	{
  1.1235 -		g_MenuHelpers.FreePanelHandler(handler);
  1.1236 -	}
  1.1237 -
  1.1238 -	return 1;
  1.1239 -}
  1.1240 -
  1.1241 -static cell_t SetPanelKeys(IPluginContext *pContext, const cell_t *params)
  1.1242 -{
  1.1243 -	Handle_t hndl = (Handle_t)params[1];
  1.1244 -	HandleError err;
  1.1245 -	IMenuPanel *panel;
  1.1246 -
  1.1247 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1248 -	{
  1.1249 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1250 -	}
  1.1251 -
  1.1252 -	return panel->SetSelectableKeys(params[2]);
  1.1253 -}
  1.1254 -
  1.1255 -static cell_t GetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
  1.1256 -{
  1.1257 -	Handle_t hndl = (Handle_t)params[1];
  1.1258 -	HandleError err;
  1.1259 -	IMenuPanel *panel;
  1.1260 -
  1.1261 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1262 -	{
  1.1263 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1264 -	}
  1.1265 -
  1.1266 -	return panel->GetCurrentKey();
  1.1267 -}
  1.1268 -
  1.1269 -static cell_t GetPanelTextRemaining(IPluginContext *pContext, const cell_t *params)
  1.1270 -{
  1.1271 -	Handle_t hndl = (Handle_t)params[1];
  1.1272 -	HandleError err;
  1.1273 -	IMenuPanel *panel;
  1.1274 -
  1.1275 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1276 -	{
  1.1277 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1278 -	}
  1.1279 -
  1.1280 -	return panel->GetAmountRemaining();
  1.1281 -}
  1.1282 -
  1.1283 -static cell_t SetPanelCurrentKey(IPluginContext *pContext, const cell_t *params)
  1.1284 -{
  1.1285 -	Handle_t hndl = (Handle_t)params[1];
  1.1286 -	HandleError err;
  1.1287 -	IMenuPanel *panel;
  1.1288 -
  1.1289 -	if ((err=ReadPanelHandle(hndl, &panel)) != HandleError_None)
  1.1290 -	{
  1.1291 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1292 -	}
  1.1293 -
  1.1294 -	return panel->SetCurrentKey(params[2]) ? 1 : 0;
  1.1295 -}
  1.1296 -
  1.1297 -static cell_t RedrawMenuItem(IPluginContext *pContext, const cell_t *params)
  1.1298 -{
  1.1299 -	if (!s_pCurPanel)
  1.1300 -	{
  1.1301 -		return pContext->ThrowNativeError("You can only call this once from a MenuAction_DisplayItem callback");
  1.1302 -	}
  1.1303 -
  1.1304 -	char *str;
  1.1305 -	pContext->LocalToString(params[1], &str);
  1.1306 -
  1.1307 -	ItemDrawInfo dr = *s_CurDrawInfo;
  1.1308 -	dr.display = str;
  1.1309 -
  1.1310 -	if ((s_CurPanelReturn = s_pCurPanel->DrawItem(dr)) != 0)
  1.1311 -	{
  1.1312 -		s_pCurPanel = NULL;
  1.1313 -	}
  1.1314 -
  1.1315 -	return s_CurPanelReturn;
  1.1316 -}
  1.1317 -
  1.1318 -static cell_t GetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
  1.1319 -{
  1.1320 -	Handle_t hndl = (Handle_t)params[1];
  1.1321 -	HandleError err;
  1.1322 -	IBaseMenu *menu;
  1.1323 -
  1.1324 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
  1.1325 -	{
  1.1326 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1327 -	}
  1.1328 -
  1.1329 -	return menu->GetMenuOptionFlags();
  1.1330 -}
  1.1331 -
  1.1332 -static cell_t SetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
  1.1333 -{
  1.1334 -	Handle_t hndl = (Handle_t)params[1];
  1.1335 -	HandleError err;
  1.1336 -	IBaseMenu *menu;
  1.1337 -
  1.1338 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
  1.1339 -	{
  1.1340 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1341 -	}
  1.1342 -
  1.1343 -	menu->SetMenuOptionFlags(params[2]);
  1.1344 -
  1.1345 -	return 1;
  1.1346 -}
  1.1347 -
  1.1348 -static cell_t CancelVote(IPluginContext *pContxt, const cell_t *params)
  1.1349 -{
  1.1350 -	if (!g_Menus.IsVoteInProgress())
  1.1351 -	{
  1.1352 -		return pContxt->ThrowNativeError("No vote is in progress");
  1.1353 -	}
  1.1354 -
  1.1355 -	g_Menus.CancelVoting();
  1.1356 -
  1.1357 -	return 1;
  1.1358 -}
  1.1359 -
  1.1360 -static cell_t SetVoteResultCallback(IPluginContext *pContext, const cell_t *params)
  1.1361 -{
  1.1362 -	Handle_t hndl = (Handle_t)params[1];
  1.1363 -	HandleError err;
  1.1364 -	IBaseMenu *menu;
  1.1365 -
  1.1366 -	if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
  1.1367 -	{
  1.1368 -		return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
  1.1369 -	}
  1.1370 -
  1.1371 -	IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
  1.1372 -	if (!pFunction)
  1.1373 -	{
  1.1374 -		return pContext->ThrowNativeError("Invalid function %x", params[2]);
  1.1375 -	}
  1.1376 -
  1.1377 -	void *array[2];
  1.1378 -	array[0] = pFunction;
  1.1379 -	array[1] = (void *)&params[2];
  1.1380 -
  1.1381 -	IMenuHandler *pHandler = menu->GetHandler();
  1.1382 -	if (!pHandler->OnSetHandlerOption("set_vote_results_handler", (const void *)array))
  1.1383 -	{
  1.1384 -		return pContext->ThrowNativeError("The given menu does not support this option");
  1.1385 -	}
  1.1386 -
  1.1387 -	return 1;
  1.1388 -}
  1.1389 -
  1.1390 -static cell_t CheckVoteDelay(IPluginContext *pContext, const cell_t *params)
  1.1391 -{
  1.1392 -	return g_Menus.GetRemainingVoteDelay();
  1.1393 -}
  1.1394 -
  1.1395 -static cell_t GetMenuSelectionPosition(IPluginContext *pContext, const cell_t *params)
  1.1396 -{
  1.1397 -	if (!s_CurSelectPosition)
  1.1398 -	{
  1.1399 -		return pContext->ThrowNativeError("Can only be called from inside a MenuAction_Select callback");
  1.1400 -	}
  1.1401 -
  1.1402 -	return *s_CurSelectPosition;
  1.1403 -}
  1.1404 -
  1.1405 -class EmptyMenuHandler : public IMenuHandler
  1.1406 -{
  1.1407 -public:
  1.1408 -} s_EmptyMenuHandler;
  1.1409 -
  1.1410 -static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
  1.1411 -{
  1.1412 -	int client = params[1];
  1.1413 -	CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
  1.1414 -
  1.1415 -	if (pPlayer == NULL)
  1.1416 -	{
  1.1417 -		return pContext->ThrowNativeError("Invalid client index %d", client);
  1.1418 -	}
  1.1419 -	else if (!pPlayer->IsInGame())
  1.1420 -	{
  1.1421 -		return pContext->ThrowNativeError("Client %d is not in game", client);
  1.1422 -	}
  1.1423 -
  1.1424 -	if (!g_RadioMenuStyle.IsSupported())
  1.1425 -	{
  1.1426 -		return pContext->ThrowNativeError("Radio menus are not supported on this mod");
  1.1427 -	}
  1.1428 -
  1.1429 -	char *str;
  1.1430 -	pContext->LocalToString(params[2], &str);
  1.1431 -
  1.1432 -	IMenuPanel *pPanel = g_RadioMenuStyle.MakeRadioDisplay(str, params[4]);
  1.1433 -
  1.1434 -	if (pPanel == NULL)
  1.1435 -	{
  1.1436 -		return 0;
  1.1437 -	}
  1.1438 -
  1.1439 -	IMenuHandler *pHandler;
  1.1440 -	CPanelHandler *pActualHandler = NULL;
  1.1441 -	if (params[5] != -1)
  1.1442 -	{
  1.1443 -		IPluginFunction *pFunction = pContext->GetFunctionById(params[5]);
  1.1444 -		if (pFunction == NULL)
  1.1445 -		{
  1.1446 -			return pContext->ThrowNativeError("Invalid function index %x", params[5]);
  1.1447 -		}
  1.1448 -		pActualHandler = g_MenuHelpers.GetPanelHandler(pFunction);
  1.1449 -	}
  1.1450 -
  1.1451 -	if (pActualHandler == NULL)
  1.1452 -	{
  1.1453 -		pHandler = &s_EmptyMenuHandler;
  1.1454 -	}
  1.1455 -	else
  1.1456 -	{
  1.1457 -		pHandler = pActualHandler;
  1.1458 -	}
  1.1459 -
  1.1460 -	bool bSuccess = pPanel->SendDisplay(client, pHandler, params[3]);
  1.1461 -
  1.1462 -	pPanel->DeleteThis();
  1.1463 -
  1.1464 -	if (!bSuccess && pActualHandler != NULL)
  1.1465 -	{
  1.1466 -		g_MenuHelpers.FreePanelHandler(pActualHandler);
  1.1467 -	}
  1.1468 -
  1.1469 -	return bSuccess ? 1 : 0;
  1.1470 -}
  1.1471 -
  1.1472 -REGISTER_NATIVES(menuNatives)
  1.1473 -{
  1.1474 -	{"AddMenuItem",				AddMenuItem},
  1.1475 -	{"CanPanelDrawFlags",		CanPanelDrawFlags},
  1.1476 -	{"CancelClientMenu",		CancelClientMenu},
  1.1477 -	{"CancelMenu",				CancelMenu},
  1.1478 -	{"CancelVote",				CancelVote},
  1.1479 -	{"CheckVoteDelay",			CheckVoteDelay},
  1.1480 -	{"CreateMenu",				CreateMenu},
  1.1481 -	{"CreateMenuEx",			CreateMenuEx},
  1.1482 -	{"CreatePanel",				CreatePanel},
  1.1483 -	{"CreatePanelFromMenu",		CreatePanelFromMenu},
  1.1484 -	{"DisplayMenu",				DisplayMenu},
  1.1485 -	{"DisplayMenuAtItem",		DisplayMenuAtItem},
  1.1486 -	{"DrawPanelItem",			DrawPanelItem},
  1.1487 -	{"DrawPanelText",			DrawPanelText},
  1.1488 -	{"GetClientMenu",			GetClientMenu},
  1.1489 -	{"GetMaxPageItems",			GetMaxPageItems},
  1.1490 -	{"GetMenuExitBackButton",	GetMenuExitBackButton},
  1.1491 -	{"GetMenuExitButton",		GetMenuExitButton},
  1.1492 -	{"GetMenuItem",				GetMenuItem},
  1.1493 -	{"GetMenuItemCount",		GetMenuItemCount},
  1.1494 -	{"GetMenuOptionFlags",		GetMenuOptionFlags},
  1.1495 -	{"GetMenuPagination",		GetMenuPagination},
  1.1496 -	{"GetMenuSelectionPosition",GetMenuSelectionPosition},
  1.1497 -	{"GetMenuStyle",			GetMenuStyle},
  1.1498 -	{"GetMenuStyleHandle",		GetMenuStyleHandle},
  1.1499 -	{"GetMenuTitle",			GetMenuTitle},
  1.1500 -	{"GetPanelTextRemaining",	GetPanelTextRemaining},
  1.1501 -	{"GetPanelCurrentKey",		GetPanelCurrentKey},
  1.1502 -	{"GetPanelStyle",			GetPanelStyle},
  1.1503 -	{"InsertMenuItem",			InsertMenuItem},
  1.1504 -	{"InternalShowMenu",		InternalShowMenu},
  1.1505 -	{"IsVoteInProgress",		IsVoteInProgress},
  1.1506 -	{"RedrawMenuItem",			RedrawMenuItem},
  1.1507 -	{"RemoveAllMenuItems",		RemoveAllMenuItems},
  1.1508 -	{"RemoveMenuItem",			RemoveMenuItem},
  1.1509 -	{"SendPanelToClient",		SendPanelToClient},
  1.1510 -	{"SetMenuExitBackButton",	SetMenuExitBackButton},
  1.1511 -	{"SetMenuExitButton",		SetMenuExitButton},
  1.1512 -	{"SetMenuOptionFlags",		SetMenuOptionFlags},
  1.1513 -	{"SetMenuPagination",		SetMenuPagination},
  1.1514 -	{"SetMenuTitle",			SetMenuTitle},
  1.1515 -	{"SetPanelCurrentKey",		SetPanelCurrentKey},
  1.1516 -	{"SetPanelTitle",			SetPanelTitle},
  1.1517 -	{"SetPanelKeys",			SetPanelKeys},
  1.1518 -	{"SetVoteResultCallback",	SetVoteResultCallback},
  1.1519 -	{"VoteMenu",				VoteMenu},
  1.1520 -	{NULL,						NULL},
  1.1521 -};