]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/quickmenu.qc
Mark dirty csprogs pk3 with ~, * is a reserved character on some filesystems
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / quickmenu.qc
index 3a243d07e29c36726166db53326f1631d2a44b6c..6d281aa6b6a578b919efacc0d262534d61f95e99 100644 (file)
@@ -1,3 +1,9 @@
+#include "quickmenu.qh"
+
+#include <common/ent_cs.qh>
+#include "hud/all.qh"
+#include "mapvoting.qh"
+
 // QUICKMENU_MAXLINES must be <= 10
 const int QUICKMENU_MAXLINES = 10;
 // visible entries are loaded from QuickMenu_Buffer into QuickMenu_Page_* arrays
@@ -19,9 +25,20 @@ int QuickMenu_Buffer_Size;
 int QuickMenu_Buffer_Index;
 string QuickMenu_CurrentSubMenu;
 float QuickMenu_TimeOut;
+
+// QuickMenu_Buffer are labeled with these tags
+#define QM_TAG_TITLE "T"
+#define QM_TAG_SUBMENU "S"
+#define QM_TAG_COMMAND "C"
+#define QM_TAG_PLCOMMAND "P"
+
+#define QuickMenu_Buffer_Set(tag, string) bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat(tag, string))
+#define QuickMenu_Buffer_Get() bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index)
+
 // if s1 is not empty s will be displayed as command otherwise as submenu
 void QuickMenu_Page_LoadEntry(int i, string s, string s1)
 {
+    TC(int, i);
        //printf("^xc80 entry %d: %s, %s\n", i, s, s1);
        if (QuickMenu_Page_Description[i])
                strunzone(QuickMenu_Page_Description[i]);
@@ -33,6 +50,7 @@ void QuickMenu_Page_LoadEntry(int i, string s, string s1)
 
 void QuickMenu_Page_ClearEntry(int i)
 {
+    TC(int, i);
        if (QuickMenu_Page_Description[i])
                strunzone(QuickMenu_Page_Description[i]);
        QuickMenu_Page_Description[i] = string_null;
@@ -56,6 +74,20 @@ bool QuickMenu_Open(string mode, string submenu)
                        mode = "file";
        }
 
+       if(mode == "file")
+       {
+               if(autocvar_hud_panel_quickmenu_file == "" || autocvar_hud_panel_quickmenu_file == "0")
+                       LOG_INFO("No file name is set in hud_panel_quickmenu_file, loading default quickmenu\n");
+               else
+               {
+                       fh = fopen(autocvar_hud_panel_quickmenu_file, FILE_READ);
+                       if(fh < 0)
+                               LOG_INFOF("Couldn't open file \"%s\", loading default quickmenu\n", autocvar_hud_panel_quickmenu_file);
+               }
+               if(fh < 0)
+                       mode = "default";
+       }
+
        if(mode == "default")
        {
                QuickMenu_Buffer = buf_create();
@@ -66,15 +98,6 @@ bool QuickMenu_Open(string mode, string submenu)
        }
        else if(mode == "file")
        {
-               if(autocvar_hud_panel_quickmenu_file != "")
-               if(autocvar_hud_panel_quickmenu_file != "0")
-                       fh = fopen(autocvar_hud_panel_quickmenu_file, FILE_READ);
-               if(fh < 0)
-               {
-                       printf("Couldn't open file \"%s\"\n", autocvar_hud_panel_quickmenu_file);
-                       return false;
-               }
-
                QuickMenu_Buffer = buf_create();
                if(QuickMenu_Buffer < 0)
                {
@@ -88,17 +111,17 @@ bool QuickMenu_Open(string mode, string submenu)
                        // first skip invalid entries, so we don't check them anymore
                        float argc;
                        argc = tokenize_console(s);
-                       if(argc == 0 || argv(0) == "" || substring(argv(0), 0, 2) == "////")
+                       if(argc == 0 || argv(0) == "")
                                continue;
                        if(argc == 1)
-                               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("S", argv(0))); // Submenu
+                               QuickMenu_Buffer_Set(QM_TAG_SUBMENU, argv(0));
                        else if(argc == 2)
                        {
                                if(argv(1) == "")
                                        continue;
-                               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("T", argv(0))); // command Title
+                               QuickMenu_Buffer_Set(QM_TAG_TITLE, argv(0));
                                ++QuickMenu_Buffer_Size;
-                               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("C", argv(1))); // command
+                               QuickMenu_Buffer_Set(QM_TAG_COMMAND, argv(1));
                        }
                        else if(argc == 3)
                        {
@@ -106,9 +129,9 @@ bool QuickMenu_Open(string mode, string submenu)
                                float teamplayers = 0, without_me = 0;
                                switch(argv(2))
                                {
-                                       case "ALLPLAYERS_BUT_ME":               without_me = 1;
+                                       case "ALLPLAYERS_BUT_ME":               without_me = 1; // fall through
                                        case "ALLPLAYERS":                              teamplayers = 0; break;
-                                       case "OWNTEAMPLAYERS_BUT_ME":   without_me = 1;
+                                       case "OWNTEAMPLAYERS_BUT_ME":   without_me = 1; // fall through
                                        case "OWNTEAMPLAYERS":                  teamplayers = 1; break;
                                        case "ENEMYTEAMPLAYERS":                teamplayers = 2; break;
                                        default: continue;
@@ -116,13 +139,13 @@ bool QuickMenu_Open(string mode, string submenu)
 
                                if(QuickMenu_Buffer_Size + 3 < QUICKMENU_BUFFER_MAXENTRIES)
                                {
-                                       bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("S", argv(0))); // Submenu
+                                       QuickMenu_Buffer_Set(QM_TAG_SUBMENU, argv(0));
                                        ++QuickMenu_Buffer_Size;
-                                       bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("T", ftos(teamplayers), ftos(without_me))); // command arguments
+                                       QuickMenu_Buffer_Set(QM_TAG_TITLE, strcat(ftos(teamplayers), ftos(without_me))); // put PLCOMMAND arguments in the title string
                                        ++QuickMenu_Buffer_Size;
-                                       bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("P", argv(1))); // command for each player
+                                       QuickMenu_Buffer_Set(QM_TAG_PLCOMMAND, argv(1));
                                        ++QuickMenu_Buffer_Size;
