]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud.qc
Merge branch 'master' into Mario/buff_updates
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud.qc
index 1088011808d0c6479f632725848403b82ed3d2bd..dfe52049b16ed8c6ed79c7140dd9ab54de9f9227 100644 (file)
@@ -146,10 +146,44 @@ float HUD_GetRowCount(float item_count, vector size, float item_aspect)
        return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
 }
 
-float HUD_GetColumnCount(float item_count, vector size, float item_aspect)
+vector HUD_GetTableSize(float item_count, vector psize, float item_aspect)
 {
-       float aspect = size_x / size_y;
-       return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
+       float columns, rows;
+       float ratio, best_ratio = 0;
+       float best_columns = 1, best_rows = 1;
+       bool vertical = (psize.x / psize.y >= item_aspect);
+       if(vertical)
+       {
+               psize = eX * psize.y + eY * psize.x;
+               item_aspect = 1 / item_aspect;
+       }
+
+       rows = ceil(sqrt(item_count));
+       columns = ceil(item_count/rows);
+       while(columns >= 1)
+       {
+               ratio = (psize.x/columns) / (psize.y/rows);
+               if(ratio > item_aspect)
+                       ratio = item_aspect * item_aspect / ratio;
+
+               if(ratio <= best_ratio)
+                       break; // ratio starts decreasing by now, skip next configurations
+
+               best_columns = columns;
+               best_rows = rows;
+               best_ratio = ratio;
+
+               if(columns == 1)
+                       break;
+
+               --columns;
+               rows = ceil(item_count/columns);
+       }
+
+       if(vertical)
+               return eX * best_rows + eY * best_columns;
+       else
+               return eX * best_columns + eY * best_rows;
 }
 
 float stringwidth_colors(string s, vector theSize)
@@ -512,6 +546,17 @@ void HUD_Weapons(void)
                if(!weapons_stat)
                        for(i = WEP_FIRST; i <= WEP_LAST; i += floor((WEP_LAST-WEP_FIRST)/5))
                                weapons_stat |= WepSet_FromWeapon(i);
+
+               #if 0
+               /// debug code
+               if(cvar("wep_add"))
+               {
+                       weapons_stat = '0 0 0';
+                       float countw = 1 + floor((floor(time * cvar("wep_add"))) % WEP_COUNT);
+                       for(i = WEP_FIRST; i <= countw; ++i)
+                               weapons_stat |= WepSet_FromWeapon(i);
+               }
+               #endif
        }
 
        // determine which weapons are going to be shown
@@ -529,6 +574,7 @@ void HUD_Weapons(void)
                        if((weapons_stat & WepSet_FromWeapon(weaponorder[i].weapon)) || (weaponorder[i].weapon == complain_weapon))
                                ++weapon_count;
 
+
                // might as well commit suicide now, no reason to live ;)
                if (weapon_count == 0)
                {
@@ -540,51 +586,32 @@ void HUD_Weapons(void)
                vector padded_panel_size = panel_size - '2 2 0' * panel_bg_padding;
 
                // get the all-weapons layout
-               if(padded_panel_size.x / padded_panel_size.y < aspect)
-               {
-                       columns = HUD_GetColumnCount(WEP_COUNT, padded_panel_size, aspect);
-                       rows = ceil(WEP_COUNT/columns);
-               }
-               else
-               {
-                       rows = HUD_GetRowCount(WEP_COUNT, padded_panel_size, aspect);
-                       columns = ceil(WEP_COUNT/rows);
-               }
+               vector table_size = HUD_GetTableSize(WEP_COUNT, padded_panel_size, aspect);
+               columns = table_size.x;
+               rows = table_size.y;
                weapon_size.x = padded_panel_size.x / columns;
                weapon_size.y = padded_panel_size.y / rows;
 
-               // reduce table trying to keep the original table proportions as much as possible
-               vertical_order = (columns >= rows);
-               if(vertical_order)
-               {
-                       rows = ceil(sqrt(weapon_count / (columns / rows)));
-                       columns = ceil(weapon_count / rows);
-               }
-               else
+               // NOTE: although weapons should aways look the same even if onlyowned is enabled,
+               // we enlarge them a bit when possible to better match the desired aspect ratio
+               if(padded_panel_size.x / padded_panel_size.y < aspect)
                {
-                       columns = ceil(sqrt(weapon_count / (rows / columns)));
+                       // maximum number of rows that allows to display items with the desired aspect ratio
+                       float max_rows = floor(padded_panel_size.y / (weapon_size.x / aspect));
+                       columns = min(columns, ceil(weapon_count / max_rows));
                        rows = ceil(weapon_count / columns);
+                       weapon_size.y = min(padded_panel_size.y / rows, weapon_size.x / aspect);
+                       weapon_size.x = min(padded_panel_size.x / columns, aspect * weapon_size.y);
+                       vertical_order = false;
                }
-
-               // reduce cell size to match the desired aspect ratio
-               // NOTE: it doesn't reduce weapon icon size itself at all
-               // (assuming aspect ratio of the real weapon image == aspect)
-               if(weapon_size.x / weapon_size.y > aspect)
-                       weapon_size.x = aspect * weapon_size.y;
                else
-                       weapon_size.y = weapon_size.x / aspect;
-
-               float maxscale = autocvar_hud_panel_weapons_onlyowned_icon_maxscale;
-               if(maxscale == 0)
-                       maxscale = 99;
-               if(maxscale > 1)
                {
-                       weapon_size.x = min(padded_panel_size.x / columns, weapon_size.x * maxscale);
-                       weapon_size.y = min(padded_panel_size.y / rows, weapon_size.y * maxscale);
-                       if(weapon_size.x / weapon_size.y > aspect)
-                               weapon_size.x = aspect * weapon_size.y;
-                       else
-                               weapon_size.y = weapon_size.x / aspect;
+                       float max_columns = floor(padded_panel_size.x / (weapon_size.y * aspect));
+                       rows = min(rows, ceil(weapon_count / max_columns));
+                       columns = ceil(weapon_count / rows);
+                       weapon_size.x = min(padded_panel_size.x / columns, aspect * weapon_size.y);
+                       weapon_size.y = min(padded_panel_size.y / rows, weapon_size.x / aspect);
+                       vertical_order = true;
                }
 
                // reduce size of the panel
@@ -594,16 +621,24 @@ void HUD_Weapons(void)
 
                // center the resized panel, or snap it to the screen edge when close enough
                if(panel_pos.x > vid_conwidth * 0.001)
+               {
                        if(panel_pos.x + old_panel_size.x > vid_conwidth * 0.999)
                                panel_pos.x += old_panel_size.x - panel_size.x;
                        else
                                panel_pos.x += (old_panel_size.x - panel_size.x) / 2;
+               }
+               else if(old_panel_size.x > vid_conwidth * 0.999)
+                       panel_pos.x += (old_panel_size.x - panel_size.x) / 2;
 
                if(panel_pos.y > vid_conheight * 0.001)
+               {
                        if(panel_pos.y + old_panel_size.y > vid_conheight * 0.999)
                                panel_pos.y += old_panel_size.y - panel_size.y;
                        else
                                panel_pos.y += (old_panel_size.y - panel_size.y) / 2;
+               }
+               else if(old_panel_size.y > vid_conheight * 0.999)
+                       panel_pos.y += (old_panel_size.y - panel_size.y) / 2;
        }
        else
                weapon_count = WEP_COUNT;
