]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud.qc
Merge branch 'master' into terencehill/quickmenu
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud.qc
index 4b0bfa4fb862d3b5dbb6f0f377d31a7c87ab51f7..c4f81d3d47bfe059242a7f5ffbd1f31d154b665e 100644 (file)
@@ -243,9 +243,9 @@ float GetPlayerColorForce(float i)
 float GetPlayerColor(float i)
 {
        if not(playerslots[i].gotscores) // unconnected
-               return FL_SPECTATOR;
+               return NUM_SPECTATOR;
        else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
-               return FL_SPECTATOR;
+               return NUM_SPECTATOR;
        else
                return GetPlayerColorForce(i);
 }
@@ -526,8 +526,7 @@ void HUD_Weapons(void)
                weaponorder_cmp_str = string_null;
        }
 
-       if(autocvar_hud_panel_weapons_complainbubble)
-       if(autocvar__hud_configure || time - complain_weapon_time >= when + fadetime)
+       if(!autocvar_hud_panel_weapons_complainbubble || autocvar__hud_configure || time - complain_weapon_time >= when + fadetime)
                complain_weapon = 0;
 
        // determine which weapons are going to be shown
@@ -734,7 +733,7 @@ void HUD_Weapons(void)
                weapon_id = self.impulse;
 
                // skip if this weapon doesn't exist
-               if (!self || self.impulse < 0) { continue; }
+               if(!self || weapon_id < 0) { continue; }
 
                // skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon
                if(autocvar_hud_panel_weapons_onlyowned)
@@ -1629,20 +1628,6 @@ void HUD_HealthArmor(void)
 // Notification area (#4)
 //
 
-string Weapon_SuicideMessage(float deathtype)
-{
-       w_deathtype = deathtype;
-       get_weaponinfo(DEATH_WEAPONOF(deathtype)).weapon_func(WR_SUICIDEMESSAGE);
-       return w_deathtypestring;
-}
-
-string Weapon_KillMessage(float deathtype)
-{
-       w_deathtype = deathtype;
-       get_weaponinfo(DEATH_WEAPONOF(deathtype)).weapon_func(WR_KILLMESSAGE);
-       return w_deathtypestring;
-}
-
 void HUD_Notify_Push(string icon, string attacker, string victim)
 {
        if(icon != "")
@@ -2035,13 +2020,13 @@ void HUD_Radar(void)
        for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
        {
                color2 = GetPlayerColor(tm.sv_entnum);
-               //if(color == FL_SPECTATOR || color == color2)
+               //if(color == NUM_SPECTATOR || color == color2)
                        draw_teamradar_player(tm.origin, tm.angles, Team_ColorRGB(color2));
        }
        draw_teamradar_player(view_origin, view_angles, '1 1 1');
 
        drawresetcliparea();
-};
+}
 
 // Score (#7)
 //
@@ -2116,7 +2101,7 @@ void HUD_Score_Rankings(vector pos, vector mySize, entity me, float team_count)
                // show team scores in the first line
                float score_size = mySize_x / team_count;
                for(tm = teams.sort_next; tm; tm = tm.sort_next) {
-                       if(tm.team == FL_SPECTATOR)
+                       if(tm.team == NUM_SPECTATOR)
                                continue;
                        if (tm.team == myteam)
                                drawfill(pos + eX * score_size * i, eX * score_size + eY * fontsize_y, '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
@@ -2132,14 +2117,14 @@ void HUD_Score_Rankings(vector pos, vector mySize, entity me, float team_count)
        do
        for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
        {
-               if ((team_count && pl.team != tm.team) || pl.team == FL_SPECTATOR)
+               if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
                        continue;
 
                if (i == entries-1 && !me_printed && pl != me)
                if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
                {
                        for (pl = me.sort_next; pl; pl = pl.sort_next)
-                               if (pl.team != FL_SPECTATOR)
+                               if (pl.team != NUM_SPECTATOR)
                                        break;
 
                        if (pl)
@@ -2164,7 +2149,7 @@ void HUD_Score_Rankings(vector pos, vector mySize, entity me, float team_count)
                pos_y += fontsize_y;
                ++i;
        }
-       while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != FL_SPECTATOR || (tm = tm.sort_next)));
+       while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
 }
 
 void HUD_Score(void)