-                                       bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("S", argv(0))); // Submenu
+                                       QuickMenu_Buffer_Set(QM_TAG_SUBMENU, argv(0));
                                }
                        }
                        ++QuickMenu_Buffer_Size;
@@ -131,7 +154,7 @@ bool QuickMenu_Open(string mode, string submenu)
        }
        else
        {
-               printf("Unrecognized mode %s\n", mode);
+               LOG_WARNINGF("Unrecognized mode %s\n", mode);
                return false;
        }
 
@@ -152,7 +175,7 @@ bool QuickMenu_Open(string mode, string submenu)
                setcursormode(1);
        hudShiftState = 0;
 
-       QuickMenu_TimeOut = time + autocvar_hud_panel_quickmenu_time;
+       QuickMenu_TimeOut = ((autocvar_hud_panel_quickmenu_time > 0) ? time + autocvar_hud_panel_quickmenu_time : 0);
        return true;
 }
 
@@ -192,8 +215,8 @@ void QuickMenu_skip_submenu(string submenu)
        z_submenu = strzone(submenu);
        for(++QuickMenu_Buffer_Index ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index)
        {
-               s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index);
-               if(substring(s, 0, 1) != "S")
+               s = QuickMenu_Buffer_Get();
+               if(substring(s, 0, 1) != QM_TAG_SUBMENU)
                        continue;
                if(substring(s, 1, -1) == z_submenu) // submenu end
                        break;
@@ -207,9 +230,10 @@ bool QuickMenu_IsOpened()
        return (QuickMenu_Page_Entries > 0);
 }
 
