@@ -48,6 +48,7 @@ public Plugin myinfo =
4848
4949ConVar g_Cvar_ExcludeOld ;
5050ConVar g_Cvar_ExcludeCurrent ;
51+ ConVar g_Cvar_MaxMatches ;
5152
5253Menu g_MapMenu = null ;
5354ArrayList g_MapList = null ;
@@ -71,11 +72,12 @@ public void OnPluginStart()
7172
7273 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 );
7374 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 );
74-
75+ g_Cvar_MaxMatches = CreateConVar (" sm_nominate_maxfound" , " 0" , " Maximum number of nomination matches to add to the menu. 0 = infinite." , _ , true , 0.0 );
76+
7577 RegConsoleCmd (" sm_nominate" , Command_Nominate );
7678
7779 RegAdminCmd (" sm_nominate_addmap" , Command_Addmap , ADMFLAG_CHANGEMAP , " sm_nominate_addmap <mapname> - Forces a map to be on the next mapvote." );
78-
80+
7981 g_mapTrie = new StringMap ();
8082}
8183
@@ -178,7 +180,7 @@ public void OnClientSayCommand_Post(int client, const char[] command, const char
178180 {
179181 ReplySource old = SetCmdReplySource (SM_REPLY_TO_CHAT );
180182
181- AttemptNominate (client );
183+ OpenNominationMenu (client );
182184
183185 SetCmdReplySource (old );
184186 }
@@ -190,21 +192,110 @@ public Action Command_Nominate(int client, int args)
190192 {
191193 return Plugin_Handled ;
192194 }
195+
196+ ReplySource source = GetCmdReplySource ();
193197
194198 if (args == 0 )
195- {
196- AttemptNominate (client );
199+ {
200+ if (source == SM_REPLY_TO_CHAT )
201+ {
202+ OpenNominationMenu (client );
203+ }
204+ else
205+ {
206+ ReplyToCommand (client , " [SM] Usage: sm_nominate <mapname>" );
207+ }
208+
197209 return Plugin_Handled ;
198210 }
199211
200212 char mapname [PLATFORM_MAX_PATH ];
201213 GetCmdArg (1 , mapname , sizeof (mapname ));
202-
203- if (FindMap (mapname , mapname , sizeof (mapname )) == FindMap_NotFound )
214+
215+ ArrayList results = new ArrayList ();
216+ int matches = FindMatchingMaps (g_MapList , results , mapname );
217+
218+ char mapResult [PLATFORM_MAX_PATH ];
219+
220+ if (matches <= 0 )
221+ {
222+ ReplyToCommand (client , " %t " , " Map was not found" , mapname );
223+ }
224+ // One result
225+ else if (matches == 1 )
226+ {
227+ // Get the result and nominate it
228+ g_MapList .GetString (results .Get (0 ), mapResult , sizeof (mapResult ));
229+ AttemptNominate (client , mapResult , sizeof (mapResult ));
230+ }
231+ else if (matches > 1 )
232+ {
233+ if (source == SM_REPLY_TO_CONSOLE )
234+ {
235+ // if source is console, attempt instead of displaying menu.
236+ AttemptNominate (client , mapname , sizeof (mapname ));
237+ delete results ;
238+ return Plugin_Handled ;
239+ }
240+
241+ // Display results to the client and end
242+ Menu menu = new Menu (MenuHandler_MapSelect , MENU_ACTIONS_DEFAULT | MenuAction_DrawItem | MenuAction_DisplayItem );
243+ menu .SetTitle (" Select map" );
244+
245+ for (int i = 0 ; i < results .Length ; i ++ )
246+ {
247+ g_MapList .GetString (results .Get (i ), mapResult , sizeof (mapResult ));
248+ menu .AddItem (mapResult , mapResult );
249+ }
250+
251+ menu .Display (client , 30 );
252+ }
253+
254+ delete results ;
255+
256+ return Plugin_Handled ;
257+ }
258+
259+ int FindMatchingMaps (ArrayList mapList , ArrayList results , const char [] input )
260+ {
261+ int map_count = mapList .Length ;
262+
263+ if (! map_count )
264+ {
265+ return - 1 ;
266+ }
267+
268+ int matches = 0 ;
269+ char map [PLATFORM_MAX_PATH ];
270+
271+ int maxmatches = g_Cvar_MaxMatches .IntValue ;
272+
273+ for (int i = 0 ; i < map_count ; i ++ )
274+ {
275+ mapList .GetString (i , map , sizeof (map ));
276+ if (StrContains (map , input ) != - 1 )
277+ {
278+ results .Push (i );
279+ matches ++ ;
280+
281+ if (maxmatches > 0 && matches >= maxmatches )
282+ {
283+ break ;
284+ }
285+ }
286+ }
287+
288+ return matches ;
289+ }
290+
291+ void AttemptNominate (int client , const char [] map , int size )
292+ {
293+ char mapname [PLATFORM_MAX_PATH ];
294+ if (FindMap (map , mapname , size ) == FindMap_NotFound )
204295 {
205296 // We couldn't resolve the map entry to a filename, so...
206297 ReplyToCommand (client , " %t " , " Map was not found" , mapname );
207- return Plugin_Handled ;
298+ return ;
208299 }
209300
210301 char displayName [PLATFORM_MAX_PATH ];
@@ -214,7 +305,7 @@ public Action Command_Nominate(int client, int args)
214305 if (! g_mapTrie .GetValue (mapname , status ))
215306 {
216307 ReplyToCommand (client , " %t " , " Map was not found" , displayName );
217- return Plugin_Handled ;
308+ return ;
218309 }
219310
220311 if ((status & MAPSTATUS_DISABLED ) == MAPSTATUS_DISABLED )
@@ -234,7 +325,7 @@ public Action Command_Nominate(int client, int args)
234325 ReplyToCommand (client , " [SM] %t " , " Map Already Nominated" );
235326 }
236327
237- return Plugin_Handled ;
328+ return ;
238329 }
239330
240331 NominateResult result = NominateMap (mapname , false , client );
@@ -250,7 +341,7 @@ public Action Command_Nominate(int client, int args)
250341 ReplyToCommand (client , " [SM] %t " , " Map Already Nominated" );
251342 }
252343
253- return Plugin_Handled ;
344+ return ;
254345 }
255346
256347 /* Map was nominated! - Disable the menu item and update the trie */
@@ -259,17 +350,16 @@ public Action Command_Nominate(int client, int args)
259350
260351 char name [MAX_NAME_LENGTH ];
261352 GetClientName (client , name , sizeof (name ));
353+
262354 PrintToChatAll (" [SM] %t " , " Map Nominated" , name , displayName );
263355
264- return Plugin_Handled ;
356+ return ;
265357}
266358
267- void AttemptNominate (int client )
359+ void OpenNominationMenu (int client )
268360{
269361 g_MapMenu .SetTitle (" %T " , " Nominate Title" , client );
270362 g_MapMenu .Display (client , MENU_TIME_FOREVER );
271-
272- return ;
273363}
274364
275365void BuildMapMenu ()
@@ -278,7 +368,7 @@ void BuildMapMenu()
278368
279369 g_mapTrie .Clear ();
280370
281- g_MapMenu = new Menu (Handler_MapSelectMenu , MENU_ACTIONS_DEFAULT | MenuAction_DrawItem | MenuAction_DisplayItem );
371+ g_MapMenu = new Menu (MenuHandler_MapSelect , MENU_ACTIONS_DEFAULT | MenuAction_DrawItem | MenuAction_DisplayItem );
282372
283373 char map [PLATFORM_MAX_PATH ];
284374
@@ -333,49 +423,23 @@ void BuildMapMenu()
333423 delete excludeMaps ;
334424}
335425
336- public int Handler_MapSelectMenu (Menu menu , MenuAction action , int param1 , int param2 )
426+ public int MenuHandler_MapSelect (Menu menu , MenuAction action , int param1 , int param2 )
337427{
338428 switch (action )
339429 {
340430 case MenuAction_Select :
341431 {
342- char map [PLATFORM_MAX_PATH ], name [MAX_NAME_LENGTH ], displayName [PLATFORM_MAX_PATH ];
343- menu .GetItem (param2 , map , sizeof (map ), _ , displayName , sizeof (displayName ));
344-
345- GetClientName (param1 , name , sizeof (name ));
346-
347- NominateResult result = NominateMap (map , false , param1 );
348-
349- /* Don't need to check for InvalidMap because the menu did that already */
350- if (result == Nominate_AlreadyInVote )
351- {
352- PrintToChat (param1 , " [SM] %t " , " Map Already Nominated" );
353- return 0 ;
354- }
355- else if (result == Nominate_VoteFull )
356- {
357- PrintToChat (param1 , " [SM] %t " , " Max Nominations" );
358- return 0 ;
359- }
360-
361- g_mapTrie .SetValue (map , MAPSTATUS_DISABLED | MAPSTATUS_EXCLUDE_NOMINATED );
362-
363- if (result == Nominate_Replaced )
364- {
365- PrintToChatAll (" [SM] %t " , " Map Nomination Changed" , name , displayName );
366- return 0 ;
367- }
368-
369- PrintToChatAll (" [SM] %t " , " Map Nominated" , name , displayName );
432+ char mapname [PLATFORM_MAX_PATH ];
433+ // Get the map name and attempt to nominate it
434+ menu .GetItem (param2 , mapname , sizeof (mapname ));
435+ AttemptNominate (param1 , mapname , sizeof (mapname ));
370436 }
371-
372437 case MenuAction_DrawItem :
373438 {
374439 char map [PLATFORM_MAX_PATH ];
375440 menu .GetItem (param2 , map , sizeof (map ));
376441
377442 int status ;
378-
379443 if (! g_mapTrie .GetValue (map , status ))
380444 {
381445 LogError (" Menu selection of item not in trie. Major logic problem somewhere." );
@@ -386,50 +450,53 @@ public int Handler_MapSelectMenu(Menu menu, MenuAction action, int param1, int p
386450 {
387451 return ITEMDRAW_DISABLED ;
388452 }
389-
453+
390454 return ITEMDRAW_DEFAULT ;
391-
392455 }
393-
394456 case MenuAction_DisplayItem :
395457 {
396- char map [ PLATFORM_MAX_PATH ], displayName [PLATFORM_MAX_PATH ];
397- menu .GetItem (param2 , map , sizeof (map ), _ , displayName , sizeof ( displayName ));
398-
458+ char mapname [PLATFORM_MAX_PATH ];
459+ menu .GetItem (param2 , mapname , sizeof (mapname ));
460+
399461 int status ;
400462
401- if (! g_mapTrie .GetValue (map , status ))
463+ if (! g_mapTrie .GetValue (mapname , status ))
402464 {
403465 LogError (" Menu selection of item not in trie. Major logic problem somewhere." );
404466 return 0 ;
405467 }
406468
407- char display [PLATFORM_MAX_PATH + 64 ];
408-
409469 if ((status & MAPSTATUS_DISABLED ) == MAPSTATUS_DISABLED )
410470 {
411471 if ((status & MAPSTATUS_EXCLUDE_CURRENT ) == MAPSTATUS_EXCLUDE_CURRENT )
412472 {
413- Format (display , sizeof (display ), " %s (%T )" , displayName , " Current Map" , param1 );
414- return RedrawMenuItem (display );
473+ Format (mapname , sizeof (mapname ), " %s (%T )" , mapname , " Current Map" , param1 );
474+ return RedrawMenuItem (mapname );
415475 }
416476
417477 if ((status & MAPSTATUS_EXCLUDE_PREVIOUS ) == MAPSTATUS_EXCLUDE_PREVIOUS )
418478 {
419- Format (display , sizeof (display ), " %s (%T )" , displayName , " Recently Played" , param1 );
420- return RedrawMenuItem (display );
479+ Format (mapname , sizeof (mapname ), " %s (%T )" , mapname , " Recently Played" , param1 );
480+ return RedrawMenuItem (mapname );
421481 }
422482
423483 if ((status & MAPSTATUS_EXCLUDE_NOMINATED ) == MAPSTATUS_EXCLUDE_NOMINATED )
424484 {
425- Format (display , sizeof (display ), " %s (%T )" , displayName , " Nominated" , param1 );
426- return RedrawMenuItem (display );
485+ Format (mapname , sizeof (mapname ), " %s (%T )" , mapname , " Nominated" , param1 );
486+ return RedrawMenuItem (mapname );
427487 }
428488 }
489+ }
490+ case MenuAction_End :
491+ {
492+ // This check allows the plugin to use the same callback
493+ // for the main menu and the match menu.
494+ if (menu != g_MapMenu )
495+ {
496+ delete menu ;
497+ }
429498
430- return 0 ;
431499 }
432500 }
433-
434501 return 0 ;
435502}
0 commit comments