@@ -2285,7 +2270,7 @@ void HUD_Score(void)
                vector score_pos, score_size; //for scores other than myteam
                if (spectatee_status == -1 || autocvar_hud_panel_score_rankings)
                {
-                       for(tm = teams.sort_next; tm, tm.team != FL_SPECTATOR; tm = tm.sort_next)
+                       for(tm = teams.sort_next; tm, tm.team != NUM_SPECTATOR; tm = tm.sort_next)
                                ++scores_count;
                        if (autocvar_hud_panel_score_rankings)
                        {
@@ -2324,7 +2309,7 @@ void HUD_Score(void)
                draw_beginBoldFont();
                row = column = 0;
                for(tm = teams.sort_next; tm; tm = tm.sort_next) {
-                       if(tm.team == FL_SPECTATOR)
+                       if(tm.team == NUM_SPECTATOR)
                                continue;
                        score = tm.(teamscores[ts_primary]);
                        if(autocvar__hud_configure)
@@ -3295,7 +3280,7 @@ void HUD_Mod_Dom(vector myPos, vector mySize)
        entity tm;
        float teams_count = 0;
        for(tm = teams.sort_next; tm; tm = tm.sort_next)
-               if(tm.team != FL_SPECTATOR)
+               if(tm.team != NUM_SPECTATOR)
                        ++teams_count;
 
        float layout = autocvar_hud_panel_modicons_dom_layout;
@@ -3754,7 +3739,7 @@ void HUD_InfoMessages(void)
                        {
                                for(; tm.sort_next; tm = tm.sort_next)
                                {
-                                       if(!tm.team_size || tm.team == FL_SPECTATOR)
+                                       if(!tm.team_size || tm.team == NUM_SPECTATOR)
                                                continue;
                                        if(!ts_min) ts_min = tm.team_size;
                                        else ts_min = min(ts_min, tm.team_size);
@@ -3766,7 +3751,7 @@ void HUD_InfoMessages(void)
                                        s = strcat(blinkcolor, _("Teamnumbers are unbalanced!"));
                                        tm = GetTeam(myteam, false);
                                        if (tm)
-                                       if (tm.team != FL_SPECTATOR)
+                                       if (tm.team != NUM_SPECTATOR)
                                        if (tm.team_size == ts_max)
                                                s = strcat(s, sprintf(_(" Press ^3%s%s to adjust"), getcommandkey("team menu", "menu_showteamselect"), blinkcolor));
                                        drawInfoMessage(s)
@@ -4373,6 +4358,441 @@ void HUD_CenterPrint (void)
        }
 }
 
+
+// QUICKMENU_MAXLINES must be <= 10
+#define QUICKMENU_MAXLINES 10
+#define QUICKMENU_MAXENTRIES 256
+string QuickMenu_Command[QUICKMENU_MAXLINES];
+string QuickMenu_Description[QUICKMENU_MAXLINES];
+float QuickMenu_CurrentPage;
+float QuickMenu_IsLastPage;
+var float QuickMenu_Buffer = -1;
+float QuickMenu_Buffer_Size;
+float QuickMenu_Buffer_Index;
+string QuickMenu_CurrentSubMenu;
+float QuickMenu_CurrentPage_FirstEntry;
+var float QuickMenu_Entries;
+void HUD_QuickMenu_load_entry(float i, string s, string s1)
+{
+       //print(sprintf("^xc80 entry %d: %s, %s\n", i, s, s1));
+       if (QuickMenu_Description[i])
+               strunzone(QuickMenu_Description[i]);
+       QuickMenu_Description[i] = strzone(s);
+       if (QuickMenu_Command[i])
+               strunzone(QuickMenu_Command[i]);
+       QuickMenu_Command[i] = strzone(s1);
+}
+void HUD_QuickMenu_clear_entry(float i)
+{
+       if (QuickMenu_Description[i])
+               strunzone(QuickMenu_Description[i]);
+       QuickMenu_Description[i] = string_null;
+       if (QuickMenu_Command[i])
+               strunzone(QuickMenu_Command[i]);
+       QuickMenu_Command[i] = string_null;
+}
+
+float HUD_QuickMenu_Buffer_Init()
+{
+       float fh, i;
+       string s;
+       fh = fopen(autocvar_hud_panel_quickmenu_file, FILE_READ);
+       if(fh < 0)
+       {
+               print(sprintf(_("Error: Couldn't open file %s!\n"), autocvar_hud_panel_quickmenu_file));
+               return false;
+       }
+
+       QuickMenu_Buffer = buf_create();
+       if (QuickMenu_Buffer < 0)
+       {
+               fclose(fh);
+               return false;
+       }
+
+       i = 0;
+       while((s = fgets(fh)) && i < QUICKMENU_MAXENTRIES)
+       {
+               // first skip invalid entries, so we don't check them anymore
+               float argc;
+               argc = tokenize_console(s);
+               if(argc == 0 || argc > 2)
+                       continue;
+
+               bufstr_set(QuickMenu_Buffer, i, s);
+               ++i;
+       }
+       QuickMenu_Buffer_Size = i;
+
+       if (QuickMenu_Buffer_Size <= 0)
+       {
+               buf_del(QuickMenu_Buffer);
+               QuickMenu_Buffer = -1;
+       }
+       fclose(fh);
+       return true;
+}
+void HUD_QuickMenu_Buffer_Close()
+{
+       if (QuickMenu_Buffer >= 0)
+       {
+               buf_del(QuickMenu_Buffer);
+               QuickMenu_Buffer = -1;
+               QuickMenu_Buffer_Size = 0;
+       }
+}
+void HUD_QuickMenu_Close()
+{
+       if (QuickMenu_CurrentSubMenu)
+               strunzone(QuickMenu_CurrentSubMenu);
+       QuickMenu_CurrentSubMenu = string_null;
+       float i;
+       for (i = 0; i < QUICKMENU_MAXLINES; ++i)
+               HUD_QuickMenu_clear_entry(i);
+       QuickMenu_Entries = 0;
+       hud_panel_quickmenu = 0;
+       mouseClicked = 0;
+       prevMouseClicked = 0;
+       HUD_QuickMenu_Buffer_Close();
+}
+
+// It assumes submenu open tag is already detected
+void HUD_QuickMenu_skip_submenu(string submenu)
+{
+       string s, z_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);
+               float argc;
+               argc = tokenize_console(s);
+               if(argc == 2)
+                       continue;
+               if (argv(0) == "")
+                       continue;
+               if (argv(0) == z_submenu) // submenu end
+                       break;
+               HUD_QuickMenu_skip_submenu(argv(0));
+       }
+       strunzone(z_submenu);
+}
+
+
+float HUD_QuickMenu_IsOpened()
+{
+       return (QuickMenu_Entries > 0);
+}
+
+// new_page 0 means page 0, new_page != 0 means next page
+float QuickMenu_Buffer_Index_Prev;
+void HUD_QuickMenu_Open(string target_submenu, float new_page)
+{
+       float total, i;
+       string s, z_submenu;
+
+       if (new_page == 0)
+               QuickMenu_CurrentPage = 0;
+       else
+               ++QuickMenu_CurrentPage;
+       QuickMenu_CurrentPage_FirstEntry = QuickMenu_CurrentPage * (QUICKMENU_MAXLINES - 2);
+
+       z_submenu = strzone(target_submenu);
+       if (QuickMenu_CurrentSubMenu)
+               strunzone(QuickMenu_CurrentSubMenu);
+       QuickMenu_CurrentSubMenu = strzone(z_submenu);
+
+       QuickMenu_IsLastPage = TRUE;
+       QuickMenu_Entries = 0;
+
+       QuickMenu_Buffer_Index = 0;
+       if (z_submenu != "")
+       {
+               // 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 (tokenize_console(s) == 1 && argv(0) == z_submenu)
+                       {
+                               // print(sprintf("^3 beginning of %s\n", z_submenu));
+                               ++QuickMenu_Buffer_Index;
+                               break;
+                       }
+                       // print(sprintf("^1 skipping %s\n", s));
+               }
+       }
+       for( ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index)
+       {
+               s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index);
+               float argc;
+               argc = tokenize_console(s);
+
+               if (z_submenu != "" && z_submenu == argv(0))
+               {
+                       // print(sprintf("^3 end of %s\n", z_submenu));
+                       break;
+               }
+
+               if (total - QuickMenu_CurrentPage_FirstEntry >= 0)
+               {
+                       ++QuickMenu_Entries;
+                       if(QuickMenu_Entries == QUICKMENU_MAXLINES - 2)
+                               QuickMenu_Buffer_Index_Prev = QuickMenu_Buffer_Index;
+                       else if(QuickMenu_Entries == QUICKMENU_MAXLINES)
+                       {
+                               HUD_QuickMenu_clear_entry(QUICKMENU_MAXLINES - 1);
+                               QuickMenu_Buffer_Index = QuickMenu_Buffer_Index_Prev;
+                               QuickMenu_IsLastPage = FALSE;
+                               break;
+                       }
+               }
+
+               // NOTE: entries are loaded starting from 1, not from 0
+               if (argc == 1 && argv(0) != "") // submenu
+               {
+                       if (total - QuickMenu_CurrentPage_FirstEntry >= 0)
+                               HUD_QuickMenu_load_entry(QuickMenu_Entries, argv(0), "");
+                       HUD_QuickMenu_skip_submenu(argv(0));
+               }
+               else if (total - QuickMenu_CurrentPage_FirstEntry >= 0)
+                       HUD_QuickMenu_load_entry(QuickMenu_Entries, argv(0), argv(1));
+
+               ++total;
+       }
+       strunzone(z_submenu);
+       if (QuickMenu_Entries == 0)
+               HUD_QuickMenu_Close();
+       else
+               hud_panel_quickmenu = 1;
+}
+
+float HUD_QuickMenu_ActionForNumber(float num)
+{
+       if (!QuickMenu_IsLastPage)
+       {
+               if (num < 0 || num >= QUICKMENU_MAXLINES)
+                       return 0;
+               if (num == QUICKMENU_MAXLINES - 1)
+                       return 0;
+               if (num == 0)
+               {
+                       HUD_QuickMenu_Open(QuickMenu_CurrentSubMenu, +1);
+                       return 0;
+               }
+       } else if (num <= 0 || num > QuickMenu_Entries)
+               return 0;
+
+       if (QuickMenu_Command[num] != "")
+       {
+               localcmd(strcat("\n", QuickMenu_Command[num], "\n"));
+               return 1;
+       }
+       if (QuickMenu_Description[num] != "")
+               HUD_QuickMenu_Open(QuickMenu_Description[num], 0);
+       return 0;
+}
+float HUD_QuickMenu_InputEvent(float bInputType, float nPrimary, float nSecondary)
+{
+       string s;
+
+       // we only care for keyboard events
+       if(bInputType != 0 && bInputType != 1)
+               return false;
+
+       if(!HUD_QuickMenu_IsOpened() || autocvar__hud_configure)
+               return false;
+
+       // allow console bind to work
+       string con_keys;
+       float keys;
+       con_keys = findkeysforcommand("toggleconsole", 0);
+       keys = tokenize(con_keys); // findkeysforcommand returns data for this
+
+       float hit_con_bind, i;
+       for (i = 0; i < keys; ++i)
+       {
+               if(nPrimary == stof(argv(i)))
+                       hit_con_bind = 1;
+       }
+
+       if(bInputType == 0) {
+               if(nPrimary == K_ALT) hudShiftState |= S_ALT;
+               if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
+               if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
+       }
+       else if(bInputType == 1) {
+               if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
+               if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
+               if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
+       }
+
+       if(nPrimary == K_ESCAPE)
+       {
+               if (bInputType == 1)
+                       return true;
+               HUD_QuickMenu_Close();
+       }
+       else if(nPrimary >= '0' && nPrimary <= '9')
+       {
+               if (bInputType == 1)
+                       return true;
+               HUD_QuickMenu_ActionForNumber(stof(chr2str(nPrimary)));
+       }
+       if(nPrimary == K_MOUSE1)
+       {
+               if(bInputType == 0) // key pressed
+                       mouseClicked |= S_MOUSE1;
+               else if(bInputType == 1) // key released
+                       mouseClicked -= (mouseClicked & S_MOUSE1);
+       }
+       else if(nPrimary == K_MOUSE2)
+       {
+               if(bInputType == 0) // key pressed
+                       mouseClicked |= S_MOUSE2;
+               else if(bInputType == 1) // key released
+                       mouseClicked -= (mouseClicked & S_MOUSE2);
+       }
+       else if(hit_con_bind)
+               return false;
+
+       return true;
+}
+void HUD_QuickMenu_Mouse()
+{
+       if(!mouseClicked)
+       if(prevMouseClicked & S_MOUSE2)
+       {
+               HUD_QuickMenu_Close();
+               return;
+       }
+
+       mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
+
+       mousepos_x = bound(0, mousepos_x, vid_conwidth);
+       mousepos_y = bound(0, mousepos_y, vid_conheight);
+
+       HUD_Panel_UpdatePosSize(quickmenu)
+
+       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_Entries) * fontsize_y) / 2;
+       entries_height = panel_size_y - ((QUICKMENU_MAXLINES - QuickMenu_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)
+       {
+               float entry_num;
+               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;
+                       vector color;
+                       if(mouseClicked & S_MOUSE1)
+                               color = '0.5 1 0.5';
+                       else if(hudShiftState & S_CTRL)
+                               color = '1 1 0.3';
+                       else
+                               color = '1 1 1';
+                       drawfill(panel_pos, eX * panel_size_x + eY * fontsize_y, color, .2, DRAWFLAG_NORMAL);
+
+                       if(!mouseClicked && prevMouseClicked & S_MOUSE1)
+                       {
+                               float f;
+                               if (entry_num < QUICKMENU_MAXLINES - 1)
+                                       f = HUD_QuickMenu_ActionForNumber(entry_num + 1);
+                               else
+                                       f = HUD_QuickMenu_ActionForNumber(0);
+                               if(f && !(hudShiftState & S_CTRL))
+                                       HUD_QuickMenu_Close();
+                       }
+               }
+       }
+
+       const vector cursorsize = '32 32 0';
+       drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', 0.8, DRAWFLAG_NORMAL);
+
+       prevMouseClicked = mouseClicked;
+}
+void HUD_QuickMenu_DrawEntry(vector pos, string s, vector fontsize)
+{
+       string entry;
+       float offset;
+       entry = textShortenToWidth(s, panel_size_x, fontsize, stringwidth_colors);
+       if (autocvar_hud_panel_quickmenu_align > 0)
+       {
+               offset = (panel_size_x - stringwidth_colors(entry, fontsize)) * min(autocvar_hud_panel_quickmenu_align, 1);
+               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)
+{
+       if(!autocvar__hud_configure)
+       {
+               if (hud_configure_prev && hud_configure_prev != -1)
+                       HUD_QuickMenu_Close();
+
+               if(!hud_draw_maximized) return;
+               //if(!autocvar_hud_panel_quickmenu) return; // autocvar exists only for conformity with other panels
+               if(!hud_panel_quickmenu) return;
+       }
+       else
+       {
+               if(!HUD_QuickMenu_IsOpened())
+               {
+                       QuickMenu_Entries = 1;
+                       HUD_QuickMenu_load_entry(QuickMenu_Entries, sprintf(_("Submenu%d"), QuickMenu_Entries), "");
+                       ++QuickMenu_Entries;
+                       HUD_QuickMenu_load_entry(QuickMenu_Entries, sprintf(_("Submenu%d"), QuickMenu_Entries), "");
+                       ++QuickMenu_Entries;
+                       // although real command doesn't matter here, it must not be empty
+                       // otherwise the entry is displayed like a submenu
+                       for (; QuickMenu_Entries < QUICKMENU_MAXLINES - 1; ++QuickMenu_Entries)
+                               HUD_QuickMenu_load_entry(QuickMenu_Entries, sprintf(_("Command%d"), QuickMenu_Entries), "-");
+                       ++QuickMenu_Entries;
+                       HUD_QuickMenu_clear_entry(QuickMenu_Entries);
+                       QuickMenu_IsLastPage = FALSE;
+               }
+
+               hud_configure_active_panel = HUD_PANEL_QUICKMENU;
+       }
+
+       HUD_Panel_UpdateCvars(quickmenu);
+       HUD_Panel_ApplyFadeAlpha();
+
+       HUD_Panel_DrawBg(1);
+
+       if(panel_bg_padding)
+       {
+               panel_pos += '1 1 0' * panel_bg_padding;
+               panel_size -= '2 2 0' * panel_bg_padding;
+       }
+
+       float i;
+       vector fontsize;
+       string color;
+       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...")), fontsize);
+       }
+       else
+               panel_pos_y += ((QUICKMENU_MAXLINES - QuickMenu_Entries) * fontsize_y) / 2;
+
+       for (i = 1; i <= QuickMenu_Entries; ++i) {
+               if (QuickMenu_Description[i] == "")
+                       break;
+               if (QuickMenu_Command[i] == "")
+                       color = "^4";
+               else
+                       color = "^3";
+               HUD_QuickMenu_DrawEntry(panel_pos, sprintf("%d: %s%s", i, color, QuickMenu_Description[i]), fontsize);
+               panel_pos_y += fontsize_y;
+       }
+}
+
 /*
 ==================
 Main HUD system
@@ -4424,6 +4844,8 @@ switch (id) {\
                HUD_Physics(); break;\
        case (HUD_PANEL_CENTERPRINT):\
                HUD_CenterPrint(); break;\
+       case (HUD_PANEL_QUICKMENU):\
+               HUD_QuickMenu(); break;\
 } ENDS_WITH_CURLY_BRACE
 
 void HUD_Main (void)
@@ -4588,6 +5010,8 @@ void HUD_Main (void)
                HUD_Radar();
        if(autocvar__con_chat_maximized)
                HUD_Chat();
+       if(hud_panel_quickmenu)
+               HUD_QuickMenu();
 
        if(autocvar__hud_configure)
        {