-void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, float without_me);
-bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, float without_me)
+void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me);
+bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, bool without_me)
 {
+    TC(int, teamplayers); TC(bool, without_me);
        int i;
        for(i = 0; i < QUICKMENU_MAXLINES; ++i)
                QuickMenu_Page_ClearEntry(i);
@@ -232,8 +256,9 @@ bool HUD_Quickmenu_PlayerListEntries_Create(string cmd, int teamplayers, float w
 
 // new_page 0 means page 0, new_page != 0 means next page
 int QuickMenu_Buffer_Index_Prev;
-bool QuickMenu_Page_Load(string target_submenu, int new_page)
+bool QuickMenu_Page_Load(string target_submenu, bool new_page)
 {
+    TC(bool, new_page);
        string s = string_null, cmd = string_null, z_submenu;
 
        if (new_page == 0)
@@ -255,8 +280,8 @@ bool QuickMenu_Page_Load(string target_submenu, int new_page)
                // skip everything until the submenu open tag is found
                for( ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index)
                {
-                       s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index);
-                       if(substring(s, 0, 1) == "S" && substring(s, 1, -1) == z_submenu)
+                       s = QuickMenu_Buffer_Get();
+                       if(substring(s, 0, 1) == QM_TAG_SUBMENU && substring(s, 1, -1) == z_submenu)
                        {
                                // printf("^3 beginning of %s\n", z_submenu);
                                ++QuickMenu_Buffer_Index;
@@ -265,7 +290,7 @@ bool QuickMenu_Page_Load(string target_submenu, int new_page)
                        // printf("^1 skipping %s\n", s);
                }
                if(QuickMenu_Buffer_Index == QuickMenu_Buffer_Size)
-                       printf("Couldn't find submenu \"%s\"\n", z_submenu);
+                       LOG_WARNINGF("Couldn't find submenu \"%s\"\n", z_submenu);
        }
 
        // only the last page can contain up to QUICKMENU_MAXLINES entries
@@ -275,7 +300,7 @@ bool QuickMenu_Page_Load(string target_submenu, int new_page)
        int entry_num = 0; // counts entries in target_submenu
        for( ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index)
        {
-               s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index);
+               s = QuickMenu_Buffer_Get();
 
                if(z_submenu != "" && substring(s, 1, -1) == z_submenu)
                {
@@ -298,20 +323,20 @@ bool QuickMenu_Page_Load(string target_submenu, int new_page)
                }
 
                // NOTE: entries are loaded starting from 1, not from 0
-               if(substring(s, 0, 1) == "S") // submenu
+               if(substring(s, 0, 1) == QM_TAG_SUBMENU)
                {
                        if(entry_num >= first_entry)
                                QuickMenu_Page_LoadEntry(QuickMenu_Page_Entries, substring(s, 1, -1), "");
                        QuickMenu_skip_submenu(substring(s, 1, -1));
                }
-               else if(entry_num >= first_entry && substring(s, 0, 1) == "T")
+               else if(entry_num >= first_entry && substring(s, 0, 1) == QM_TAG_TITLE)
                {
                        ++QuickMenu_Buffer_Index;
-                       cmd = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index);
+                       cmd = QuickMenu_Buffer_Get();
                        string command_code = substring(cmd, 0, 1);
-                       if(command_code == "C")
+                       if(command_code == QM_TAG_COMMAND)
                                cmd = substring(cmd, 1, -1);
-                       else if(command_code == "P")
+                       else if(command_code == QM_TAG_PLCOMMAND)
                        {
                                // throw away the current quickmenu buffer and load a new one
                                cmd = substring(cmd, 1, -1);
@@ -336,12 +361,13 @@ bool QuickMenu_Page_Load(string target_submenu, int new_page)
                QuickMenu_Close();
                return false;
        }
-       QuickMenu_TimeOut = time + autocvar_hud_panel_quickmenu_time;
+       QuickMenu_TimeOut = ((autocvar_hud_panel_quickmenu_time > 0) ? time + autocvar_hud_panel_quickmenu_time : 0);
        return true;
 }
 
 bool QuickMenu_ActionForNumber(int num)
 {
+    TC(int, num);
        if (!QuickMenu_IsLastPage)
        {
                if (num < 0 || num >= QUICKMENU_MAXLINES)
@@ -359,7 +385,7 @@ bool QuickMenu_ActionForNumber(int num)
        if (QuickMenu_Page_Command[num] != "")
        {
                localcmd(strcat("\n", QuickMenu_Page_Command[num], "\n"));
-               QuickMenu_TimeOut = time + autocvar_hud_panel_quickmenu_time;
+               QuickMenu_TimeOut = ((autocvar_hud_panel_quickmenu_time > 0) ? time + autocvar_hud_panel_quickmenu_time : 0);
                return true;
        }
        if (QuickMenu_Page_Description[num] != "")
@@ -367,8 +393,9 @@ bool QuickMenu_ActionForNumber(int num)
        return false;
 }
 
-void QuickMenu_Page_ActiveEntry(float entry_num)
+void QuickMenu_Page_ActiveEntry(int entry_num)
 {
+    TC(int, entry_num);
        QuickMenu_Page_ActivatedEntry = entry_num;
        QuickMenu_Page_ActivatedEntry_Time = time + 0.1;
        if(QuickMenu_Page_Command[QuickMenu_Page_ActivatedEntry])
@@ -384,8 +411,9 @@ void QuickMenu_Page_ActiveEntry(float entry_num)
                QuickMenu_Page_ActivatedEntry_Close = (!(hudShiftState & S_CTRL));
 }
 
-bool QuickMenu_InputEvent(float bInputType, float nPrimary, float nSecondary)
+bool QuickMenu_InputEvent(int bInputType, float nPrimary, float nSecondary)
 {
+    TC(int, bInputType);
        // we only care for keyboard events
        if(bInputType == 2)
                return false;
@@ -395,8 +423,8 @@ bool QuickMenu_InputEvent(float bInputType, float nPrimary, float nSecondary)
 
        if(bInputType == 3)
        {
-               mousepos_x = nPrimary;
-               mousepos_y = nSecondary;
+               mousepos.x = nPrimary;
+               mousepos.y = nSecondary;
                return true;
        }
 
@@ -472,8 +500,8 @@ void QuickMenu_Mouse()
        {
                mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
 
-               mousepos_x = bound(0, mousepos_x, vid_conwidth);
-               mousepos_y = bound(0, mousepos_y, vid_conheight);
+               mousepos.x = bound(0, mousepos.x, vid_conwidth);
+               mousepos.y = bound(0, mousepos.y, vid_conheight);
        }
 
        HUD_Panel_UpdateCvars();
@@ -486,17 +514,17 @@ void QuickMenu_Mouse()
 
        float first_entry_pos, entries_height;
        vector fontsize;
-       fontsize = '1 1 0' * (panel_size_y / QUICKMENU_MAXLINES);
-       first_entry_pos = panel_pos_y + ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize_y) / 2;
-       entries_height = panel_size_y - ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize_y);
+       fontsize = '1 1 0' * (panel_size.y / QUICKMENU_MAXLINES);
+       first_entry_pos = panel_pos.y + ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize.y) / 2;
+       entries_height = panel_size.y - ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize.y);
 
