mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 14:25:38 +03:00
Merge pull request #21 from Nextra/newmenus
Newmenus: Add menu timeouts (+ extra bugfix)
This commit is contained in:
commit
a828ee8fda
@ -65,20 +65,8 @@ void CPlayer::Disconnect()
|
|||||||
authorized = false;
|
authorized = false;
|
||||||
teamIdsInitialized = false;
|
teamIdsInitialized = false;
|
||||||
|
|
||||||
if (newmenu != -1)
|
if (Menu *pMenu = get_menu_by_id(newmenu))
|
||||||
{
|
pMenu->Close(index);
|
||||||
Menu *pMenu = g_NewMenus[newmenu];
|
|
||||||
if (pMenu)
|
|
||||||
{
|
|
||||||
//prevent recursion
|
|
||||||
newmenu = -1;
|
|
||||||
menu = 0;
|
|
||||||
executeForwards(pMenu->func,
|
|
||||||
static_cast<cell>(ENTINDEX(pEdict)),
|
|
||||||
static_cast<cell>(pMenu->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
||||||
for (iter=queries.begin(); iter!=end; iter++)
|
for (iter=queries.begin(); iter!=end; iter++)
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "CMenu.h"
|
#include "CMenu.h"
|
||||||
|
#include "newmenus.h"
|
||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "binlog.h"
|
#include "binlog.h"
|
||||||
@ -1292,6 +1293,10 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
|||||||
pPlayer->keys = 0;
|
pPlayer->keys = 0;
|
||||||
pPlayer->menu = 0;
|
pPlayer->menu = 0;
|
||||||
|
|
||||||
|
// Fire newmenu callback so closing it can be handled by the plugin
|
||||||
|
if (Menu *pMenu = get_menu_by_id(pPlayer->newmenu))
|
||||||
|
pMenu->Close(pPlayer->index);
|
||||||
|
|
||||||
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
|
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
|
||||||
|
|
||||||
pPlayer->keys = keys;
|
pPlayer->keys = keys;
|
||||||
@ -1303,7 +1308,6 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
|||||||
else
|
else
|
||||||
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
||||||
|
|
||||||
pPlayer->newmenu = -1;
|
|
||||||
pPlayer->page = 0;
|
pPlayer->page = 0;
|
||||||
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
|
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
|
||||||
}
|
}
|
||||||
@ -1324,6 +1328,10 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
|||||||
pPlayer->keys = 0;
|
pPlayer->keys = 0;
|
||||||
pPlayer->menu = 0;
|
pPlayer->menu = 0;
|
||||||
|
|
||||||
|
// Fire newmenu callback so closing it can be handled by the plugin
|
||||||
|
if (Menu *pMenu = get_menu_by_id(pPlayer->newmenu))
|
||||||
|
pMenu->Close(pPlayer->index);
|
||||||
|
|
||||||
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
|
UTIL_FakeClientCommand(pPlayer->pEdict, "menuselect", "10", 0);
|
||||||
|
|
||||||
pPlayer->keys = keys;
|
pPlayer->keys = keys;
|
||||||
@ -1335,7 +1343,6 @@ static cell AMX_NATIVE_CALL show_menu(AMX *amx, cell *params) /* 3 param */
|
|||||||
else
|
else
|
||||||
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
||||||
|
|
||||||
pPlayer->newmenu = -1;
|
|
||||||
pPlayer->page = 0;
|
pPlayer->page = 0;
|
||||||
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
|
UTIL_ShowMenu(pPlayer->pEdict, keys, time, sMenu, ilen);
|
||||||
}
|
}
|
||||||
@ -2947,7 +2954,11 @@ static cell AMX_NATIVE_CALL get_user_menu(AMX *amx, cell *params) /* 3 param */
|
|||||||
{
|
{
|
||||||
if (gpGlobals->time > pPlayer->menuexpire)
|
if (gpGlobals->time > pPlayer->menuexpire)
|
||||||
{
|
{
|
||||||
pPlayer->menu = 0;
|
if (Menu *pMenu = get_menu_by_id(pPlayer->newmenu))
|
||||||
|
pMenu->Close(pPlayer->index);
|
||||||
|
else
|
||||||
|
pPlayer->menu = 0;
|
||||||
|
|
||||||
*cpMenu = 0;
|
*cpMenu = 0;
|
||||||
*cpKeys = 0;
|
*cpKeys = 0;
|
||||||
|
|
||||||
|
@ -961,12 +961,21 @@ void C_ClientCommand(edict_t *pEntity)
|
|||||||
|
|
||||||
if (pPlayer->keys & bit_key)
|
if (pPlayer->keys & bit_key)
|
||||||
{
|
{
|
||||||
if ((pPlayer->menu > 0 && !pPlayer->vgui) && (gpGlobals->time > pPlayer->menuexpire))
|
if (gpGlobals->time > pPlayer->menuexpire)
|
||||||
{
|
{
|
||||||
pPlayer->menu = 0;
|
if (Menu *pMenu = get_menu_by_id(pPlayer->newmenu))
|
||||||
pPlayer->keys = 0;
|
{
|
||||||
|
pMenu->Close(pPlayer->index);
|
||||||
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
|
else if (pPlayer->menu > 0 && !pPlayer->vgui)
|
||||||
|
{
|
||||||
|
pPlayer->menu = 0;
|
||||||
|
pPlayer->keys = 0;
|
||||||
|
|
||||||
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int menuid = pPlayer->menu;
|
int menuid = pPlayer->menu;
|
||||||
@ -978,10 +987,8 @@ void C_ClientCommand(edict_t *pEntity)
|
|||||||
{
|
{
|
||||||
int menu = pPlayer->newmenu;
|
int menu = pPlayer->newmenu;
|
||||||
pPlayer->newmenu = -1;
|
pPlayer->newmenu = -1;
|
||||||
|
if (Menu *pMenu = get_menu_by_id(menu))
|
||||||
if (menu >= 0 && menu < (int)g_NewMenus.size() && g_NewMenus[menu])
|
|
||||||
{
|
{
|
||||||
Menu *pMenu = g_NewMenus[menu];
|
|
||||||
int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key+1);
|
int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key+1);
|
||||||
if (item == MENU_BACK)
|
if (item == MENU_BACK)
|
||||||
{
|
{
|
||||||
|
@ -81,6 +81,14 @@ void validate_menu_text(char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Menu *get_menu_by_id(int id)
|
||||||
|
{
|
||||||
|
if (id < 0 || size_t(id) >= g_NewMenus.size() || !g_NewMenus[id])
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return g_NewMenus[id];
|
||||||
|
}
|
||||||
|
|
||||||
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
|
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
|
||||||
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
|
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
|
||||||
isDestroying(false), items_per_page(7)
|
isDestroying(false), items_per_page(7)
|
||||||
@ -321,6 +329,26 @@ bool Menu::Display(int player, page_t page)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::Close(int player)
|
||||||
|
{
|
||||||
|
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
|
||||||
|
|
||||||
|
int status;
|
||||||
|
if (gpGlobals->time > pPlayer->menuexpire)
|
||||||
|
status = MENU_TIMEOUT;
|
||||||
|
else
|
||||||
|
status = MENU_EXIT;
|
||||||
|
|
||||||
|
pPlayer->keys = 0;
|
||||||
|
pPlayer->menu = 0;
|
||||||
|
pPlayer->newmenu = -1;
|
||||||
|
|
||||||
|
executeForwards(func,
|
||||||
|
static_cast<cell>(player),
|
||||||
|
static_cast<cell>(thisId),
|
||||||
|
static_cast<cell>(status));
|
||||||
|
}
|
||||||
|
|
||||||
const char *Menu::GetTextString(int player, page_t page, int &keys)
|
const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||||
{
|
{
|
||||||
page_t pages = GetPageCount();
|
page_t pages = GetPageCount();
|
||||||
@ -590,10 +618,10 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
|||||||
return m_Text.c_str();
|
return m_Text.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p] || g_NewMenus[p]->isDestroying) { \
|
#define GETMENU(p) Menu *pMenu = get_menu_by_id(p); \
|
||||||
|
if (pMenu == NULL || pMenu->isDestroying) { \
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
||||||
return 0; } \
|
return 0; }
|
||||||
Menu *pMenu = g_NewMenus[p];
|
|
||||||
|
|
||||||
//Makes a new menu handle (-1 for failure)
|
//Makes a new menu handle (-1 for failure)
|
||||||
//native csdm_makemenu(title[]);
|
//native csdm_makemenu(title[]);
|
||||||
@ -799,13 +827,7 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Menu *pOther = g_NewMenus[menu];
|
Menu *pOther = g_NewMenus[menu];
|
||||||
|
pOther->Close(pPlayer->index);
|
||||||
pPlayer->newmenu = -1;
|
|
||||||
pPlayer->menu = 0;
|
|
||||||
executeForwards(pOther->func,
|
|
||||||
static_cast<cell>(player),
|
|
||||||
static_cast<cell>(pOther->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
|
|
||||||
/* Infinite loop counter */
|
/* Infinite loop counter */
|
||||||
if (++loops >= 10)
|
if (++loops >= 10)
|
||||||
@ -815,8 +837,14 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will set the expire time of the menu to infinite
|
int time = -1;
|
||||||
pPlayer->menuexpire = INFINITE;
|
if (params[0] / sizeof(cell) >= 4)
|
||||||
|
time = params[4];
|
||||||
|
|
||||||
|
if (time < 0)
|
||||||
|
pPlayer->menuexpire = INFINITE;
|
||||||
|
else
|
||||||
|
pPlayer->menuexpire = gpGlobals->time + static_cast<float>(time);
|
||||||
|
|
||||||
return pMenu->Display(player, page);
|
return pMenu->Display(player, page);
|
||||||
}
|
}
|
||||||
@ -1029,10 +1057,10 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GETMENU_R(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p]) { \
|
#define GETMENU_R(p) Menu *pMenu = get_menu_by_id(p); \
|
||||||
|
if (pMenu == NULL) { \
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
||||||
return 0; } \
|
return 0; }
|
||||||
Menu *pMenu = g_NewMenus[p];
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
@ -1047,24 +1075,16 @@ static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
|
|||||||
CPlayer *player = GET_PLAYER_POINTER_I(index);
|
CPlayer *player = GET_PLAYER_POINTER_I(index);
|
||||||
if (!player->ingame)
|
if (!player->ingame)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Played %d is not in game", index);
|
LogError(amx, AMX_ERR_NATIVE, "Player %d is not in game", index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int menu = player->newmenu;
|
if (Menu *pMenu = get_menu_by_id(player->newmenu)) {
|
||||||
if (menu < 0 || menu >= (int)g_NewMenus.size() || !g_NewMenus[menu])
|
pMenu->Close(player->index);
|
||||||
return 0;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Menu *pMenu = g_NewMenus[menu];
|
return 0;
|
||||||
|
|
||||||
player->newmenu = -1;
|
|
||||||
player->menu = 0;
|
|
||||||
executeForwards(pMenu->func,
|
|
||||||
static_cast<cell>(index),
|
|
||||||
static_cast<cell>(pMenu->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
|
||||||
@ -1084,12 +1104,7 @@ static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
|
|||||||
player = GET_PLAYER_POINTER_I(i);
|
player = GET_PLAYER_POINTER_I(i);
|
||||||
if (player->newmenu == pMenu->thisId)
|
if (player->newmenu == pMenu->thisId)
|
||||||
{
|
{
|
||||||
player->newmenu = -1;
|
pMenu->Close(player->index);
|
||||||
player->menu = 0;
|
|
||||||
executeForwards(pMenu->func,
|
|
||||||
static_cast<cell>(i),
|
|
||||||
static_cast<cell>(pMenu->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_NewMenus[params[1]] = NULL;
|
g_NewMenus[params[1]] = NULL;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#ifndef _INCLUDE_NEWMENUS_H
|
#ifndef _INCLUDE_NEWMENUS_H
|
||||||
#define _INCLUDE_NEWMENUS_H
|
#define _INCLUDE_NEWMENUS_H
|
||||||
|
|
||||||
|
#define MENU_TIMEOUT -4
|
||||||
#define MENU_EXIT -3
|
#define MENU_EXIT -3
|
||||||
#define MENU_BACK -2
|
#define MENU_BACK -2
|
||||||
#define MENU_MORE -1
|
#define MENU_MORE -1
|
||||||
@ -126,6 +127,7 @@ public:
|
|||||||
|
|
||||||
const char *GetTextString(int player, page_t page, int &keys);
|
const char *GetTextString(int player, page_t page, int &keys);
|
||||||
bool Display(int player, page_t page);
|
bool Display(int player, page_t page);
|
||||||
|
void Close(int player);
|
||||||
|
|
||||||
int PagekeyToItem(page_t page, item_t key);
|
int PagekeyToItem(page_t page, item_t key);
|
||||||
int GetMenuMenuid();
|
int GetMenuMenuid();
|
||||||
@ -150,6 +152,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void ClearMenus();
|
void ClearMenus();
|
||||||
|
Menu *get_menu_by_id(int id);
|
||||||
|
|
||||||
extern CVector<Menu *> g_NewMenus;
|
extern CVector<Menu *> g_NewMenus;
|
||||||
extern AMX_NATIVE_INFO g_NewMenuNatives[];
|
extern AMX_NATIVE_INFO g_NewMenuNatives[];
|
||||||
|
@ -269,9 +269,10 @@ enum {
|
|||||||
|
|
||||||
#define INVALID_PLUGIN_ID -1
|
#define INVALID_PLUGIN_ID -1
|
||||||
|
|
||||||
#define MENU_EXIT -3
|
#define MENU_TIMEOUT -4
|
||||||
#define MENU_BACK -2
|
#define MENU_EXIT -3
|
||||||
#define MENU_MORE -1
|
#define MENU_BACK -2
|
||||||
|
#define MENU_MORE -1
|
||||||
#define ITEM_IGNORE 0
|
#define ITEM_IGNORE 0
|
||||||
#define ITEM_ENABLED 1
|
#define ITEM_ENABLED 1
|
||||||
#define ITEM_DISABLED 2
|
#define ITEM_DISABLED 2
|
||||||
|
@ -115,13 +115,21 @@ native menu_items(menu);
|
|||||||
* when the item is less than 0 (i.e. calling this from a cancelled menu will
|
* when the item is less than 0 (i.e. calling this from a cancelled menu will
|
||||||
* result in an error).
|
* result in an error).
|
||||||
*
|
*
|
||||||
|
* Starting with 1.8.3 this allows to specify a menu timeout similar to the
|
||||||
|
* show_menu native. If the menu exists on the client past the timeout *any*
|
||||||
|
* further action will send the MENU_TIMEOUT status code to the menu handler.
|
||||||
|
* That includes actions which would otherwise send MENU_EXIT, such as the
|
||||||
|
* client selecting an item or disconnecting and calling menu_cancel or
|
||||||
|
* menu_destroy on a live menu.
|
||||||
|
*
|
||||||
* @param id Client index.
|
* @param id Client index.
|
||||||
* @param menu Menu resource identifier.
|
* @param menu Menu resource identifier.
|
||||||
* @param page Page to start from (starting from 0).
|
* @param page Page to start from (starting from 0).
|
||||||
|
* @param time If >=0 menu will timeout after this many seconds
|
||||||
* @noreturn
|
* @noreturn
|
||||||
* @error Invalid menu resource or client index.
|
* @error Invalid menu resource or client index.
|
||||||
*/
|
*/
|
||||||
native menu_display(id, menu, page=0);
|
native menu_display(id, menu, page=0, time=-1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a page on a menu and a keypress on that page, returns the item id selected.
|
* Given a page on a menu and a keypress on that page, returns the item id selected.
|
||||||
|
Loading…
Reference in New Issue
Block a user