From 4135c1fa0091e44a68906deae6e788273edb552a Mon Sep 17 00:00:00 2001 From: Karol Szuster Date: Sat, 25 Feb 2017 22:49:12 +0100 Subject: [PATCH 1/4] Add "menu_additem2" & "menu_item_setdata" natives --- amxmodx/meta_api.cpp | 15 ++++-- amxmodx/newmenus.cpp | 90 ++++++++++++++++++++++++++++-------- amxmodx/newmenus.h | 6 ++- plugins/include/newmenus.inc | 35 +++++++++++++- 4 files changed, 119 insertions(+), 27 deletions(-) diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index 521a4e2e..b554f668 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -1088,14 +1088,21 @@ void C_ClientCommand(edict_t *pEntity) if (item == MENU_BACK) { pMenu->Display(pPlayer->index, pPlayer->page - 1); - } else if (item == MENU_MORE) { + } + else if (item == MENU_MORE) + { pMenu->Display(pPlayer->index, pPlayer->page + 1); - } else { - ret = executeForwards(pMenu->func, static_cast(pPlayer->index), static_cast(menu), static_cast(item)); + } + else + { + auto pItem = pMenu->GetMenuItem(static_cast(item)); + ret = executeForwards(pMenu->func, static_cast(pPlayer->index), static_cast(menu), static_cast(item), pItem ? static_cast(pItem->data) : 0); if (ret & 2) { result = MRES_SUPERCEDE; - } else if (ret & 1) { + } + else if (ret & 1) + { RETURN_META(MRES_SUPERCEDE); } } diff --git a/amxmodx/newmenus.cpp b/amxmodx/newmenus.cpp index 61400f3b..68d4e7f8 100755 --- a/amxmodx/newmenus.cpp +++ b/amxmodx/newmenus.cpp @@ -10,6 +10,7 @@ #include "amxmodx.h" #include "CMenu.h" #include "newmenus.h" +#include "CDataPack.h" ke::Vector g_NewMenus; CStack g_MenuFreeStack; @@ -119,9 +120,16 @@ isDestroying(false), items_per_page(7) Menu::~Menu() { + menuitem *pItem; + for (size_t i = 0; i < m_Items.length(); i++) { - delete m_Items[i]; + pItem = m_Items[i]; + + if (pItem->isDataDataPack && pItem->data > 0) + DataPackHandles.destroy(pItem->data); + + delete pItem; } unregisterSPForward(this->func); @@ -129,7 +137,7 @@ Menu::~Menu() m_Items.clear(); } -menuitem *Menu::AddItem(const char *name, const char *cmd, int access) +menuitem *Menu::AddItem(const char *name, const char *cmd, int access, int handler = -1) { menuitem *pItem = new menuitem; @@ -137,7 +145,7 @@ menuitem *Menu::AddItem(const char *name, const char *cmd, int access) pItem->cmd = cmd; pItem->access = access; pItem->id = m_Items.length(); - pItem->handler = -1; + pItem->handler = handler; pItem->isBlank = false; pItem->pfn = NULL; @@ -430,22 +438,26 @@ const char *Menu::GetTextString(int player, page_t page, int &keys) if (pItem->handler != -1) { - ret = executeForwards(pItem->handler, static_cast(player), static_cast(thisId), static_cast(i)); + ret = executeForwards(pItem->handler, static_cast(player), static_cast(thisId), static_cast(i), static_cast(pItem->data)); if (ret == ITEM_ENABLED) { enabled = true; - } else if (ret == ITEM_DISABLED) { + } + else if (ret == ITEM_DISABLED) + { enabled = false; } } if (pItem->pfn) { - ret = (pItem->pfn)(player, thisId, i); + ret = (pItem->pfn)(player, thisId, i, pItem->data); if (ret == ITEM_ENABLED) { enabled = true; - } else if (ret == ITEM_DISABLED) { + } + else if (ret == ITEM_DISABLED) + { enabled = false; } } @@ -629,11 +641,11 @@ const char *Menu::GetTextString(int player, page_t page, int &keys) static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params) { int len; - char *title = get_amxstring(amx, params[1], 0, len); + auto title = get_amxstring(amx, params[1], 0, len); validate_menu_text(title); - char *handler = get_amxstring(amx, params[2], 1, len); + auto handler = get_amxstring(amx, params[2], 1, len); - int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE); + auto func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); if (func == -1) { @@ -764,8 +776,6 @@ static cell AMX_NATIVE_CALL menu_addtext2(AMX *amx, cell *params) static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params) { int len; - char *name, *cmd; - int access; GETMENU(params[1]); @@ -775,14 +785,36 @@ static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params) return 0; } - name = get_amxstring(amx, params[2], 0, len); + auto name = get_amxstring(amx, params[2], 0, len); validate_menu_text(name); - cmd = get_amxstring(amx, params[3], 1, len); - access = params[4]; + auto cmd = get_amxstring(amx, params[3], 1, len); - menuitem *pItem = pMenu->AddItem(name, cmd, access); + pMenu->AddItem(name, cmd, params[4], params[5]); - pItem->handler = params[5]; + return 1; +} + +//Adds an item to the menu +//native menu_additem2(menu, const name[], any:data = 0, access = 0, callback = -1, bool:dp_data = false); +static cell AMX_NATIVE_CALL menu_additem2(AMX *amx, cell *params) +{ + int len; + + GETMENU(params[1]); + + if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10) + { + LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items."); + return 0; + } + + auto name = get_amxstring(amx, params[2], 0, len); + validate_menu_text(name); + + auto pItem = pMenu->AddItem(name, "", params[4], params[5]); + + pItem->data = params[3]; + pItem->isDataDataPack = params[6] != 0; return 1; } @@ -876,9 +908,9 @@ static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params) static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params) { int len; - char *name = get_amxstring(amx, params[1], 0, len); + auto name = get_amxstring(amx, params[1], 0, len); - int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE); + auto id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); if (id == -1) { @@ -927,6 +959,24 @@ static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params) return 1; } +static cell AMX_NATIVE_CALL menu_item_setdata(AMX *amx, cell *params) +{ + GETMENU(params[1]); + + auto pItem = pMenu->GetMenuItem(static_cast(params[2])); + + if (!pItem) + return 0; + + if (pItem->isDataDataPack && pItem->data > 0) + DataPackHandles.destroy(pItem->data); + + pItem->data = params[3]; + pItem->isDataDataPack = params[4] != 0; + + return 1; +} + static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params) { GETMENU(params[1]); @@ -1136,6 +1186,7 @@ AMX_NATIVE_INFO g_NewMenuNatives[] = { {"menu_create", menu_create}, {"menu_additem", menu_additem}, + {"menu_additem2", menu_additem2}, {"menu_addblank", menu_addblank}, {"menu_addtext", menu_addtext}, {"menu_pages", menu_pages}, @@ -1146,6 +1197,7 @@ AMX_NATIVE_INFO g_NewMenuNatives[] = {"menu_makecallback", menu_makecallback}, {"menu_item_setcall", menu_item_setcall}, {"menu_item_setcmd", menu_item_setcmd}, + {"menu_item_setdata", menu_item_setdata}, {"menu_item_setname", menu_item_setname}, {"menu_destroy", menu_destroy}, {"menu_setprop", menu_setprop}, diff --git a/amxmodx/newmenus.h b/amxmodx/newmenus.h index 1991c7ff..40c444f9 100755 --- a/amxmodx/newmenus.h +++ b/amxmodx/newmenus.h @@ -31,7 +31,7 @@ #define MPROP_PADMENU 9 #define MPROP_SET_NUMBER_COLOR 10 -typedef int (*MENUITEM_CALLBACK)(int, int, int); +typedef int (*MENUITEM_CALLBACK)(int, int, int, int); class BlankItem { @@ -79,6 +79,8 @@ struct menuitem int access; int handler; bool isBlank; + int data; + bool isDataDataPack; MENUITEM_CALLBACK pfn; size_t id; @@ -99,7 +101,7 @@ public: menuitem *GetMenuItem(item_t item); size_t GetPageCount(); size_t GetItemCount(); - menuitem *AddItem(const char *name, const char *cmd, int access); + menuitem *AddItem(const char *name, const char *cmd, int access, int handler); const char *GetTextString(int player, page_t page, int &keys); bool Display(int player, page_t page); diff --git a/plugins/include/newmenus.inc b/plugins/include/newmenus.inc index 88af28f4..dc2259b9 100644 --- a/plugins/include/newmenus.inc +++ b/plugins/include/newmenus.inc @@ -39,13 +39,14 @@ * * The handler function should be prototyped as: * - * public (id, menu, item) + * public (id, menu, item, any:data) * id - Client the menu is being acted upon. * menu - Menu resource identifier. * item - Item the client selected. If less than 0, the menu was * cancelled and the item is a status code. menu_display * should never be called immediately if the item is a status * code, for re-entrancy reasons. + * data - Item's data the client selected. * * The handler function should always return PLUGIN_HANDLED to block * any old menu handlers from potentially feeding on the menu, unless @@ -67,10 +68,11 @@ native menu_create(const title[], const handler[], ml=0); * * The handler function should be prototyped as: * - * public (id, menu, item) + * public (id, menu, item, any:data) * id - Client index being displayed to. * menu - Menu resource identifier. * item - Item being drawn. + * data - Item's data. * - ITEM_IGNORE to use the default functionality. ITEM_ENABLED to * explicitly enable or ITEM_DISABLED to explicitly disable. * @@ -93,6 +95,22 @@ native menu_makecallback(const function[]); */ native menu_additem(menu, const name[], const info[]="", paccess=0, callback=-1); +/** + * Adds an item to a menu. + * + * @param menu Menu resource identifier. + * @param name Item text to display. + * @param info Item data for internal information. + * @param paccess Access required by the player viewing the menu. + * @param callback If set to a valid ID from menu_makecallback(), the + * callback will be invoked before drawing the item. + * @param dp_data If true, item's data will be treat as DataPack and be destroyed + * along with the menu. + * @noreturn + * @error Invalid menu resource. + */ +native menu_additem2(menu, const name[], any:data = 0, access = 0, callback = -1, bool:dp_data = false); + /** * Returns the number of pages in a menu. * @@ -182,6 +200,19 @@ native menu_item_setname(menu, item, const name[]); */ native menu_item_setcmd(menu, item, const info[]); +/** + * Sets an item's data. + * + * @param menu Menu resource identifier. + * @param item Item identifier. + * @param data New item data. + * @param dp_data If true, item's data will be treat as DataPack and be destroyed + * along with the menu. + * @return 1 on success, 0 on failure. + * @error Invalid menu resource. + */ +native menu_item_setdata(menu, item, any:data = 0, bool:dp_data = false); + /** * Sets an item's callback. * From 86ca75fac1d55b204b5640427ea69bec7880752c Mon Sep 17 00:00:00 2001 From: Karol Szuster Date: Sat, 25 Feb 2017 22:59:42 +0100 Subject: [PATCH 2/4] Update "pluginmenu.sma" --- plugins/pluginmenu.sma | 117 +++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 70 deletions(-) diff --git a/plugins/pluginmenu.sma b/plugins/pluginmenu.sma index 0bf1ec78..e97c846c 100644 --- a/plugins/pluginmenu.sma +++ b/plugins/pluginmenu.sma @@ -121,8 +121,8 @@ stock DisplayPluginMenu(id,const MenuText[], const Handler[], const Command[], c new PluginName[64]; new func=get_func_id(Callback); new tally; - new PluginCmd[64]; new MenuText[64]; + new DataPack:itemData; for (new i=0, max=get_pluginsnum(); i Date: Tue, 3 Oct 2017 18:40:08 +0200 Subject: [PATCH 3/4] Fix typos in doc --- plugins/include/newmenus.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/include/newmenus.inc b/plugins/include/newmenus.inc index 2079d5ba..219bc13f 100644 --- a/plugins/include/newmenus.inc +++ b/plugins/include/newmenus.inc @@ -107,7 +107,7 @@ native menu_additem(menu, const name[], const info[]="", paccess=0, callback=-1) * @param paccess Access required by the player viewing the menu. * @param callback If set to a valid ID from menu_makecallback(), the * callback will be invoked before drawing the item. - * @param dp_data If true, item's data will be treat as DataPack and be destroyed + * @param dp_data If true, item's data will be treated as DataPack and be destroyed * along with the menu. * @noreturn * @error Invalid menu resource. @@ -209,7 +209,7 @@ native menu_item_setcmd(menu, item, const info[]); * @param menu Menu resource identifier. * @param item Item identifier. * @param data New item data. - * @param dp_data If true, item's data will be treat as DataPack and be destroyed + * @param dp_data If true, item's data will be treated as DataPack and be destroyed * along with the menu. * @return 1 on success, 0 on failure. * @error Invalid menu resource. From aa7addf9d8519b7bcf68755b599af177372235a9 Mon Sep 17 00:00:00 2001 From: Karol Szuster Date: Tue, 3 Oct 2017 18:45:40 +0200 Subject: [PATCH 4/4] Use for range loop --- amxmodx/newmenus.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/amxmodx/newmenus.cpp b/amxmodx/newmenus.cpp index 7dc6f78a..433c4c27 100755 --- a/amxmodx/newmenus.cpp +++ b/amxmodx/newmenus.cpp @@ -120,16 +120,12 @@ isDestroying(false), pageCallback(-1), items_per_page(7) Menu::~Menu() { - menuitem *pItem; - - for (size_t i = 0; i < m_Items.length(); i++) + for (auto &item : m_Items) { - pItem = m_Items[i]; + if (item->isDataDataPack && item->data > 0) + DataPackHandles.destroy(item->data); - if (pItem->isDataDataPack && pItem->data > 0) - DataPackHandles.destroy(pItem->data); - - delete pItem; + delete item; } unregisterSPForward(this->func);