-       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)
+       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)
        {
                float entry_num;
-               entry_num = floor((mousepos_y - first_entry_pos) / fontsize_y);
+               entry_num = floor((mousepos.y - first_entry_pos) / fontsize.y);
                if (QuickMenu_IsLastPage || entry_num != QUICKMENU_MAXLINES - 2)
                {
-                       panel_pos_y = first_entry_pos + entry_num * fontsize_y;
+                       panel_pos.y = first_entry_pos + entry_num * fontsize.y;
                        vector color;
                        if(mouseClicked & S_MOUSE1)
                                color = '0.5 1 0.5';
@@ -504,15 +532,14 @@ void QuickMenu_Mouse()
                                color = '1 1 0.3';
                        else
                                color = '1 1 1';
-                       drawfill(panel_pos, eX * panel_size_x + eY * fontsize_y, color, .2, DRAWFLAG_NORMAL);
+                       drawfill(panel_pos, eX * panel_size.x + eY * fontsize.y, color, .2, DRAWFLAG_NORMAL);
 
                        if(!mouseClicked && (prevMouseClicked & S_MOUSE1))
                                QuickMenu_Page_ActiveEntry((entry_num < QUICKMENU_MAXLINES - 1) ? entry_num + 1 : 0);
                }
        }
 
-       vector cursorsize = '32 32 0';
-       drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', 0.8, DRAWFLAG_NORMAL);
+       draw_cursor_normal(mousepos, '1 1 1', 0.8);
 
        prevMouseClicked = mouseClicked;
 }