@@ -714,18 +749,12 @@ void HUD_Weapons(void)
 
        if(!rows) // if rows is > 0 onlyowned code has already updated these vars
        {
-               if(panel_size.x / panel_size.y < aspect)
-               {
-                       columns = HUD_GetColumnCount(WEP_COUNT, panel_size, aspect);
-                       rows = ceil(WEP_COUNT/columns);
-               }
-               else
-               {
-                       rows = HUD_GetRowCount(WEP_COUNT, panel_size, aspect);
-                       columns = ceil(WEP_COUNT/rows);
-               }
-               weapon_size = eX * panel_size.x*(1/columns) + eY * panel_size.y*(1/rows);
-               vertical_order = (columns >= rows);
+               vector table_size = HUD_GetTableSize(WEP_COUNT, panel_size, aspect);
+               columns = table_size.x;
+               rows = table_size.y;
+               weapon_size.x = panel_size.x / columns;
+               weapon_size.y = panel_size.y / rows;
+               vertical_order = (panel_size.x / panel_size.y >= aspect);
        }
 
        // calculate position/size for visual bar displaying ammount of ammo status
@@ -882,9 +911,14 @@ void HUD_Weapons(void)
                        drawstring_aspect(weapon_pos + '1 1 0' * padding, s, weapon_size - '2 2 0' * padding, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
                }
 
-               /// debug
-               //drawfill(weapon_pos + '1 1 0', weapon_size - '2 2 0', '1 1 1', panel_fg_alpha * 0.2, DRAWFLAG_NORMAL);
-               //drawstring(weapon_pos, ftos(i + 1), label_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               #if 0
+               /// debug code
+               if(!autocvar_hud_panel_weapons_onlyowned)
+               {
+                       drawfill(weapon_pos + '1 1 0', weapon_size - '2 2 0', '1 1 1', panel_fg_alpha * 0.2, DRAWFLAG_NORMAL);
+                       drawstring(weapon_pos, ftos(i + 1), label_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               }
+               #endif
 
                // continue with new position for the next weapon
                if(vertical_order)
@@ -4252,12 +4286,12 @@ void HUD_CenterPrint (void)
        {
                if(!autocvar_hud_panel_centerprint) return;
 
-               if (hud_configure_prev && hud_configure_prev != -1)
+               if(hud_configure_prev)
                        reset_centerprint_messages();
        }
        else
        {
-               if (!hud_configure_prev)
+               if(!hud_configure_prev)
                        reset_centerprint_messages();
                if (time > hud_configure_cp_generation_time)
                {
@@ -4488,8 +4522,7 @@ void HUD_Buffs(void)
        }
 
        HUD_Panel_UpdateCvars();
-
-       draw_beginBoldFont();
+       
 
        vector pos, mySize;
        pos = panel_pos;
@@ -4507,8 +4540,16 @@ void HUD_Buffs(void)
        //float buff_iconalign = autocvar_hud_panel_buffs_iconalign;
        vector buff_offset = '0 0 0';
 
+       draw_beginBoldFont();
+       float buff_time, buff_maxtime;
+       buff_time = bound(0, getstatf(STAT_BUFF_TIME) - time, 99);
+       buff_maxtime = 60; // TODO: stat?
        for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
        {
+               if(buff_time && autocvar_hud_panel_buffs_progressbar)
+                       HUD_Panel_DrawProgressBar(pos + buff_offset, mySize, autocvar_hud_panel_buffs_progressbar_name, buff_time/buff_maxtime, 0, 0, 
+                                                                         Buff_Color(e.items) * -1 + '1 1 1', (autocvar_hud_progressbar_alpha * panel_fg_alpha) * 0.4, DRAWFLAG_NORMAL);
+
                //DrawNumIcon(pos + buff_offset, mySize, shield, "shield", is_vertical, buff_iconalign, '1 1 1', 1);
                drawcolorcodedstring_aspect(pos + buff_offset, s, mySize, panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
        }