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 *)¶ms[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 -};