@@ -521,24 +548,39 @@ void HUD_Quickmenu_DrawEntry(vector pos, string desc, string option, vector font
 {
        string entry;
        float offset;
-       float desc_size = panel_size_x;
+       float desc_width = panel_size.x;
        if(option)
        {
-               float option_size = stringwidth_nocolors(option, fontsize);
-               desc_size -= option_size;
-               drawstring(pos + eX * desc_size, option, fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_ADDITIVE);
+               string pic = strcat(hud_skin_path, "/", option);
+               if(precache_pic(pic) == "")
+                       pic = strcat("gfx/hud/default/", option);
+               vector option_size = '1 1 0' * fontsize.y * 0.8;
+               desc_width -= option_size.x;
+               drawpic(pos + eX * desc_width + eY * (fontsize.y - option_size.y) / 2, pic, option_size, '1 1 1', panel_fg_alpha, DRAWFLAG_ADDITIVE);
+               desc_width -= fontsize.x / 4;
        }
-       entry = textShortenToWidth(desc, desc_size, fontsize, stringwidth_colors);
+       entry = textShortenToWidth(desc, desc_width, fontsize, stringwidth_colors);
        if (autocvar_hud_panel_quickmenu_align > 0)
        {
-               offset = (desc_size - stringwidth_colors(entry, fontsize)) * min(autocvar_hud_panel_quickmenu_align, 1);
+               float real_desc_width = stringwidth_colors(entry, fontsize);
+               offset = (desc_width - real_desc_width) * min(autocvar_hud_panel_quickmenu_align, 1);
+
+               if(option)
+               {
+                       // when there's enough room align description regardless the checkbox
+                       float extra_offset = (panel_size.x - desc_width) * min(autocvar_hud_panel_quickmenu_align, 1);
+                       if(offset + real_desc_width + extra_offset < desc_width)
+                               offset += extra_offset;
+                       else
+                               offset = max(0, desc_width - real_desc_width);
+               }
                drawcolorcodedstring(pos + eX * offset, entry, fontsize, panel_fg_alpha, DRAWFLAG_ADDITIVE);
        }
        else
                drawcolorcodedstring(pos, entry, fontsize, panel_fg_alpha, DRAWFLAG_ADDITIVE);
 }
 
-void HUD_QuickMenu(void)
+void HUD_QuickMenu()
 {
        if(!autocvar__hud_configure)
        {
@@ -550,6 +592,7 @@ void HUD_QuickMenu(void)
                //if(!autocvar_hud_panel_quickmenu) return;
                if(!hud_panel_quickmenu) return;
 
+               if(QuickMenu_TimeOut)
                if(time > QuickMenu_TimeOut)
                {
                        QuickMenu_Close();
@@ -588,15 +631,15 @@ void HUD_QuickMenu(void)
        int i;
        vector fontsize;
        string color;
-       fontsize = '1 1 0' * (panel_size_y / QUICKMENU_MAXLINES);
+       fontsize = '1 1 0' * (panel_size.y / QUICKMENU_MAXLINES);
 
        if (!QuickMenu_IsLastPage)
        {
                color = "^5";
-               HUD_Quickmenu_DrawEntry(panel_pos + eY * (panel_size_y - fontsize_y), sprintf("%d: %s%s", 0, color, _("Continue...")), string_null, fontsize);
+               HUD_Quickmenu_DrawEntry(panel_pos + eY * (panel_size.y - fontsize.y), sprintf("%d: %s%s", 0, color, _("Continue...")), string_null, fontsize);
        }
        else
-               panel_pos_y += ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize_y) / 2;
+               panel_pos.y += ((QUICKMENU_MAXLINES - QuickMenu_Page_Entries) * fontsize.y) / 2;
 
        for (i = 1; i <= QuickMenu_Page_Entries; ++i) {
                if (QuickMenu_Page_Description[i] == "")
@@ -630,11 +673,11 @@ void HUD_QuickMenu(void)
 
                                        float value = cvar(argv(1));
                                        if(value == ON_value)
-                                               option = "[X]";
+                                               option = "checkbox_checked";
                                        else if(value == OFF_value)
-                                               option = "[_]";
+                                               option = "checkbox_empty";
                                        else
-                                               option = "[?]";
+                                               option = "checkbox_undefined";
                                }
                        }
                }
@@ -642,9 +685,9 @@ void HUD_QuickMenu(void)
 
                if(QuickMenu_Page_ActivatedEntry_Time && time < QuickMenu_Page_ActivatedEntry_Time
                        && QuickMenu_Page_ActivatedEntry == i)
-                       drawfill(panel_pos, eX * panel_size_x + eY * fontsize_y, '0.5 1 0.5', .2, DRAWFLAG_NORMAL);
+                       drawfill(panel_pos, eX * panel_size.x + eY * fontsize.y, '0.5 1 0.5', .2, DRAWFLAG_NORMAL);
 
-               panel_pos_y += fontsize_y;
+               panel_pos.y += fontsize.y;
        }
 
        if(QuickMenu_Page_ActivatedEntry >= 0 && time >= QuickMenu_Page_ActivatedEntry_Time)
