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