Xonotic
quickmenu.qc
Go to the documentation of this file.
1 #include "quickmenu.qh"
2 
3 #include <client/draw.qh>
4 #include <client/hud/_mod.qh>
5 #include <client/mapvoting.qh>
6 #include <common/ent_cs.qh>
8 
9 // QuickMenu (#23)
10 
12 {
13  // allow saving cvars that aesthetically change the panel into hud skin files
14  HUD_Write_Cvar("hud_panel_quickmenu_align");
15 }
16 
17 // QUICKMENU_MAXLINES must be <= 10
18 const int QUICKMENU_MAXLINES = 10;
19 // visible entries are loaded from QuickMenu_Buffer into QuickMenu_Page_* arrays
29 // all the entries are loaded into QuickMenu_Buffer
30 // each entry (submenu or command) is composed of 2 entries
31 const int QUICKMENU_MAXENTRIES = 256;
38 
39 // QuickMenu_Buffer are labeled with these tags
40 #define QM_TAG_TITLE "T"
41 #define QM_TAG_SUBMENU "S"
42 #define QM_TAG_COMMAND "C"
43 #define QM_TAG_PLCOMMAND "P"
44 
45 #define QuickMenu_Buffer_Set(tag, string) bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat(tag, string))
46 #define QuickMenu_Buffer_Get() bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index)
47 
49 {
51 }
52 
53 // if s1 is not empty s will be displayed as command otherwise as submenu
54 void QuickMenu_Page_LoadEntry(int i, string s, string s1)
55 {
56  TC(int, i);
57  //LOG_INFOF("^xc80 entry %d: %s, %s\n", i, s, s1);
60 }
61 
63 {
64  TC(int, i);
68 }
69 
71 {
72  return (mv_active
76 }
77 
78 // returns true if succeded, false otherwise
79 bool QuickMenu_Open(string mode, string submenu, string file)
80 {
83  return false;
84 
85  int fh = -1;
86  string s;
87 
88  if(mode == "")
89  {
90  if(file == "" || file == "0")
91  mode = "default";
92  else
93  mode = "file";
94  }
95 
96  if(mode == "file")
97  {
98  if(file == "" || file == "0")
99  LOG_INFO("No file name is set in hud_panel_quickmenu_file, loading default quickmenu");
100  else
101  {
102  fh = fopen(file, FILE_READ);
103  if(fh < 0)
104  LOG_INFOF("Couldn't open file \"%s\", loading default quickmenu", file);
105  }
106  if(fh < 0)
107  mode = "default";
108  }
109 
110  if(mode == "default")
111  {
113  if(QuickMenu_Buffer < 0)
114  return false;
115 
116  QuickMenu_Default(submenu);
117  }
118  else if(mode == "file")
119  {
121  if(QuickMenu_Buffer < 0)
122  {
123  fclose(fh);
124  return false;
125  }
126 
129  {
130  // first skip invalid entries, so we don't check them anymore
131  int argc;
132  argc = tokenize_console(s);
133  if(argc == 0 || argv(0) == "")
134  continue;
135  if(argc == 1)
137  else if(argc == 2)
138  {
139  if(argv(1) == "")
140  continue;
144  }
145  else if(argc == 3)
146  {
147  // check for special keywords
148  float teamplayers = 0, without_me = 0;
149  switch(argv(2))
150  {
151  case "ALLPLAYERS_BUT_ME": without_me = 1; // fall through
152  case "ALLPLAYERS": teamplayers = 0; break;
153  case "OWNTEAMPLAYERS_BUT_ME": without_me = 1; // fall through
154  case "OWNTEAMPLAYERS": teamplayers = 1; break;
155  case "ENEMYTEAMPLAYERS": teamplayers = 2; break;
156  default: continue;
157  }
158 
160  {
163  QuickMenu_Buffer_Set(QM_TAG_TITLE, strcat(ftos(teamplayers), ftos(without_me))); // put PLCOMMAND arguments in the title string
168  }
169  }
171  }
172  fclose(fh);
173  }
174  else
175  {
176  LOG_WARNF("Unrecognized mode %s", mode);
177  return false;
178  }
179 
180  if (QuickMenu_Buffer_Size <= 0)
181  {
182  buf_del(QuickMenu_Buffer);
183  QuickMenu_Buffer = -1;
184  return false;
185  }
186 
187  if(mode == "file")
188  QuickMenu_Page_Load(submenu, 0);
189  else
190  QuickMenu_Page_Load("", 0);
191 
192  mouseClicked = 0;
193  hudShiftState = 0;
194 
195  // we must unset the player's buttons, as they aren't released elsewhere
196  localcmd("-fire\n");
197  localcmd("-fire2\n");
198  localcmd("-use\n");
199  localcmd("-hook\n");
200  localcmd("-jump\n");
201 
203  return true;
204 }
205 
207 {
208  if (QuickMenu_Buffer >= 0)
209  {
210  buf_del(QuickMenu_Buffer);
211  QuickMenu_Buffer = -1;
213  }
214 }
215 
217 {
219  int i;
220  for (i = 0; i < QUICKMENU_MAXLINES; ++i)
223  mouseClicked = 0;
224  prevMouseClicked = 0;
226 }
227 
228 // It assumes submenu open tag is already detected
229 void QuickMenu_skip_submenu(string submenu)
230 {
231  string z_submenu = string_null; strcpy(z_submenu, submenu);
233  {
234  string s = QuickMenu_Buffer_Get();
235  if(substring(s, 0, 1) != QM_TAG_SUBMENU)
236  continue;
237  if(substring(s, 1, -1) == z_submenu) // submenu end
238  break;
240  }
241  strfree(z_submenu);
242 }
243 
245 {
246  return (QuickMenu_Page_Entries > 0);
247 }
248 
249 bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, bool without_me)
250 {
251  TC(int, teamplayers); TC(bool, without_me);
252  int i;
253  for(i = 0; i < QUICKMENU_MAXLINES; ++i)
256 
258  if(QuickMenu_Buffer < 0)
259  return false;
260 
261  HUD_Quickmenu_PlayerListEntries(cmd, teamplayers, without_me);
262 
263  if(QuickMenu_Buffer_Size <= 0)
264  {
265  buf_del(QuickMenu_Buffer);
266  QuickMenu_Buffer = -1;
267  return false;
268  }
269  return true;
270 }
271 
272 // new_page 0 means page 0, new_page != 0 means next page
274 bool QuickMenu_Page_Load(string target_submenu, bool new_page)
275 {
276  TC(bool, new_page);
277  string s = string_null, cmd = string_null, z_submenu;
278 
280  if (new_page == 0)
281  QuickMenu_Page = 0;
282  else
283  ++QuickMenu_Page;
284 
285  z_submenu = strzone(target_submenu);
286  strcpy(QuickMenu_CurrentSubMenu, z_submenu);
287 
288  QuickMenu_IsLastPage = true;
290 
292  if (z_submenu != "")
293  {
294  // skip everything until the submenu open tag is found
296  {
297  s = QuickMenu_Buffer_Get();
298  if(substring(s, 0, 1) == QM_TAG_SUBMENU && substring(s, 1, -1) == z_submenu)
299  {
300  //LOG_INFOF("^3 beginning of %s\n", z_submenu);
302  break; // target_submenu found!
303  }
304  //LOG_INFOF("^1 skipping %s\n", s);
305  }
306  if(QuickMenu_Buffer_Index == QuickMenu_Buffer_Size)
307  LOG_WARNF("Couldn't find submenu \"%s\"", z_submenu);
308  }
309 
310  // only the last page can contain up to QUICKMENU_MAXLINES entries
311  // the other ones contain only (QUICKMENU_MAXLINES - 2) entries
312  // so that the panel can show an empty row and "Continue..."
313  float first_entry = QuickMenu_Page * (QUICKMENU_MAXLINES - 2);
314  int entry_num = 0; // counts entries in target_submenu
316  {
317  s = QuickMenu_Buffer_Get();
318 
319  if(z_submenu != "" && substring(s, 1, -1) == z_submenu)
320  {
321  //LOG_INFOF("^3 end of %s\n", z_submenu);
322  break;
323  }
324 
325  if(entry_num >= first_entry)
326  {
331  {
334  QuickMenu_IsLastPage = false;
335  break;
336  }
337  }
338 
339  // NOTE: entries are loaded starting from 1, not from 0
340  if(substring(s, 0, 1) == QM_TAG_SUBMENU)
341  {
342  if(entry_num >= first_entry)
345  }
346  else if(substring(s, 0, 1) == QM_TAG_TITLE)
347  {
349  if(entry_num >= first_entry)
350  {
351  cmd = QuickMenu_Buffer_Get();
352  string command_code = substring(cmd, 0, 1);
353  if(command_code == QM_TAG_COMMAND)
354  cmd = substring(cmd, 1, -1);
355  else if(command_code == QM_TAG_PLCOMMAND)
356  {
357  // throw away the current quickmenu buffer and load a new one
358  cmd = substring(cmd, 1, -1);
359  strunzone(z_submenu);
361  return QuickMenu_Page_Load("", 0);
362  QuickMenu_Close();
363  return false;
364  }
365 
366  tokenize_console(cmd);
368 
370  }
371 
372  }
373 
374  ++entry_num;
375  }
376  strunzone(z_submenu);
377  if (QuickMenu_Page_Entries == 0)
378  {
379  QuickMenu_Close();
380  return false;
381  }
383  return true;
384 }
385 
387 {
388  TC(int, num);
390  {
391  if (num < 0 || num >= QUICKMENU_MAXLINES)
392  return false;
393  if (num == QUICKMENU_MAXLINES - 1)
394  return false;
395  if (num == 0)
396  {
398  return false;
399  }
400  } else if (num <= 0 || num > QuickMenu_Page_Entries)
401  return false;
402 
403  if (QuickMenu_Page_Command[num] != "")
404  {
406  localcmd(strcat("\n", QuickMenu_Page_Command[num], "\n"));
408  return true;
409  }
410  if (QuickMenu_Page_Description[num] != "")
412  return false;
413 }
414 
415 void QuickMenu_Page_ActiveEntry(int entry_num)
416 {
417  TC(int, entry_num);
418  QuickMenu_Page_ActivatedEntry = entry_num;
420  {
421  bool f = QuickMenu_ActionForNumber(QuickMenu_Page_ActivatedEntry);
422  // toggle commands don't close the quickmenu
423  if(QuickMenu_Page_Command_Type[QuickMenu_Page_ActivatedEntry] == 1)
425  else
427  }
428  else
430 }
431 
432 bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
433 {
434  TC(int, bInputType);
435 
437  return false;
438 
439  if(bInputType == 3)
440  {
441  mousepos.x = nPrimary;
442  mousepos.y = nSecondary;
443  return true;
444  }
445 
446  if(bInputType == 2)
447  return false;
448 
449  // at this point bInputType can only be 0 or 1 (key pressed or released)
450  bool key_pressed = (bInputType == 0);
451 
452  if(key_pressed)
453  {
454  if(nPrimary == K_ALT) hudShiftState |= S_ALT;
455  if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
456  if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
457  if(nPrimary == K_MOUSE1) mouseClicked |= S_MOUSE1;
458  if(nPrimary == K_MOUSE2) mouseClicked |= S_MOUSE2;
459  }
460  else
461  {
462  if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
463  if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
464  if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
465  if(nPrimary == K_MOUSE1) mouseClicked -= (mouseClicked & S_MOUSE1);
466  if(nPrimary == K_MOUSE2) mouseClicked -= (mouseClicked & S_MOUSE2);
467  }
468 
469  if(nPrimary == K_ESCAPE && key_pressed)
470  {
471  QuickMenu_Close();
472  }
473  else if(nPrimary >= '0' && nPrimary <= '9' && key_pressed)
474  {
476  }
477  else
478  {
479  // allow console bind to work
480  string con_keys = findkeysforcommand("toggleconsole", 0);
481  int keys = tokenize(con_keys); // findkeysforcommand returns data for this
482  int i;
483  for (i = 0; i < keys; ++i)
484  {
485  if(nPrimary == stof(argv(i)))
486  return false; // hit console bind
487  }
488  if (key_pressed)
489  QuickMenu_Close();
490  return false;
491  }
492 
493  return true;
494 }
495 
498 {
499  if(mv_active) return;
500 
501  if(!mouseClicked)
503  {
504  QuickMenu_Close();
505  return;
506  }
507 
508  panel = HUD_PANEL(QUICKMENU);
510 
511  if(panel_bg_padding)
512  {
513  panel_pos += '1 1 0' * panel_bg_padding;
514  panel_size -= '2 2 0' * panel_bg_padding;
515  }
516 
517  float first_entry_pos, entries_height;
518  vector fontsize;
519  fontsize = '1 1 0' * (panel_size.y / QUICKMENU_MAXLINES);
520  first_entry_pos = panel_pos.y + ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize.y) / 2;
521  entries_height = panel_size.y - ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize.y);
522 
523  if (mousepos.x >= panel_pos.x && mousepos.y >= first_entry_pos && mousepos.x <= panel_pos.x + panel_size.x && mousepos.y <= first_entry_pos + entries_height)
524  {
525  int entry_num = min(QuickMenu_Page_Entries - 1, floor((mousepos.y - first_entry_pos) / fontsize.y));
526  if (entry_num != entry_num_prev)
527  {
529  entry_num_prev = entry_num;
530  }
531  if (QuickMenu_IsLastPage || entry_num != QUICKMENU_MAXLINES - 2)
532  {
534  QuickMenu_Page_ActiveEntry((entry_num < QUICKMENU_MAXLINES - 1) ? entry_num + 1 : 0);
535 
537  {
538  vector entry_pos = panel_pos;
539  entry_pos.y = first_entry_pos + entry_num * fontsize.y;
540  vector color;
541  if (mouseClicked & S_MOUSE1)
542  color = '0.5 1 0.5';
543  else if (hudShiftState & S_CTRL)
544  color = '1 1 0.3';
545  else
546  color = '1 1 1';
547  drawfill(entry_pos, vec2(panel_size.x, fontsize.y), color, .2, DRAWFLAG_NORMAL);
548  }
549  }
550  }
551 }
552 
553 void HUD_Quickmenu_DrawEntry(vector pos, string desc, string option, vector fontsize)
554 {
555  string entry;
556  float offset;
557  float desc_width = panel_size.x;
558  if(option)
559  {
560  string pic = strcat(hud_skin_path, "/", option);
561  if(precache_pic(pic) == "")
562  pic = strcat("gfx/hud/default/", option);
563  vector option_size = '1 1 0' * fontsize.y * 0.8;
564  desc_width -= option_size.x;
565  drawpic(pos + vec2(desc_width, (fontsize.y - option_size.y) / 2), pic, option_size, '1 1 1', panel_fg_alpha, DRAWFLAG_ADDITIVE);
566  desc_width -= fontsize.x / 4;
567  }
568  entry = textShortenToWidth(desc, desc_width, fontsize, stringwidth_colors);
570  {
571  float real_desc_width = stringwidth_colors(entry, fontsize);
572  offset = (desc_width - real_desc_width) * min(autocvar_hud_panel_quickmenu_align, 1);
573 
574  if(option)
575  {
576  // when there's enough room align description regardless the checkbox
577  float extra_offset = (panel_size.x - desc_width) * min(autocvar_hud_panel_quickmenu_align, 1);
578  if(offset + real_desc_width + extra_offset < desc_width)
579  offset += extra_offset;
580  else
581  offset = max(0, desc_width - real_desc_width);
582  }
583  drawcolorcodedstring(pos + eX * offset, entry, fontsize, panel_fg_alpha, DRAWFLAG_ADDITIVE);
584  }
585  else
586  drawcolorcodedstring(pos, entry, fontsize, panel_fg_alpha, DRAWFLAG_ADDITIVE);
587 }
588 
590 {
592  {
594  return;
595 
597  {
598  QuickMenu_Close();
599  return;
600  }
601  }
602  else
603  {
604  if(!QuickMenu_IsOpened())
605  {
611  // although real command doesn't matter here, it must not be empty
612  // otherwise the entry is displayed like a submenu
617  QuickMenu_IsLastPage = false;
618  }
619  }
620 
622 
625 
626  if(panel_bg_padding)
627  {
628  panel_pos += '1 1 0' * panel_bg_padding;
629  panel_size -= '2 2 0' * panel_bg_padding;
630  }
631 
632  int i;
633  vector fontsize;
634  string color;
635  fontsize = '1 1 0' * (panel_size.y / QUICKMENU_MAXLINES);
636 
638  {
639  color = "^5";
640  HUD_Quickmenu_DrawEntry(panel_pos + eY * (panel_size.y - fontsize.y), sprintf("%d: %s%s", 0, color, _("Continue...")), string_null, fontsize);
641  }
642  else
643  panel_pos.y += ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize.y) / 2;
644 
645  for (i = 1; i <= QuickMenu_Page_Entries; ++i) {
646  if (QuickMenu_Page_Description[i] == "")
647  break;
648  string option = string_null;
649  if (QuickMenu_Page_Command[i] == "")
650  color = "^4";
651  else
652  {
653  color = "^3";
654  if(QuickMenu_Page_Command_Type[i] == 1) // toggle command
655  {
656  int end = strstrofs(QuickMenu_Page_Command[i], ";", 0);
657  if(end < 0)
659  else
661 
662  if(argv(1) && argv(0) == "toggle")
663  {
664  // "enable feature xxx" "toggle xxx" (or "toggle xxx 1 0")
665  // "disable feature xxx" "toggle xxx 0 1"
666  float ON_value = 1, OFF_value = 0;
667  if(argv(2))
668  ON_value = stof(argv(2));
669 
670  if(argv(3))
671  OFF_value = stof(argv(3));
672  else
673  OFF_value = !ON_value;
674 
675  float value = cvar(argv(1));
676  if(value == ON_value)
677  option = "checkbox_checked";
678  else if(value == OFF_value)
679  option = "checkbox_empty";
680  else
681  option = "checkbox_undefined";
682  }
683  }
684  }
685  HUD_Quickmenu_DrawEntry(panel_pos, sprintf("%d: %s%s", i, color, QuickMenu_Page_Description[i]), option, fontsize);
686 
688  drawfill(panel_pos, vec2(panel_size.x, fontsize.y), '0.5 1 0.5', .2, DRAWFLAG_NORMAL);
689 
690  panel_pos.y += fontsize.y;
691  }
692 
694  {
696  {
697  bool f = QuickMenu_ActionForNumber(QuickMenu_Page_ActivatedEntry);
699  QuickMenu_Close();
700  }
702  QuickMenu_Close();
703  QuickMenu_Page_ActivatedEntry = -1;
705  }
706 }
707 
708 
709 #define QUICKMENU_SMENU(submenu,eng_submenu) { \
710  if(target_submenu == eng_submenu && target_submenu_found) \
711  return; /* target_submenu entries are now loaded, exit */ \
712  if(QuickMenu_Buffer_Size < QUICKMENU_BUFFER_MAXENTRIES) \
713  QuickMenu_Buffer_Set(QM_TAG_SUBMENU, submenu); \
714  ++QuickMenu_Buffer_Size; \
715  if(target_submenu == eng_submenu && !target_submenu_found) { \
716  QuickMenu_Buffer_Size = 0; /* enable load of next entries */ \
717  target_submenu_found = true; \
718  } \
719 }
720 
721 #define QUICKMENU_ENTRY(title,command) { \
722  if(QuickMenu_Buffer_Size + 1 < QUICKMENU_BUFFER_MAXENTRIES) \
723  { \
724  QuickMenu_Buffer_Set(QM_TAG_TITLE, title); \
725  ++QuickMenu_Buffer_Size; \
726  QuickMenu_Buffer_Set(QM_TAG_COMMAND, command); \
727  } \
728  ++QuickMenu_Buffer_Size; \
729 }
730 
731 #define QUICKMENU_SMENU_PL(submenu,eng_submenu,command,teamplayers,without_me) { \
732  if(QuickMenu_Buffer_Size + 3 < QUICKMENU_BUFFER_MAXENTRIES) {\
733  QUICKMENU_SMENU(submenu,eng_submenu) \
734  QuickMenu_Buffer_Set(QM_TAG_TITLE, strcat(ftos(teamplayers), ftos(without_me))); \
735  ++QuickMenu_Buffer_Size; \
736  QuickMenu_Buffer_Set(QM_TAG_PLCOMMAND, command); \
737  ++QuickMenu_Buffer_Size; \
738  QUICKMENU_SMENU(submenu,eng_submenu) \
739  } \
740 }
741 
742 
743 
744 // useful to Translate a string inside the Command
745 #define QUICKMENU_ENTRY_TC(title,command,text,translated_text) {\
746  if(prvm_language == "en") { \
747  tc_title = title; \
748  tc_cmd = sprintf(command, text); \
749  } \
750  else if(!autocvar_hud_panel_quickmenu_translatecommands || translated_text == text) { \
751  tc_title = strcat("(en)", title); \
752  tc_cmd = sprintf(command, text); \
753  } \
754  else { \
755  tc_title = strcat("(", prvm_language, ")", title); \
756  tc_cmd = sprintf(command, translated_text); \
757  } \
758  QUICKMENU_ENTRY(tc_title, tc_cmd) \
759 }
760 
761 void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me)
762 {
763  TC(int, teamplayers); TC(bool, without_me);
764  entity pl;
765  if(teamplayers && !team_count)
766  return;
767 
768  for(pl = players.sort_next; pl; pl = pl.sort_next)
769  {
770  if(teamplayers == 1 && (pl.team != myteam || pl.team == NUM_SPECTATOR)) // only own team players
771  continue;
772  if(teamplayers == 2 && (pl.team == myteam || pl.team == NUM_SPECTATOR)) // only enemy team players
773  continue;
774  if(without_me && pl.sv_entnum == player_localnum)
775  continue;
776  QUICKMENU_ENTRY(strcat("^7", entcs_GetName(pl.sv_entnum)), sprintf(cmd, entcs_GetName(pl.sv_entnum)))
777  }
778 
779  return;
780 }
781 
782 
783 // Specifying target_submenu, this function only loads entries inside target_submenu
784 // NOTE: alternatively we could have loaded the whole default quickmenu and
785 // then called QuickMenu_Page_Load(target_submenu, 0);
786 // but this sytem is more reliable since we can always refer to target_submenu
787 // with the English title even if a translation is active
788 void QuickMenu_Default(string target_submenu)
789 {
790  bool target_submenu_found = false;
791  if(target_submenu != "")
792  QuickMenu_Buffer_Size = QUICKMENU_BUFFER_MAXENTRIES; // forbids load of next entries until target_submenu
793 
794  string tc_title;
795  string tc_cmd;
796 
797  QUICKMENU_SMENU(_("Chat"), "Chat")
798  QUICKMENU_SMENU_PL(CTX(_("QMCMD^Send public message to")), "Send public message to", "commandmode say %s:^7", 0, 1)
799  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^nice one")), "say %s", ":-) / nice one", CTX(_("QMCMD^:-) / nice one")))
800  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^good game")), "say %s", "good game", CTX(_("QMCMD^good game")))
801  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^hi / good luck")), "say %s", "hi / good luck and have fun", CTX(_("QMCMD^hi / good luck and have fun")))
802  if(prvm_language != "en")
803  QUICKMENU_ENTRY(CTX(_("QMCMD^Send in English")), "toggle hud_panel_quickmenu_translatecommands 0 1; quickmenu; wait; quickmenu default Chat")
804  QUICKMENU_SMENU(_("Chat"), "Chat")
805 
806  if(teamplay)
807  {
808  QUICKMENU_SMENU(CTX(_("QMCMD^Team chat")), "Team chat")
809  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^strength soon")), "say_team %s", "strength soon", CTX(_("QMCMD^strength soon")))
810  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^free item, icon")), "say_team %s; g_waypointsprite_team_here_p", "free item %x^7 (l:%y^7)", CTX(_("QMCMD^free item %x^7 (l:%y^7)")))
811  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^took item, icon")), "say_team %s; g_waypointsprite_team_here", "took item (l:%l^7)", CTX(_("QMCMD^took item (l:%l^7)")))
812  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^negative")), "say_team %s", "negative", CTX(_("QMCMD^negative")))
813  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^positive")), "say_team %s", "positive", CTX(_("QMCMD^positive")))
814  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^need help, icon")), "say_team %s; g_waypointsprite_team_helpme; cmd voice needhelp", "need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)", CTX(_("QMCMD^need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)")))
815  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^enemy seen, icon")), "say_team %s; g_waypointsprite_team_danger_p; cmd voice incoming", "enemy seen (l:%y^7)", CTX(_("QMCMD^enemy seen (l:%y^7)")))
816  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^flag seen, icon")), "say_team %s; g_waypointsprite_team_here_p; cmd voice seenflag", "flag seen (l:%y^7)", CTX(_("QMCMD^flag seen (l:%y^7)")))
817  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^defending, icon")), "say_team %s; g_waypointsprite_team_here", "defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)", CTX(_("QMCMD^defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)")))
818  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^roaming, icon")), "say_team %s; g_waypointsprite_team_here", "roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)", CTX(_("QMCMD^roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)")))
819  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^attacking, icon")), "say_team %s; g_waypointsprite_team_here", "attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)", CTX(_("QMCMD^attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)")))
820  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^killed flagcarrier, icon")), "say_team %s; g_waypointsprite_team_here_p", "killed flagcarrier (l:%y^7)", CTX(_("QMCMD^killed flagcarrier (l:%y^7)")))
821  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^dropped flag, icon")), "say_team %s; g_waypointsprite_team_here_d", "dropped flag (l:%d^7)", CTX(_("QMCMD^dropped flag (l:%d^7)")))
822  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^drop weapon, icon")), "say_team %s; g_waypointsprite_team_here; wait; dropweapon", "dropped gun %w^7 (l:%l^7)", CTX(_("QMCMD^dropped weapon %w^7 (l:%l^7)")))
823  QUICKMENU_ENTRY_TC(CTX(_("QMCMD^drop flag/key, icon")), "say_team %s; g_waypointsprite_team_here; wait; use", "dropped flag/key %w^7 (l:%l^7)", CTX(_("QMCMD^dropped flag/key %w^7 (l:%l^7)")))
824  QUICKMENU_SMENU(CTX(_("QMCMD^Team chat")), "Team chat")
825  }
826 
827  QUICKMENU_SMENU_PL(CTX(_("QMCMD^Send private message to")), "Send private message to", "commandmode tell \"%s^7\"", 0, 1)
828 
829  QUICKMENU_SMENU(CTX(_("QMCMD^Settings")), "Settings")
830  QUICKMENU_SMENU(CTX(_("QMCMD^View/HUD settings")), "View/HUD settings")
831  QUICKMENU_ENTRY(CTX(_("QMCMD^3rd person view")), "toggle chase_active")
832  QUICKMENU_ENTRY(CTX(_("QMCMD^Player models like mine")), "toggle cl_forceplayermodels")
833  QUICKMENU_ENTRY(CTX(_("QMCMD^Names above players")), "toggle hud_shownames")
834  QUICKMENU_ENTRY(CTX(_("QMCMD^Crosshair per weapon")), "toggle crosshair_per_weapon")
835  QUICKMENU_ENTRY(CTX(_("QMCMD^FPS")), "toggle hud_panel_engineinfo")
836  QUICKMENU_ENTRY(CTX(_("QMCMD^Net graph")), "toggle shownetgraph")
837  QUICKMENU_SMENU(CTX(_("QMCMD^View/HUD settings")), "View/HUD settings")
838 
839  QUICKMENU_SMENU(CTX(_("QMCMD^Sound settings")), "Sound settings")
840  QUICKMENU_ENTRY(CTX(_("QMCMD^Hit sound")), "toggle cl_hitsound")
841  QUICKMENU_ENTRY(CTX(_("QMCMD^Chat sound")), "toggle con_chatsound")
842  QUICKMENU_SMENU(CTX(_("QMCMD^Sound settings")), "Sound settings")
843 
844  if(spectatee_status > 0)
845  {
846  QUICKMENU_ENTRY(CTX(_("QMCMD^Change spectator camera")), "dropweapon")
847  }
848 
849  if(spectatee_status == -1)
850  {
851  QUICKMENU_SMENU(CTX(_("QMCMD^Observer camera")), "Observer camera")
852  QUICKMENU_ENTRY(CTX(_("QMCMD^Increase speed")), "weapnext")
853  QUICKMENU_ENTRY(CTX(_("QMCMD^Decrease speed")), "weapprev")
854  QUICKMENU_ENTRY(CTX(_("QMCMD^Wall collision")), "toggle cl_clippedspectating")
855  QUICKMENU_SMENU(CTX(_("QMCMD^Observer camera")), "Observer camera")
856  }
857 
858  QUICKMENU_ENTRY(CTX(_("QMCMD^Fullscreen")), "toggle vid_fullscreen; vid_restart")
859  QUICKMENU_SMENU(CTX(_("QMCMD^Settings")), "Settings")
860 
861  QUICKMENU_SMENU(CTX(_("QMCMD^Call a vote")), "Call a vote")
862  QUICKMENU_ENTRY(CTX(_("QMCMD^Restart the map")), "vcall restart")
863  QUICKMENU_ENTRY(CTX(_("QMCMD^End match")), "vcall endmatch")
864  if(STAT(TIMELIMIT) > 0)
865  {
866  QUICKMENU_ENTRY(CTX(_("QMCMD^Reduce match time")), "vcall reducematchtime")
867  QUICKMENU_ENTRY(CTX(_("QMCMD^Extend match time")), "vcall extendmatchtime")
868  }
869  if(teamplay)
870  QUICKMENU_ENTRY(CTX(_("QMCMD^Shuffle teams")), "vcall shuffleteams")
871  QUICKMENU_SMENU(CTX(_("QMCMD^Call a vote")), "Call a vote")
872 
873  if(spectatee_status != 0)
874  {
875  QUICKMENU_SMENU_PL(CTX(_("QMCMD^Spectate a player")), "Spectate a player", "spectate \"%s^7\"", 0, 1)
876  }
877 
878  if(target_submenu != "" && !target_submenu_found)
879  {
880  LOG_INFOF("Couldn't find submenu \"%s\"", target_submenu);
881  if(prvm_language != "en")
882  LOG_INFO("^3Warning: submenu title must be in English");
884  }
885 }
886 #undef QUICKMENU_SMENU
887 #undef QUICKMENU_ENTRY
888 #undef QUICKMENU_ENTRY_TC
vector color
void QuickMenu_TimeOut_Set()
Definition: quickmenu.qc:48
float K_ALT
Definition: keycodes.qc:20
bool QuickMenu_Page_Load(string target_submenu, bool new_page)
Definition: quickmenu.qc:274
float K_ESCAPE
Definition: keycodes.qc:9
float panel_fg_alpha
Definition: hud.qh:166
const int NUM_SPECTATOR
Definition: teams.qh:23
void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me)
Definition: quickmenu.qc:761
string string_null
Definition: nil.qh:9
#define QM_TAG_SUBMENU
Definition: quickmenu.qc:41
spree_inf s1 s2 s3loc s2 s1
Definition: all.inc:265
const vector eY
Definition: vector.qh:45
int prevMouseClicked
Definition: hud_config.qh:13
bool QuickMenu_Page_ActivatedEntry_Close
Definition: quickmenu.qc:26
bool HUD_MinigameMenu_IsOpened()
bool autocvar__hud_configure
Definition: hud_config.qh:3
int QuickMenu_Page_Entries
Definition: quickmenu.qc:23
int entry_num_prev
Definition: quickmenu.qc:496
bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
Definition: quickmenu.qc:432
const int S_SHIFT
Definition: hud.qh:127
int QuickMenu_Buffer_Size
Definition: quickmenu.qc:34
vector panel_size
Definition: hud.qh:160
entity() spawn
bool hud_draw_maximized
Definition: hud.qh:68
float QuickMenu_Page_ActivatedEntry_Time
Definition: quickmenu.qc:27
int QuickMenu_Buffer
Definition: quickmenu.qc:33
const float FILE_READ
Definition: csprogsdefs.qc:231
void HUD_Scale_Disable()
Definition: hud.qc:83
string textShortenToWidth(string theText, float maxWidth, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
Definition: util.qc:956
void HUD_QuickMenu_Export(int fh)
Definition: quickmenu.qc:11
#define QuickMenu_Buffer_Set(tag, string)
Definition: quickmenu.qc:45
int QuickMenu_Buffer_Index_Prev
Definition: quickmenu.qc:273
#define QUICKMENU_ENTRY(title, command)
Definition: quickmenu.qc:721
float K_SHIFT
Definition: keycodes.qc:22
#define QM_TAG_PLCOMMAND
Definition: quickmenu.qc:43
float QuickMenu_TimeOut
Definition: quickmenu.qc:37
float mv_active
Definition: mapvoting.qh:19
int QuickMenu_Page
Definition: quickmenu.qc:24
const int S_ALT
Definition: hud.qh:129
#define QuickMenu_Buffer_Get()
Definition: quickmenu.qc:46
bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, bool without_me)
Definition: quickmenu.qc:249
#define strcpy(this, s)
Definition: string.qh:49
int mouseClicked
Definition: hud_config.qh:12
#define LOG_WARNF(...)
Definition: log.qh:67
int QuickMenu_Page_ActivatedEntry
Definition: quickmenu.qc:25
const float DRAWFLAG_ADDITIVE
Definition: csprogsdefs.qc:318
#define QUICKMENU_SMENU_PL(submenu, eng_submenu, command, teamplayers, without_me)
Definition: quickmenu.qc:731
#define QUICKMENU_ENTRY_TC(title, command, text, translated_text)
Definition: quickmenu.qc:745
string hud_skin_path
Definition: hud.qh:133
#define buf_create
Definition: dpextensions.qh:63
#define HUD_Panel_DrawBg()
Definition: hud.qh:54
int QuickMenu_Buffer_Index
Definition: quickmenu.qc:35
void HUD_QuickMenu()
Definition: quickmenu.qc:589
bool QuickMenu_IsOpened()
Definition: quickmenu.qc:244
void HUD_Quickmenu_DrawEntry(vector pos, string desc, string option, vector fontsize)
Definition: quickmenu.qc:553
int hudShiftState
Definition: hud.qh:126
#define LOG_INFOF(...)
Definition: log.qh:71
#define QM_TAG_COMMAND
Definition: quickmenu.qc:42
string QuickMenu_Page_Command[QUICKMENU_MAXLINES]
Definition: quickmenu.qc:20
void QuickMenu_Buffer_Close()
Definition: quickmenu.qc:206
spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 spree_cen s1 f1 s1 strcat(_("Level %s: "), "^BG%s\3\, _("^BGPress ^F2%s^BG to enter the game"))
bool HUD_QuickMenu_Forbidden()
Definition: quickmenu.qc:70
float K_CTRL
Definition: keycodes.qc:21
float K_MOUSE2
Definition: keycodes.qc:130
#define LOG_INFO(...)
Definition: log.qh:70
const float DRAWFLAG_NORMAL
Definition: csprogsdefs.qc:317
entity panel
Definition: hud.qh:144
#define QM_TAG_TITLE
Definition: quickmenu.qc:40
#define TC(T, sym)
Definition: _all.inc:82
#define strstrofs
Definition: dpextensions.qh:42
void QuickMenu_skip_submenu(string submenu)
Definition: quickmenu.qc:229
vector panel_pos
Definition: hud.qh:159
float autocvar_hud_panel_quickmenu_align
Definition: quickmenu.qh:5
float teamplay
Definition: progsdefs.qc:31
void QuickMenu_Page_ClearEntry(int i)
Definition: quickmenu.qc:62
bool QuickMenu_IsLastPage
Definition: quickmenu.qc:28
string QuickMenu_CurrentSubMenu
Definition: quickmenu.qc:36
#define QUICKMENU_SMENU(submenu, eng_submenu)
Definition: quickmenu.qc:709
vector(float skel, float bonenum) _skel_get_boneabs_hidden
#define tokenize_console
Definition: dpextensions.qh:24
entity players
Definition: main.qh:43
float K_MOUSE1
Definition: keycodes.qc:129
float autocvar_hud_panel_quickmenu_time
Definition: quickmenu.qh:8
void QuickMenu_Close()
Definition: quickmenu.qc:216
float spectatee_status
Definition: main.qh:166
string prvm_language
Definition: i18n.qh:8
const vector eX
Definition: vector.qh:44
const int QUICKMENU_MAXLINES
Definition: quickmenu.qc:18
const int QUICKMENU_MAXENTRIES
Definition: quickmenu.qc:31
vector mousepos
Definition: hud.qh:102
float team_count
Definition: main.qh:45
#define vec2(...)
Definition: vector.qh:90
float hud_configure_prev
Definition: hud_config.qh:17
const int S_MOUSE2
Definition: hud_config.qh:10
void QuickMenu_Page_LoadEntry(int i, string s, string s1)
Definition: quickmenu.qc:54
#define strfree(this)
Definition: string.qh:56
const int S_MOUSE1
Definition: hud_config.qh:9
ERASEABLE string CTX(string s)
Definition: i18n.qh:45
bool QuickMenu_Open(string mode, string submenu, string file)
Definition: quickmenu.qc:79
string QuickMenu_Page_Description[QUICKMENU_MAXLINES]
Definition: quickmenu.qc:21
bool QuickMenu_ActionForNumber(int num)
Definition: quickmenu.qc:386
const int S_CTRL
Definition: hud.qh:128
int QuickMenu_Page_Command_Type[QUICKMENU_MAXLINES]
Definition: quickmenu.qc:22
float time
Definition: csprogsdefs.qc:16
#define HUD_Write_Cvar(cvar)
Definition: hud_config.qh:38
void QuickMenu_Mouse()
Definition: quickmenu.qc:497
#define chr2str
Definition: dpextensions.qh:48
#define HUD_PANEL(NAME)
Definition: hud.qh:51
float player_localnum
Definition: csprogsdefs.qc:20
void QuickMenu_Default(string target_submenu)
Definition: quickmenu.qc:788
void QuickMenu_Page_ActiveEntry(int entry_num)
Definition: quickmenu.qc:415
const int QUICKMENU_BUFFER_MAXENTRIES
Definition: quickmenu.qc:32
void HUD_Panel_LoadCvars()
Definition: hud.qc:216
float panel_bg_padding
Definition: hud.qh:171