@@ -667,7 +710,7 @@ void HUD_QuickMenu(void)
        if(target_submenu == eng_submenu && target_submenu_found) \
                return; /* target_submenu entries are now loaded, exit */ \
        if(QuickMenu_Buffer_Size < QUICKMENU_BUFFER_MAXENTRIES) \
-               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("S", submenu)); \
+               QuickMenu_Buffer_Set(QM_TAG_SUBMENU, submenu); \
        ++QuickMenu_Buffer_Size; \
        if(target_submenu == eng_submenu && !target_submenu_found) { \
                QuickMenu_Buffer_Size = 0; /* enable load of next entries */ \
@@ -678,9 +721,9 @@ void HUD_QuickMenu(void)
 #define QUICKMENU_ENTRY(title,command) { \
        if(QuickMenu_Buffer_Size + 1 < QUICKMENU_BUFFER_MAXENTRIES) \
        { \
-               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("T", title)); \
+               QuickMenu_Buffer_Set(QM_TAG_TITLE, title); \
                ++QuickMenu_Buffer_Size; \
-               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("C", command)); \
+               QuickMenu_Buffer_Set(QM_TAG_COMMAND, command); \
        } \
        ++QuickMenu_Buffer_Size; \
 }
@@ -688,9 +731,9 @@ void HUD_QuickMenu(void)
 #define QUICKMENU_SMENU_PL(submenu,eng_submenu,command,teamplayers,without_me) { \
        if(QuickMenu_Buffer_Size + 3 < QUICKMENU_BUFFER_MAXENTRIES) {\
                QUICKMENU_SMENU(submenu,eng_submenu) \
-               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("T", ftos(teamplayers), ftos(without_me))); \
+               QuickMenu_Buffer_Set(QM_TAG_TITLE, strcat(ftos(teamplayers), ftos(without_me))); \
                ++QuickMenu_Buffer_Size; \
-               bufstr_set(QuickMenu_Buffer, QuickMenu_Buffer_Size, strcat("P", command)); \
+               QuickMenu_Buffer_Set(QM_TAG_PLCOMMAND, command); \
                ++QuickMenu_Buffer_Size; \
                QUICKMENU_SMENU(submenu,eng_submenu) \
        } \
@@ -708,8 +751,9 @@ void HUD_QuickMenu(void)
                QUICKMENU_ENTRY(strcat("(", prvm_language, ")", title), sprintf(command, translated_text)) \
 }
 
