Create menu if multiple nom matches found (#983)
This change checks the nomination against the map arraylist. If the nomination matches multiple results, those results are then added to a menu to allow the client to select available maps. The maps added to the menu go against the same checks as the normal nomination menu and wont allow nomination of disabled maps. Example image of /nominate jump_b https://i.imgur.com/ZdzB0gk.png If reply source is console, menus wont be generated and it will attempt to nominate as normal.
This commit is contained in:
parent
22635d8d35
commit
b8fd7db58d
@ -48,6 +48,7 @@ public Plugin myinfo =
|
||||
|
||||
ConVar g_Cvar_ExcludeOld;
|
||||
ConVar g_Cvar_ExcludeCurrent;
|
||||
ConVar g_Cvar_MaxMatches;
|
||||
|
||||
Menu g_MapMenu = null;
|
||||
ArrayList g_MapList = null;
|
||||
@ -71,6 +72,7 @@ public void OnPluginStart()
|
||||
|
||||
g_Cvar_ExcludeOld = CreateConVar("sm_nominate_excludeold", "1", "Specifies if the MapChooser excluded maps should also be excluded from Nominations", 0, true, 0.00, true, 1.0);
|
||||
g_Cvar_ExcludeCurrent = CreateConVar("sm_nominate_excludecurrent", "1", "Specifies if the current map should be excluded from the Nominations list", 0, true, 0.00, true, 1.0);
|
||||
g_Cvar_MaxMatches = CreateConVar("sm_nominate_maxfound", "0", "Maximum number of nomination matches to add to the menu. 0 = infinite.", _, true, 0.0);
|
||||
|
||||
RegConsoleCmd("sm_nominate", Command_Nominate);
|
||||
|
||||
@ -178,7 +180,7 @@ public void OnClientSayCommand_Post(int client, const char[] command, const char
|
||||
{
|
||||
ReplySource old = SetCmdReplySource(SM_REPLY_TO_CHAT);
|
||||
|
||||
AttemptNominate(client);
|
||||
OpenNominationMenu(client);
|
||||
|
||||
SetCmdReplySource(old);
|
||||
}
|
||||
@ -191,20 +193,109 @@ public Action Command_Nominate(int client, int args)
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
ReplySource source = GetCmdReplySource();
|
||||
|
||||
if (args == 0)
|
||||
{
|
||||
AttemptNominate(client);
|
||||
if (source == SM_REPLY_TO_CHAT)
|
||||
{
|
||||
OpenNominationMenu(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplyToCommand(client, "[SM] Usage: sm_nominate <mapname>");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
char mapname[PLATFORM_MAX_PATH];
|
||||
GetCmdArg(1, mapname, sizeof(mapname));
|
||||
|
||||
if (FindMap(mapname, mapname, sizeof(mapname)) == FindMap_NotFound)
|
||||
ArrayList results = new ArrayList();
|
||||
int matches = FindMatchingMaps(g_MapList, results, mapname);
|
||||
|
||||
char mapResult[PLATFORM_MAX_PATH];
|
||||
|
||||
if (matches <= 0)
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
}
|
||||
// One result
|
||||
else if (matches == 1)
|
||||
{
|
||||
// Get the result and nominate it
|
||||
g_MapList.GetString(results.Get(0), mapResult, sizeof(mapResult));
|
||||
AttemptNominate(client, mapResult, sizeof(mapResult));
|
||||
}
|
||||
else if (matches > 1)
|
||||
{
|
||||
if (source == SM_REPLY_TO_CONSOLE)
|
||||
{
|
||||
// if source is console, attempt instead of displaying menu.
|
||||
AttemptNominate(client, mapname, sizeof(mapname));
|
||||
delete results;
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
// Display results to the client and end
|
||||
Menu menu = new Menu(MenuHandler_MapSelect, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
menu.SetTitle("Select map");
|
||||
|
||||
for (int i = 0; i < results.Length; i++)
|
||||
{
|
||||
g_MapList.GetString(results.Get(i), mapResult, sizeof(mapResult));
|
||||
menu.AddItem(mapResult, mapResult);
|
||||
}
|
||||
|
||||
menu.Display(client, 30);
|
||||
}
|
||||
|
||||
delete results;
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
int FindMatchingMaps(ArrayList mapList, ArrayList results, const char[] input)
|
||||
{
|
||||
int map_count = mapList.Length;
|
||||
|
||||
if (!map_count)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int matches = 0;
|
||||
char map[PLATFORM_MAX_PATH];
|
||||
|
||||
int maxmatches = g_Cvar_MaxMatches.IntValue;
|
||||
|
||||
for (int i = 0; i < map_count; i++)
|
||||
{
|
||||
mapList.GetString(i, map, sizeof(map));
|
||||
if (StrContains(map, input) != -1)
|
||||
{
|
||||
results.Push(i);
|
||||
matches++;
|
||||
|
||||
if (maxmatches > 0 && matches >= maxmatches)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
void AttemptNominate(int client, const char[] map, int size)
|
||||
{
|
||||
char mapname[PLATFORM_MAX_PATH];
|
||||
if (FindMap(map, mapname, size) == FindMap_NotFound)
|
||||
{
|
||||
// We couldn't resolve the map entry to a filename, so...
|
||||
ReplyToCommand(client, "%t", "Map was not found", mapname);
|
||||
return Plugin_Handled;
|
||||
return;
|
||||
}
|
||||
|
||||
char displayName[PLATFORM_MAX_PATH];
|
||||
@ -214,7 +305,7 @@ public Action Command_Nominate(int client, int args)
|
||||
if (!g_mapTrie.GetValue(mapname, status))
|
||||
{
|
||||
ReplyToCommand(client, "%t", "Map was not found", displayName);
|
||||
return Plugin_Handled;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED)
|
||||
@ -234,7 +325,7 @@ public Action Command_Nominate(int client, int args)
|
||||
ReplyToCommand(client, "[SM] %t", "Map Already Nominated");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
return;
|
||||
}
|
||||
|
||||
NominateResult result = NominateMap(mapname, false, client);
|
||||
@ -250,7 +341,7 @@ public Action Command_Nominate(int client, int args)
|
||||
ReplyToCommand(client, "[SM] %t", "Map Already Nominated");
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Map was nominated! - Disable the menu item and update the trie */
|
||||
@ -259,17 +350,16 @@ public Action Command_Nominate(int client, int args)
|
||||
|
||||
char name[MAX_NAME_LENGTH];
|
||||
GetClientName(client, name, sizeof(name));
|
||||
|
||||
PrintToChatAll("[SM] %t", "Map Nominated", name, displayName);
|
||||
|
||||
return Plugin_Handled;
|
||||
return;
|
||||
}
|
||||
|
||||
void AttemptNominate(int client)
|
||||
void OpenNominationMenu(int client)
|
||||
{
|
||||
g_MapMenu.SetTitle("%T", "Nominate Title", client);
|
||||
g_MapMenu.Display(client, MENU_TIME_FOREVER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void BuildMapMenu()
|
||||
@ -278,7 +368,7 @@ void BuildMapMenu()
|
||||
|
||||
g_mapTrie.Clear();
|
||||
|
||||
g_MapMenu = new Menu(Handler_MapSelectMenu, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
g_MapMenu = new Menu(MenuHandler_MapSelect, MENU_ACTIONS_DEFAULT|MenuAction_DrawItem|MenuAction_DisplayItem);
|
||||
|
||||
char map[PLATFORM_MAX_PATH];
|
||||
|
||||
@ -333,49 +423,23 @@ void BuildMapMenu()
|
||||
delete excludeMaps;
|
||||
}
|
||||
|
||||
public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int param2)
|
||||
public int MenuHandler_MapSelect(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case MenuAction_Select:
|
||||
{
|
||||
char map[PLATFORM_MAX_PATH], name[MAX_NAME_LENGTH], displayName[PLATFORM_MAX_PATH];
|
||||
menu.GetItem(param2, map, sizeof(map), _, displayName, sizeof(displayName));
|
||||
|
||||
GetClientName(param1, name, sizeof(name));
|
||||
|
||||
NominateResult result = NominateMap(map, false, param1);
|
||||
|
||||
/* Don't need to check for InvalidMap because the menu did that already */
|
||||
if (result == Nominate_AlreadyInVote)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Map Already Nominated");
|
||||
return 0;
|
||||
char mapname[PLATFORM_MAX_PATH];
|
||||
// Get the map name and attempt to nominate it
|
||||
menu.GetItem(param2, mapname, sizeof(mapname));
|
||||
AttemptNominate(param1, mapname, sizeof(mapname));
|
||||
}
|
||||
else if (result == Nominate_VoteFull)
|
||||
{
|
||||
PrintToChat(param1, "[SM] %t", "Max Nominations");
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_mapTrie.SetValue(map, MAPSTATUS_DISABLED|MAPSTATUS_EXCLUDE_NOMINATED);
|
||||
|
||||
if (result == Nominate_Replaced)
|
||||
{
|
||||
PrintToChatAll("[SM] %t", "Map Nomination Changed", name, displayName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PrintToChatAll("[SM] %t", "Map Nominated", name, displayName);
|
||||
}
|
||||
|
||||
case MenuAction_DrawItem:
|
||||
{
|
||||
char map[PLATFORM_MAX_PATH];
|
||||
menu.GetItem(param2, map, sizeof(map));
|
||||
|
||||
int status;
|
||||
|
||||
if (!g_mapTrie.GetValue(map, status))
|
||||
{
|
||||
LogError("Menu selection of item not in trie. Major logic problem somewhere.");
|
||||
@ -388,48 +452,51 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
|
||||
}
|
||||
|
||||
return ITEMDRAW_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
case MenuAction_DisplayItem:
|
||||
{
|
||||
char map[PLATFORM_MAX_PATH], displayName[PLATFORM_MAX_PATH];
|
||||
menu.GetItem(param2, map, sizeof(map), _, displayName, sizeof(displayName));
|
||||
char mapname[PLATFORM_MAX_PATH];
|
||||
menu.GetItem(param2, mapname, sizeof(mapname));
|
||||
|
||||
int status;
|
||||
|
||||
if (!g_mapTrie.GetValue(map, status))
|
||||
if (!g_mapTrie.GetValue(mapname, status))
|
||||
{
|
||||
LogError("Menu selection of item not in trie. Major logic problem somewhere.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char display[PLATFORM_MAX_PATH + 64];
|
||||
|
||||
if ((status & MAPSTATUS_DISABLED) == MAPSTATUS_DISABLED)
|
||||
{
|
||||
if ((status & MAPSTATUS_EXCLUDE_CURRENT) == MAPSTATUS_EXCLUDE_CURRENT)
|
||||
{
|
||||
Format(display, sizeof(display), "%s (%T)", displayName, "Current Map", param1);
|
||||
return RedrawMenuItem(display);
|
||||
Format(mapname, sizeof(mapname), "%s (%T)", mapname, "Current Map", param1);
|
||||
return RedrawMenuItem(mapname);
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_EXCLUDE_PREVIOUS) == MAPSTATUS_EXCLUDE_PREVIOUS)
|
||||
{
|
||||
Format(display, sizeof(display), "%s (%T)", displayName, "Recently Played", param1);
|
||||
return RedrawMenuItem(display);
|
||||
Format(mapname, sizeof(mapname), "%s (%T)", mapname, "Recently Played", param1);
|
||||
return RedrawMenuItem(mapname);
|
||||
}
|
||||
|
||||
if ((status & MAPSTATUS_EXCLUDE_NOMINATED) == MAPSTATUS_EXCLUDE_NOMINATED)
|
||||
{
|
||||
Format(display, sizeof(display), "%s (%T)", displayName, "Nominated", param1);
|
||||
return RedrawMenuItem(display);
|
||||
Format(mapname, sizeof(mapname), "%s (%T)", mapname, "Nominated", param1);
|
||||
return RedrawMenuItem(mapname);
|
||||
}
|
||||
}
|
||||
}
|
||||
case MenuAction_End:
|
||||
{
|
||||
// This check allows the plugin to use the same callback
|
||||
// for the main menu and the match menu.
|
||||
if (menu != g_MapMenu)
|
||||
{
|
||||
delete menu;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
"Already Nominated"
|
||||
{
|
||||
"en" "You have already nominated a map."
|
||||
|
||||
}
|
||||
|
||||
"Max Nominations"
|
||||
@ -11,7 +10,6 @@
|
||||
"en" "The maximum allowed nominations has been reached."
|
||||
}
|
||||
|
||||
|
||||
"Map Already In Vote"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
|
Loading…
Reference in New Issue
Block a user