Skip to content

Commit 8717ffe

Browse files
authored
Implement menu_create "ml" param to allow menu title/item to be looked up as multilingual key (#593)
* Clean up menu_create() internal code No code changes. Just modernizing code a little and tidying up things. * Implement menu_create() "ml" param * Include newmenu.inc to VS project files * Adjust documentation * Put back the quote in the log error message.
1 parent b4768a3 commit 8717ffe

File tree

5 files changed

+75
-33
lines changed

5 files changed

+75
-33
lines changed

amxmodx/msvc12/amxmodx_mm.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ md -p JIT 2>NUL
457457
<None Include="..\..\plugins\include\cvars.inc" />
458458
<None Include="..\..\plugins\include\datapack.inc" />
459459
<None Include="..\..\plugins\include\gameconfig.inc" />
460+
<None Include="..\..\plugins\include\newmenus.inc" />
460461
<None Include="..\..\plugins\include\string_const.inc" />
461462
<None Include="..\..\plugins\include\string_stocks.inc" />
462463
<None Include="..\..\plugins\include\textparse_ini.inc" />

amxmodx/msvc12/amxmodx_mm.vcxproj.filters

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
</Filter>
5555
<Filter Include="ReSDK\engine">
5656
<UniqueIdentifier>{04fab577-6f56-40d0-8f69-7ce1b8bf3bb9}</UniqueIdentifier>
57-
</Filter>
57+
</Filter>
5858
<Filter Include="Third Party\UTF8Rewind">
5959
<UniqueIdentifier>{270f3524-564f-4154-bb35-242a6faac09e}</UniqueIdentifier>
6060
</Filter>
@@ -693,10 +693,13 @@
693693
<None Include="..\..\plugins\include\string_stocks.inc">
694694
<Filter>Pawn Includes</Filter>
695695
</None>
696+
<None Include="..\..\plugins\include\newmenus.inc">
697+
<Filter>Pawn Includes</Filter>
698+
</None>
696699
</ItemGroup>
697700
<ItemGroup>
698701
<Object Include="..\Jit\helpers-x86.obj">
699702
<Filter>Assembly\Builds</Filter>
700703
</Object>
701704
</ItemGroup>
702-
</Project>
705+
</Project>

amxmodx/newmenus.cpp

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "amxmodx.h"
1111
#include "CMenu.h"
1212
#include "newmenus.h"
13+
#include "format.h"
1314

1415
ke::Vector<Menu *> g_NewMenus;
1516
CStack<int> g_MenuFreeStack;
@@ -90,9 +91,9 @@ bool CloseNewMenus(CPlayer *pPlayer)
9091
return true;
9192
}
9293

93-
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
94+
Menu::Menu(const char *title, AMX *amx, int fid, bool use_ml) : m_Title(title), m_ItemColor("\\r"),
9495
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
95-
isDestroying(false), pageCallback(-1), showPageNumber(true), items_per_page(7)
96+
isDestroying(false), pageCallback(-1), showPageNumber(true), useMultilingual(use_ml), amx(amx), items_per_page(7)
9697
{
9798
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
9899
menuId = g_menucmds.registerMenuId(title, amx);
@@ -356,18 +357,32 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
356357

357358
m_Text = nullptr;
358359

360+
361+
auto title = m_Title.chars();
362+
363+
if (this->useMultilingual)
364+
{
365+
const auto language = playerlang(player);
366+
const auto definition = translate(this->amx, language, title);
367+
368+
if (definition)
369+
{
370+
title = definition;
371+
}
372+
}
373+
359374
char buffer[255];
360375
if (showPageNumber && items_per_page && (pages != 1))
361376
{
362377
if (m_AutoColors)
363-
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s %d/%d\n\\w\n", m_Title.chars(), page + 1, pages);
378+
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s %d/%d\n\\w\n", title, page + 1, pages);
364379
else
365-
ke::SafeSprintf(buffer, sizeof(buffer), "%s %d/%d\n\n", m_Title.chars(), page + 1, pages);
380+
ke::SafeSprintf(buffer, sizeof(buffer), "%s %d/%d\n\n", title, page + 1, pages);
366381
} else {
367382
if (m_AutoColors)
368-
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s\n\\w\n", m_Title.chars());
383+
ke::SafeSprintf(buffer, sizeof(buffer), "\\y%s\n\\w\n", title);
369384
else
370-
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n\n", m_Title.chars());
385+
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n\n", title);
371386
}
372387

373388
m_Text = m_Text + buffer;
@@ -462,24 +477,37 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
462477
option_display = 0;
463478
}
464479