-void HUD_Quickmenu_PlayerListEntries(string cmd, float teamplayers, float without_me)
+void HUD_Quickmenu_PlayerListEntries(string cmd, int teamplayers, bool without_me)
 {
+    TC(int, teamplayers); TC(bool, without_me);
        entity pl;
        if(teamplayers && !team_count)
                return;
@@ -722,7 +766,7 @@ void HUD_Quickmenu_PlayerListEntries(string cmd, float teamplayers, float withou
                        continue;
                if(without_me && pl.sv_entnum == player_localnum)
                        continue;
-               QUICKMENU_ENTRY(GetPlayerName(pl.sv_entnum), sprintf(cmd, GetPlayerName(pl.sv_entnum)))
+               QUICKMENU_ENTRY(entcs_GetName(pl.sv_entnum), sprintf(cmd, entcs_GetName(pl.sv_entnum)))
        }
 
        return;
@@ -763,11 +807,11 @@ void QuickMenu_Default(string target_submenu)
                QUICKMENU_ENTRY_TC(CTX(_("QMCMD^killed flag, icon")), "say_team %s; g_waypointsprite_team_here_p", "killed flagcarrier (l:%y^7)", CTX(_("QMCMD^killed flagcarrier (l:%y^7)")))
                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)")))
                QUICKMENU_ENTRY_TC(CTX(_("QMCMD^drop gun, icon")), "say_team %s; g_waypointsprite_team_here; wait; dropweapon", "dropped gun %w^7 (l:%l^7)", CTX(_("QMCMD^dropped gun %w^7 (l:%l^7)")))
-               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)")))
+               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)")))
        QUICKMENU_SMENU(CTX(_("QMCMD^Team chat")), "Team chat")
        }
 
-       QUICKMENU_SMENU_PL(CTX(_("QMCMD^Send private message to")), "Send private message to", "commandmode tell \"%s\" ^7", 0, 1)
+       QUICKMENU_SMENU_PL(CTX(_("QMCMD^Send private message to")), "Send private message to", "commandmode tell \"%s^7\"", 0, 1)
 
        QUICKMENU_SMENU(CTX(_("QMCMD^Settings")), "Settings")
                QUICKMENU_SMENU(CTX(_("QMCMD^View/HUD settings")), "View/HUD settings")
@@ -781,7 +825,7 @@ void QuickMenu_Default(string target_submenu)
 
                QUICKMENU_SMENU(CTX(_("QMCMD^Sound settings")), "Sound settings")
                        QUICKMENU_ENTRY(CTX(_("QMCMD^Hit sound")), "toggle cl_hitsound")
-                       QUICKMENU_ENTRY(CTX(_("QMCMD^Chat sound")), "toggle cl_chatsound")
+                       QUICKMENU_ENTRY(CTX(_("QMCMD^Chat sound")), "toggle con_chatsound")
                QUICKMENU_SMENU(CTX(_("QMCMD^Sound settings")), "Sound settings")
 
                if(spectatee_status > 0)
@@ -811,7 +855,7 @@ void QuickMenu_Default(string target_submenu)
        QUICKMENU_SMENU(CTX(_("QMCMD^Call a vote")), "Call a vote")
                QUICKMENU_ENTRY(CTX(_("QMCMD^Restart the map")), "vcall restart")
                QUICKMENU_ENTRY(CTX(_("QMCMD^End match")), "vcall endmatch")
-               if(getstatf(STAT_TIMELIMIT) > 0)
+               if(STAT(TIMELIMIT) > 0)
                {
                QUICKMENU_ENTRY(CTX(_("QMCMD^Reduce match time")), "vcall reducematchtime")
                QUICKMENU_ENTRY(CTX(_("QMCMD^Extend match time")), "vcall extendmatchtime")
@@ -822,9 +866,9 @@ void QuickMenu_Default(string target_submenu)
 
        if(target_submenu != "" && !target_submenu_found)
        {
-               printf("Couldn't find submenu \"%s\"\n", target_submenu);
+               LOG_WARNINGF("Couldn't find submenu \"%s\"\n", target_submenu);
                if(prvm_language != "en")
-                       printf("^3Warning: submenu must be in English\n", target_submenu);
+                       LOG_WARNINGF("^3Warning: submenu must be in English\n", target_submenu);
                QuickMenu_Buffer_Size = 0;
        }
 }