480+
auto itemName = pItem->name.chars();
481+
482+
if (this->useMultilingual)
483+
{
484+
const auto language = playerlang(player);
485+
const auto definition = translate(this->amx, language, itemName);
486+
487+
if (definition)
488+
{
489+
itemName = definition;
490+
}
491+
}
492+
465493
if (pItem->isBlank)
466494
{
467-
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n", pItem->name.chars());
495+
ke::SafeSprintf(buffer, sizeof(buffer), "%s\n", itemName);
468496
}
469497
else if (enabled)
470498
{
471-
if (m_AutoColors)
499+
if (m_AutoColors)
472500
{
473-
ke::SafeSprintf(buffer, sizeof(buffer), "%s%d.\\w %s\n", m_ItemColor.chars(),option_display, pItem->name.chars());
501+
ke::SafeSprintf(buffer, sizeof(buffer), "%s%d.\\w %s\n", m_ItemColor.chars(),option_display, itemName);
474502
} else {
475-
ke::SafeSprintf(buffer, sizeof(buffer), "%d. %s\n", option_display, pItem->name.chars());
503+
ke::SafeSprintf(buffer, sizeof(buffer), "%d. %s\n", option_display, itemName);
476504
}
477505
} else {
478506
if (m_AutoColors)
479507
{
480-
ke::SafeSprintf(buffer, sizeof(buffer), "\\d%d. %s\n\\w", option_display, pItem->name.chars());
508+
ke::SafeSprintf(buffer, sizeof(buffer), "\\d%d. %s\n\\w", option_display, itemName);
481509
} else {
482-
ke::SafeSprintf(buffer, sizeof(buffer), "#. %s\n", pItem->name.chars());
510+
ke::SafeSprintf(buffer, sizeof(buffer), "#. %s\n", itemName);
483511
}
484512
}
485513
slots++;
@@ -620,38 +648,45 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
620648
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.length()); \
621649
return 0; }
622650

623-
//Makes a new menu handle (-1 for failure)
624-
//native csdm_makemenu(title[]);
651+
// native menu_create(const title[], const handler[], bool:ml = false);
625652
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
626653
{
627-
int len;
628-
char *title = get_amxstring(amx, params[1], 0, len);
629-
validate_menu_text(title);
630-
char *handler = get_amxstring(amx, params[2], 1, len);
654+
enum args { arg_count, arg_title, arg_handler, arg_ml };
631655

632-
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
633-
634-
if (func == -1)
656+
int length;
657+
const auto title = get_amxstring(amx, params[arg_title], 0, length);
658+
const auto handler = get_amxstring(amx, params[arg_handler], 1, length);
659+
const auto callback = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
660+
661+
if (callback == -1)
635662
{
636-
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
663+
LogError(amx, AMX_ERR_NOTFOUND, R"(Invalid function "%s")", handler);
637664
return 0;
638665
}
639666

640-
Menu *pMenu = new Menu(title, amx, func);
667+
validate_menu_text(title);
668+
669+
auto pMenu = new Menu(title, amx, callback, params[arg_ml] != 0);
641670

642671
if (g_MenuFreeStack.empty())
643672
{
644673
g_NewMenus.append(pMenu);
645-
pMenu->thisId = (int)g_NewMenus.length() - 1;
646-
} else {
647-
int pos = g_MenuFreeStack.front();
674+
675+
pMenu->thisId = static_cast<int>(g_NewMenus.length()) - 1;
676+
}
677+
else
678+
{
679+
const auto position = g_MenuFreeStack.front();
680+
648681
g_MenuFreeStack.pop();
649-
g_NewMenus[pos] = pMenu;
650-
pMenu->thisId = pos;
682+
g_NewMenus[position] = pMenu;
683+
684+
pMenu->thisId = position;
651685
}
652686

653687
return pMenu->thisId;
654688
}
689+
655690
static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
656691
{
657692
GETMENU(params[1]);

amxmodx/newmenus.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ typedef unsigned int page_t;
9595
class Menu
9696
{
9797
public:
98-
Menu(const char *title, AMX *amx, int fid);
98+
Menu(const char *title, AMX *amx, int fid, bool use_ml);
9999
~Menu();
100100

101101
menuitem *GetMenuItem(item_t item);
@@ -127,6 +127,8 @@ class Menu
127127
bool isDestroying;
128128
int pageCallback;
129129
bool showPageNumber;
130+
bool useMultilingual;
131+
AMX *amx;
130132
public:
131133
unsigned int items_per_page;
132134
};

plugins/include/newmenus.inc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,14 @@
117117
* @param title Title the menu should use.
118118
* @param handler Name of the handler function. The function will be invoked
119119
* once and only once to every menu_display() call.
120-
* @param ml Unused (should be 0).
120+
* @param ml If true, the menu title and items will be looked up as multilingual keys
121+
* when the menu displays.
121122
* @return Menu resource identifier which must be destroyed via
122123
* menu_destroy(). All menus are destroyed when the plugin
123124
* unloads.
124125
* @error Function name not found.
125126
*/
126-
native menu_create(const title[], const handler[], ml=0);
127+
native menu_create(const title[], const handler[], bool:ml = false);
127128

128129
/**
129130
* Creates a menu item callback handler.

0 commit comments

Comments
 (0)