]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'terencehill/newpanelhud' into fruitiex/newpanelhud
authorFruitieX <rasse@rasse-lappy.localdomain>
Wed, 4 Aug 2010 16:18:40 +0000 (19:18 +0300)
committerFruitieX <rasse@rasse-lappy.localdomain>
Wed, 4 Aug 2010 16:18:40 +0000 (19:18 +0300)
1  2 
defaultXonotic.cfg
qcsrc/client/hud.qc
qcsrc/client/hud.qh
qcsrc/client/miscfunctions.qc

diff --combined defaultXonotic.cfg
index 4bfda43cda29abb16c697dfddd8caff9fbffbfb8,2098db4811b90b64a0c176bae9b93c2d7d430474..9dd349f5e4f7a9e3958a68e6e60660b26fdcbd57
@@@ -1355,6 -1355,8 +1355,8 @@@ seta hud_panel_weapons_ammo_full_nails 
  seta hud_panel_weapons_ammo_full_cells 80 "show 100% of the status bar at this ammo count"
  seta hud_panel_weapons_ammo_full_rockets 80 "show 100% of the status bar at this ammo count"
  seta hud_panel_weapons_ammo_full_fuel 100 "show 100% of the status bar at this ammo count"
+ seta hud_panel_weapons_timeout "10" "panel disappears if you don't switch weapon for this amount of seconds"
+ seta hud_panel_weapons_timeout_effect "1" "disappearance effect: 0) no effect; 1) panel moves out of screen; 2) panel fades out"
  
  seta hud_panel_notify_time 10 "time that a new entry stays until it fades out"
  seta hud_panel_notify_fadetime 3 "fade out time"
@@@ -1391,8 -1393,6 +1393,8 @@@ seta scoreboard_fadeoutspeed 5 "speed a
  seta scoreboard_highlight 1 "enable highlighting for rows and columns in the scoreboard"
  seta scoreboard_highlight_alpha 0.10 "highlight alpha value (depends on hud_scoreboard_highlight 1)"
  seta scoreboard_highlight_alpha_self 0.25 "self highlight alpha value"
 +seta scoreboard_offset_left 0.04 "how many pixels the scoreboard is offset from the left screen edge"
 +seta scoreboard_offset_right 0.148 "how many pixels the scoreboard is offset from the right screen edge"
  
  // for menu server list (eventually make them have engine support?)
  seta menu_slist_showfull 1 "show servers even if they are full and have no slots to join"
@@@ -1519,7 -1519,7 +1521,7 @@@ set capturelimit 
  // hud: font size
  seta hud_fontsize 11
  seta hud_fontsize_spec 16
 -seta scr_centersize 11
 +seta scr_centersize 12
  seta hud_width 560
  // alias hud_font "loadfont user1 ${1},gfx/fallback ${2-}; loadfont user2 ${1}-big ${2-}; scoreboard_columns_set"
  alias sbar_font "set _requested_sbar_font \"${*}\""
diff --combined qcsrc/client/hud.qc
index c294401c78854d8490821529d2a93af9f9d86a59,da5c237d8f460914e780be1a463b12d09f66b3d7..6dc62337d52dea5e320795bdd1c847ba454cd7fe
@@@ -131,7 -131,7 +131,7 @@@ float stringwidth_nocolors(string s, ve
  #define CENTERPRINT_MAX_LINES 30
  string centerprint_messages[CENTERPRINT_MAX_LINES];
  float centerprint_width[CENTERPRINT_MAX_LINES];
 -vector centerprint_start;
 +float centerprint_time;
  float centerprint_expire;
  float centerprint_num;
  float centerprint_offset_hint;
@@@ -182,8 -182,6 +182,8 @@@ void centerprint(string strMessage
                while(getWrappedLine_remaining)
                {
                        s = getWrappedLine(vid_conwidth * 0.75, centerprint_fontsize, stringwidth_colors);
 +                      if(centerprint_messages[i] != s) // don't fade the same message in, looks stupid
 +                              centerprint_time = time;
                        if(centerprint_messages[i])
                                strunzone(centerprint_messages[i]);
                        centerprint_messages[i] = strzone(s);
        if(havail > vid_conheight - 70)
                havail = vid_conheight - 70; // avoid overlapping HUD
  
 -      centerprint_start_x = 0;
 -
  #if 0
        float forbiddenmin, forbiddenmax, allowedmin, allowedmax, preferred;
  
                centerprint_start_y = bound(forbiddenmax, preferred, allowedmax);
        }
  #else
 -      centerprint_start_y =
 -              min(
 -                      max(
 -                              max(scoreboard_bottom, vid_conheight * 0.5 + 16),
 -                              (havail - h)/2
 -                      ),
 -                      havail - h
 -              );
  #endif
  
        centerprint_num = i;
 +
        centerprint_expire = time + cvar("scr_centertime");
  }
  
@@@ -272,39 -279,32 +272,39 @@@ void HUD_DrawCenterPrint (void
        float i;
        vector pos;
        string ts;
 -      float a;
 +      float a, sz;
  
 -      //if(time > centerprint_expire)
 -      //      return;
 -
 -      //a = bound(0, 1 - 2 * (time - centerprint_expire), 1);
 -      a = bound(0, 1 - 4 * (time - centerprint_expire), 1);
 -      //sz = 1.2 / (a + 0.2);
 +      if(time - centerprint_time < 0.25)
 +              a = (time - centerprint_time) / 0.25;
 +      else
 +              a = bound(0, 1 - 4 * (time - centerprint_expire), 1);
  
        if(a <= 0)
                return;
  
 +      sz = 0.8 + (a / 5);
 +
 +      if(centerprint_num * cvar("scr_centersize") > 24 && HUD_WouldDrawScoreboard()) // 24 = height of Scoreboard text
 +      {
 +              centerprint_start_y = scoreboard_bottom + centerprint_fontsize_y;
 +      }
        pos = centerprint_start;
        for (i=0; i<centerprint_num; i = i + 1)
        {
 -              pos_x = (vid_conwidth - centerprint_width[i]) * 0.5;
                ts = centerprint_messages[i];
 +              drawfontscale = sz * '1 1 0';
 +              drawfont = hud_bigfont;
 +              pos_x = (vid_conwidth - stringwidth(ts, TRUE, centerprint_fontsize)) * 0.5;
                if (ts != "")
                {
 -                      drawcolorcodedstring(pos, ts, centerprint_fontsize, a, DRAWFLAG_NORMAL);
 -                      //  - '0 0.5 0' * (sz - 1) * centerprint_fontsize_x - '0.5 0 0' * (sz - 1) * centerprint_width[i] * centerprint_fontsize_y, centerprint_fontsize * sz
 +                      drawcolorcodedstring(pos + '0 1 0' * (1 - sz) * 0.5 *centerprint_fontsize_y, ts, centerprint_fontsize, a, DRAWFLAG_NORMAL);
                        pos_y = pos_y + centerprint_fontsize_y;
                }
                else
                        // half height for empty lines looks better
 -                      pos_y = pos_y + centerprint_fontsize_y * 0.5;
 +                      pos_y = pos_y + sz * centerprint_fontsize_y * 0.5;
 +              drawfontscale = '1 1 0';
 +              drawfont = hud_font;
        }
  }
  
@@@ -453,9 -453,6 +453,9 @@@ void HUD_Panel_ExportCfg(string cfgname
                fputs(fh, strcat("seta hud_configure_grid_ysize \"", cvar_string("hud_configure_grid_ysize"), "\"", "\n"));
                fputs(fh, "\n");
  
 +              fputs(fh, strcat("seta scr_centerpos \"", cvar_string("scr_centerpos"), "\"", "\n"));
 +              fputs(fh, "\n");
 +
                // common cvars for all panels
                float i;
                for (i = 0; i < HUD_PANEL_NUM; ++i)
                                case HUD_PANEL_PRESSEDKEYS:
                                        fputs(fh, strcat("seta hud_panel_", panel_name, "_aspect \"", cvar_string(strcat("hud_panel_", panel_name, "_aspect")), "\"", "\n"));
                                        break;
 +                              case HUD_PANEL_INFOMESSAGES:
 +                                      fputs(fh, strcat("seta hud_panel_", panel_name, "_flip \"", cvar_string(strcat("hud_panel_", panel_name, "_flip")), "\"", "\n"));
 +                                      break;
                        }
                        fputs(fh, "\n");
                }
@@@ -946,6 -940,10 +946,10 @@@ void HUD_Panel_Arrow_Action(float nPrim
  
        HUD_Panel_UpdatePosSizeForId(highlightedPanel)
  
+       vector prev_pos, prev_size;
+       prev_pos = panel_pos;
+       prev_size = panel_size;
        if (hudShiftState & S_ALT) // resize
        {
                highlightedAction = 1;
  
                HUD_Panel_SetPos(pos);
        }
+       HUD_Panel_UpdatePosSizeForId(highlightedPanel)
+       if (prev_pos != panel_pos || prev_size != panel_size)
+       {
+               // backup!
+               panel_pos_backup = prev_pos;
+               panel_size_backup = prev_size;
+               highlightedPanel_backup = highlightedPanel;
+       }
  }
  
  float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
                menu_enabled_time = time;
                localcmd("menu_showhudexit\n");
        }
+       else if(hudShiftState & S_CTRL)
+       {
+               if (mouseClicked)
+                       return true;
+               if(nPrimary == K_SPACE) // enable/disable highlighted panel or dock
+               {
+                       if (bInputType == 1)
+                               return true;
+                       if (highlightedPanel_prev != -1)
+                               cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled)));
+                       else
+                               cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : "");
+               }
+               if(nPrimary == 'c') // copy highlighted panel size
+               {
+                       if (bInputType == 1)
+                               return true;
+                       if (highlightedPanel_prev != -1)
+                       {
+                               panel_size_copied = panel_size;
+                               highlightedPanel_copied = highlightedPanel_prev;
+                       }
+               }
+               else if(nPrimary == 'v') // past copied size on the highlighted panel
+               {
+                       if (bInputType == 1)
+                               return true;
+                       if (highlightedPanel_copied != -1 && highlightedPanel_prev != -1)
+                       {
+                               // backup first!
+                               panel_pos_backup = panel_pos;
+                               panel_size_backup = panel_size;
+                               highlightedPanel_backup = highlightedPanel_prev;
+                               string s;
+                               s = strcat(ftos(panel_size_copied_x/vid_conwidth), " ", ftos(panel_size_copied_y/vid_conheight));
+                               cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
+                       }
+               }
+               else if(nPrimary == 'z') // undo last action
+               {
+                       if (bInputType == 1)
+                               return true;
+                       //restore previous values
+                       if (highlightedPanel_backup != -1)
+                       {
+                               HUD_Panel_GetName(highlightedPanel_backup)
+                               string s;
+                               s = strcat(ftos(panel_pos_backup_x/vid_conwidth), " ", ftos(panel_pos_backup_y/vid_conheight));
+                               cvar_set(strcat("hud_panel_", panel_name, "_pos"), s);
+                               s = strcat(ftos(panel_size_backup_x/vid_conwidth), " ", ftos(panel_size_backup_y/vid_conheight));
+                               cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
+                               highlightedPanel_backup = -1;
+                       }
+               }
+       }
        else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW)
        {
                if (bInputType == 1)
@@@ -1232,6 -1300,7 +1306,7 @@@ void HUD_Panel_Highlight(
  }
  
  float highlightcheck;
+ float would_backup;
  void HUD_Panel_Mouse()
  {
        // TODO: needs better check... is there any float that contains the current state of the menu? _menu_alpha isn't apparently updated the frame the menu gets enabled
  
        if(mouseClicked)
        {
+               vector prev_pos, prev_size;
                if(prevMouseClicked == 0)
+               {
                        HUD_Panel_Highlight(); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin
+                                                                       // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel
+                       would_backup = TRUE;
+               }
+               else if (would_backup)
+               {
+                       // this is not the actual backup! Saving pos and size values
+                       // only to check later if they are different from new values
+                       prev_pos = panel_pos;
+                       prev_size = panel_size;
+               }
  
                hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
  
                        HUD_Panel_SetPosSize(mySize);
                }
  
+               HUD_Panel_UpdatePosSizeForId(highlightedPanel)
+               if (prevMouseClicked)
+               if (would_backup)
+               if (prev_pos != panel_pos || prev_size != panel_size)
+               {
+                       // backup!
+                       panel_pos_backup = prev_pos;
+                       panel_size_backup = prev_size;
+                       highlightedPanel_backup = highlightedPanel;
+                       would_backup = FALSE;
+               }
                // doubleclick check
                if(time - prevMouseClickedTime < 0.4 && prevMouseClicked == 0 && prevMouseClickedPos == mousepos && highlightedPanel >= 0)
                {
@@@ -1391,14 -1484,52 +1490,52 @@@ void HUD_Weapons(void
        if(!autocvar_hud_panel_weapons && !autocvar__hud_configure)
                return;
  
+       float timeout = cvar("hud_panel_weapons_timeout");
+       float timeout_effect_lenght;
+       if (cvar("hud_panel_weapons_timeout_effect") == 0)
+               timeout_effect_lenght = 0;
+       else
+               timeout_effect_lenght = 0.75;
+       if (timeout && time >= weapontime + timeout + timeout_effect_lenght && !autocvar__hud_configure)
+               return;
        active_panel = HUD_PANEL_WEAPONS;
        HUD_Panel_UpdateCvars(weapons);
-       vector pos, mySize;
-       float i, weapid, fade, weapon_stats, weapon_number, weapon_cnt;
  
-       pos = panel_pos;
-       mySize = panel_size;
+       if (timeout && time >= weapontime + timeout && !autocvar__hud_configure)
+       {
+               float f = (time - (weapontime + timeout)) / timeout_effect_lenght;
+               if (cvar("hud_panel_weapons_timeout_effect") == 2)
+               {
+                       panel_bg_alpha *= (1 - f);
+                       panel_fg_alpha *= (1 - f);
+               }
+               else
+               {
+                       f *= f; // for a cooler movement
+                       vector center;
+                       center_x = panel_pos_x + panel_size_x/2;
+                       center_y = panel_pos_y + panel_size_y/2;
+                       float screen_ar = vid_conwidth/vid_conheight;
+                       if (center_x/center_y < screen_ar) //bottom left
+                       {
+                               if ((vid_conwidth - center_x)/center_y < screen_ar) //bottom
+                                       panel_pos_y += f * (vid_conheight - panel_pos_y);
+                               else //left
+                                       panel_pos_x -= f * (panel_pos_x + panel_size_x);
+                       }
+                       else //top right
+                       {
+                               if ((vid_conwidth - center_x)/center_y < screen_ar) //right
+                                       panel_pos_x += f * (vid_conwidth - panel_pos_x);
+                               else //top
+                                       panel_pos_y -= f * (panel_pos_y + panel_size_y);
+                       }
+               }
+       }
  
+       float i, weapid, fade, weapon_stats, weapon_number, weapon_cnt;
        weapon_cnt = 0;
        for(i = WEP_FIRST; i <= WEP_LAST; ++i)
        {
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
-               pos += '1 1 0' * panel_bg_padding;
-               mySize -= '2 2 0' * panel_bg_padding;
+               panel_pos += '1 1 0' * panel_bg_padding;
+               panel_size -= '2 2 0' * panel_bg_padding;
        }
  
        // hits
        HUD_Weapons_Clear();
  
        float rows, columns;
-       rows = mySize_y/mySize_x;
+       rows = panel_size_y/panel_size_x;
        rows = bound(1, floor((sqrt(4 * autocvar_hud_panel_weapons_aspect * rows * WEP_COUNT + rows * rows) + rows + 0.5) / 2), WEP_COUNT);
  
        columns = ceil(WEP_COUNT/rows);
  
        for(i = 0; i < weapon_cnt; ++i)
        {
-               wpnpos = pos + eX * column * mySize_x*(1/columns) + eY * row * mySize_y*(1/rows);
-               wpnsize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
+               wpnpos = panel_pos + eX * column * panel_size_x*(1/columns) + eY * row * panel_size_y*(1/rows);
+               wpnsize = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
  
                self = weaponorder[i];
                weapid = self.impulse;
                        drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL);
  
                        if(autocvar_hud_panel_weapons_label == 1) // weapon number
-                               drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * mySize_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+                               drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                        else if(autocvar_hud_panel_weapons_label == 2) // bind
-                               drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * mySize_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+                               drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
  
                        // draw ammo status bar
                        if(autocvar_hud_panel_weapons_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO)
@@@ -1851,10 -1982,17 +1988,17 @@@ void HUD_Powerups(void) 
        pos = panel_pos;
        mySize = panel_size;
  
-       float strength_time, shield_time;
-       strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99);
-       shield_time = bound(0, getstatf(STAT_INVINCIBLE_FINISHED) - time, 99);
+       float strength_time, shield_time;
+       if(autocvar__hud_configure)
+       {
+               strength_time = 15;
+               shield_time = 27;
+       }
+       else
+       {
+               strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99);
+               shield_time = bound(0, getstatf(STAT_INVINCIBLE_FINISHED) - time, 99);
+       }
  
        HUD_Panel_DrawBg(bound(0, max(strength_time, shield_time), 1));
        if(panel_bg_padding)
                mySize -= '2 2 0' * panel_bg_padding;
        }
  
-       if(autocvar__hud_configure)
-       {
-               strength_time = 15;
-               shield_time = 27;
-       }
        vector barpos, barsize;
        vector picpos;
        vector numpos;
@@@ -2479,13 -2611,8 +2617,13 @@@ void HUD_KillNotify(string s1, string s
                else if(type == KILL_FIRST_BLOOD)
                        print("^1",s1, "^1 drew first blood", "\n");
                // TODO: icon!
 -              else if (type == DEATH_TELEFRAG)
 -                      print ("^1",s1, "^1 was telefragged by ", s2, "\n");
 +              else if (type == DEATH_TELEFRAG) {
 +                      HUD_KillNotify_Push(s2, s1, 1, DEATH_TELEFRAG);
 +                      if(gentle)
 +                              print ("^1",s1, "^1 tried to occupy ", s2, "^1's teleport destination space\n");
 +                      else
 +                              print ("^1",s1, "^1 was telefragged by ", s2, "\n");
 +              }
                else if (type == DEATH_DROWN) {
                        HUD_KillNotify_Push(s2, s1, 1, DEATH_DROWN);
                        if(alsoprint)
@@@ -2763,7 -2890,7 +2901,7 @@@ void HUD_Centerprint(string s1, string 
                                centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^1Don't shoot your team mates!"));
                } else if (type == DEATH_QUIET) {
                        // do nothing
 -              } else if (type == DEATH_KILL) {
 +              } else { // generic message
                        if(gentle)
                                centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^1You need to be more careful!"));
                        else
                        } else {
                                centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^4You fragged ^7", s1, s2));
                        }
 -              } else if (type == KILL_FRAGGED) {
 +              } else { // generic message
                        if(gentle) {
                                centerprint(strcat(DAMAGE_CENTERPRINT_SPACER, "^1You were scored against by ^7", s1, s2));
                        } else {
@@@ -2857,7 -2984,7 +2995,7 @@@ void HUD_Notify (void
        float width_attacker;
        string attacker, victim;
  
 -      float i, j;
 +      float i, j, w;
        for(j = 0; j < entries; ++j)
        {
                s = "";
                                a = 0;
                }
  
 -              float w;
 +              w = -1;
                w = DEATH_WEAPONOF(killnotify_deathtype[j]);
  
                // TODO: maybe print in team colors?
                        {
                                s = "notify_teamkill_red";
                        }
 +                      else if(killnotify_deathtype[j] == DEATH_TELEFRAG)
 +                      {
 +                              s = "notify_telefrag";
 +                      }
                        else if(killnotify_deathtype[j] == DEATH_DROWN)
                        {
                                s = "notify_water";
@@@ -4398,12 -4521,6 +4536,12 @@@ void HUD_InfoMessages(void
        vector fontsize;
        fontsize = '0.20 0.20 0' * mySize_y;
        
 +      float a;
 +      if(spectatee_status != 0)
 +              a = 1;
 +      else
 +              a = panel_fg_alpha;
 +
        string s;
        if(!autocvar__hud_configure)
        {
  
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
  
                        if(spectatee_status == -1)
                                s = strcat("^1Press ^3", getcommandkey("primary fire", "+attack"), "^1 for another player");
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
  
                        if(spectatee_status == -1)
                                s = strcat("^1Press ^3", getcommandkey("secondary fire", "+attack2"), "^1 to observe");
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
  
                        s = strcat("^1Press ^3", getcommandkey("server info", "+show_info"), "^1 for gamemode info");
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
  
                        if(gametype == GAME_ARENA)
                                s = strcat("^1Press ^3", getcommandkey("jump", "+jump"), "^1 to join");
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
  
                        //show restart countdown:
                                //we need to ceil, otherwise the countdown would be off by .5 when using round()
                                countdown = ceil(getstatf(STAT_GAMESTARTTIME) - time);
                                s = strcat("^1Game starts in ^3", ftos(countdown), "^1 seconds");
 -                              drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                                o += eY * fontsize_y;
                        }
                }
                        s = "^2Currently in ^1warmup^2 stage!";
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
                }
  
                        }
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
                }
                else if(warmup_stage && !intermission && !spectatee_status)
                        s = strcat("^2Press ^3", getcommandkey("ready", "ready"), "^2 to end warmup");
                        if(autocvar_hud_panel_infomessages_flip)
                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                        o += eY * fontsize_y;
                }
  
  
                                        if(autocvar_hud_panel_infomessages_flip)
                                                o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -                                      drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                                        o += eY * fontsize_y;
                                }
                        }
                s = "^7Press ^3ESC ^7to show HUD options.";
                if(autocvar_hud_panel_infomessages_flip)
                        o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -              drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                o += eY * fontsize_y;
                s = "^3Doubleclick ^7a panel for panel-specific options.";
                if(autocvar_hud_panel_infomessages_flip)
                        o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -              drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                o += eY * fontsize_y;
                s = "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and";
                if(autocvar_hud_panel_infomessages_flip)
                        o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -              drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                o += eY * fontsize_y;
                s = "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments.";
                if(autocvar_hud_panel_infomessages_flip)
                        o_x = pos_x + mySize_x - stringwidth(s, TRUE, fontsize); 
 -              drawcolorcodedstring(o, s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              drawcolorcodedstring(o, s, fontsize, a, DRAWFLAG_NORMAL);
                o += eY * fontsize_y;
        }
  }
@@@ -4724,19 -4841,10 +4862,19 @@@ void HUD_Main (void
  {
        hud_skin_path = strcat("gfx/hud/", autocvar_hud_skin);
  
 +      // global hud alpha fade
        if(disable_menu_alphacheck == 1)
 -              menu_fade_alpha = 1;
 +              hud_fade_alpha = 1;
        else
 -              menu_fade_alpha = (1 - autocvar__menu_alpha);
 +              hud_fade_alpha = (1 - autocvar__menu_alpha);
 +
 +      if(scoreboard_fade_alpha)
 +              hud_fade_alpha = (1 - scoreboard_fade_alpha);
 +
 +      if(intermission == 2) // no hud during mapvote
 +              hud_fade_alpha = 0;
 +      else if(autocvar__menu_alpha == 0 && scoreboard_fade_alpha == 0)
 +              hud_fade_alpha = 1;
  
        hud_border_thickness = bound(0, cvar("hud_border_thickness"), 5);
        hud_accuracy_border_thickness = bound(0, cvar_or("hud_accuracy_border_thickness", 1), 5);
                if(precache_pic(pic) == "") {
                        pic = "gfx/hud/default/dock";
                }
 -              drawpic('0 0 0', pic, eX * vid_conwidth + eY * vid_conheight, color, autocvar_hud_dock_alpha * menu_fade_alpha, DRAWFLAG_NORMAL); // no aspect ratio forcing on dock...
 +              drawpic('0 0 0', pic, eX * vid_conwidth + eY * vid_conheight, color, autocvar_hud_dock_alpha * hud_fade_alpha, DRAWFLAG_NORMAL); // no aspect ratio forcing on dock...
        }
  
        // cache the panel order into the panel_order array
diff --combined qcsrc/client/hud.qh
index 3c1f27107f47b6b73b904ae368f8cc93fbe7022c,2b5394c163541c09edb9628bf411ed4629dc8f8c..e416da62aee32babca9ad8e437e039eda9c74575
@@@ -1,7 -1,5 +1,7 @@@
  float log(float f);
  
 +vector centerprint_start;
 +
  float panel_order[HUD_PANEL_NUM];
  string hud_panelorder_prev;
  
@@@ -48,12 -46,19 +48,19 @@@ const float S_CTRL = 2
  const float S_ALT = 4;
  
  float disable_menu_alphacheck; // 0 = enable alpha check, 1 = disable for entire hud, 2 = disable for one panel
 -float menu_fade_alpha;
 +float hud_fade_alpha;
  
  string hud_skin_path;
  
  var vector progressbar_color;
  
+ var float highlightedPanel_backup = -1;
+ var vector panel_pos_backup;
+ var vector panel_size_backup;
+ var float highlightedPanel_copied = -1; //this is good only to know if there is something copied
+ var vector panel_size_copied;
  var float active_panel; // this panel has recently referred the UpdateCvars macro
  var string panel_name;
  var float panel_enabled;
@@@ -164,7 -169,7 +171,7 @@@ if(autocvar__hud_configure && disable_m
  } if(autocvar__hud_configure && !panel_enabled) {\
        panel_bg_alpha = 0.25;\
  } if(!(disable_menu_alphacheck == 2 && highlightedPanel == active_panel)) {\
 -      panel_bg_alpha *= menu_fade_alpha;\
 +      panel_bg_alpha *= hud_fade_alpha;\
  }
  
  // Get value for panel_fg_alpha. Also do various minalpha checks
@@@ -175,7 -180,7 +182,7 @@@ panel_fg_alpha = autocvar_hud_panel_fg_
  if(autocvar__hud_configure && !panel_enabled)\
        panel_fg_alpha = 0.25;\
  if(!(disable_menu_alphacheck == 2 && highlightedPanel == active_panel))\
 -      panel_fg_alpha *= menu_fade_alpha;
 +      panel_fg_alpha *= hud_fade_alpha;
  
  // Get border. See comments above, it's similar.
  #define HUD_Panel_GetBorder()\
index 0bebff3687b83114fe52f40ff2b2b1e1cd220403,02698745083654f3b71b0da7579ebf3b634b5ded..cc94efb6e40aec290d834e42223431b0b45ae084
@@@ -45,54 -45,54 +45,54 @@@ void restartAnnouncer_Think() 
   * Plays the 1minute or 5 minutes (of maptime) remaining sound, if client wants it
   */
  void maptimeAnnouncer() {
-     float timelimit;
-     timelimit = getstatf(STAT_TIMELIMIT);
-     float timeleft;
-     timeleft = max(0, timelimit * 60 + getstatf(STAT_GAMESTARTTIME) - time);
-     float warmuplimit;
-     float warmuptimeleft;
-     if(warmup_stage) {
-         warmuplimit = cvar("g_warmup_limit");
-         if(warmuplimit > 0) {
-            warmuptimeleft = max(0, warmuplimit + getstatf(STAT_GAMESTARTTIME) - time); 
-         }
-     }
-     //5 minute check
-     if (cvar("cl_sound_maptime_warning") >= 2) {
-         //make sure that after connect (and e.g. 4 minutes left) we will not get a wrong sound
-         if(announcer_5min)
-         {
+       float timelimit;
+       timelimit = getstatf(STAT_TIMELIMIT);
+       float timeleft;
+       timeleft = max(0, timelimit * 60 + getstatf(STAT_GAMESTARTTIME) - time);
+       float warmuplimit;
+       float warmuptimeleft;
+       if(warmup_stage) {
+               warmuplimit = cvar("g_warmup_limit");
+               if(warmuplimit > 0) {
+                       warmuptimeleft = max(0, warmuplimit + getstatf(STAT_GAMESTARTTIME) - time); 
+               }
+       }
+       //5 minute check
+       if (cvar("cl_sound_maptime_warning") >= 2) {
+               //make sure that after connect (and e.g. 4 minutes left) we will not get a wrong sound
+               if(announcer_5min)
+               {
                        if(((!warmup_stage || warmuplimit == 0) && timeleft > 300) || (warmup_stage && warmuplimit > 0 && warmuptimeleft > 300))
                                announcer_5min = FALSE;
-         }
-         else if (((!warmup_stage || warmuplimit == 0) && timelimit > 0 && timeleft < 300 && timeleft > 299) || (warmup_stage && warmuplimit > 0 && warmuptimeleft < 300 && warmuptimeleft > 299))
-       //if we're in warmup mode, check whether there's a warmup timelimit
-         if not (warmuplimit == -1 && warmup_stage) {
-                       announcer_5min = TRUE;
-                       //dprint("i will play the sound, I promise!\n");
-                       sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/5minutesremain.wav"), VOL_BASEVOICE, ATTN_NONE);
                }
-     }
+               else if (((!warmup_stage || warmuplimit == 0) && timelimit > 0 && timeleft < 300 && timeleft > 299) || (warmup_stage && warmuplimit > 0 && warmuptimeleft < 300 && warmuptimeleft > 299))
+                       //if we're in warmup mode, check whether there's a warmup timelimit
+                       if not (warmuplimit == -1 && warmup_stage) {
+                               announcer_5min = TRUE;
+                               //dprint("i will play the sound, I promise!\n");
+                               sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/5minutesremain.wav"), VOL_BASEVOICE, ATTN_NONE);
+                       }
+       }
  
-     //1 minute check
-     if (cvar("cl_sound_maptime_warning") == 1 || cvar("cl_sound_maptime_warning") == 3) {
-       if (announcer_1min)
-       {
+       //1 minute check
+       if (cvar("cl_sound_maptime_warning") == 1 || cvar("cl_sound_maptime_warning") == 3) {
+               if (announcer_1min)
+               {
                        if(((!warmup_stage || warmuplimit == 0) && timeleft > 60) || (warmup_stage && warmuplimit > 0 && warmuptimeleft > 60))
                                announcer_1min = FALSE;
-       }
-       else if (((!warmup_stage || warmuplimit == 0) && timelimit > 0 && timeleft < 60) || (warmup_stage && warmuplimit > 0 && warmuptimeleft < 60))
-       //if we're in warmup mode, check whether there's a warmup timelimit
-       if not (warmuplimit == -1 && warmup_stage) {
-                       announcer_1min = TRUE;
-                       sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/1minuteremains.wav"), VOL_BASEVOICE, ATTN_NONE);
-       }
+               }
+               else if (((!warmup_stage || warmuplimit == 0) && timelimit > 0 && timeleft < 60) || (warmup_stage && warmuplimit > 0 && warmuptimeleft < 60))
+                       //if we're in warmup mode, check whether there's a warmup timelimit
+                       if not (warmuplimit == -1 && warmup_stage) {
+                               announcer_1min = TRUE;
+                               sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/1minuteremains.wav"), VOL_BASEVOICE, ATTN_NONE);
+                       }
        }
  }
  
 /**
+ /**
   * Announce carried items (e.g. flags in CTF).
   */
  float redflag_prev;
@@@ -181,6 -181,10 +181,10 @@@ void Announcer_Precache () 
  
        precache_sound (strcat("announcer/", cvar_string("cl_announcer"), "/lastsecond.wav"));
        precache_sound (strcat("announcer/", cvar_string("cl_announcer"), "/narrowly.wav"));
+       precache_sound (strcat("announcer/", cvar_string("cl_announcer"), "/voteaccept.wav"));
+       precache_sound (strcat("announcer/", cvar_string("cl_announcer"), "/votecall.wav"));
+       precache_sound (strcat("announcer/", cvar_string("cl_announcer"), "/votefail.wav"));
  }
  
  void AuditLists()
@@@ -320,6 -324,19 +324,6 @@@ vector HUD_GetFontsize(string cvarname
        return v;
  }
  
 -float HUD_GetWidth(float teamcolumnwidth)
 -{
 -      float f;
 -      f = cvar("hud_width");
 -      if(f == 0)
 -              f = 640;
 -      if(f < 320)
 -              f = 320;
 -      if(f > vid_conwidth - 2 * teamcolumnwidth)
 -              f = vid_conwidth - 2 * teamcolumnwidth;
 -      return f;
 -}
 -
  float PreviewExists(string name)
  {
        float f;
@@@ -459,41 -476,41 +463,41 @@@ void drawpic_tiled(vector pos, string p
  var float imgaspect;
  var float aspect;
  #define drawpic_aspect(pos,pic,mySize,color,alpha,drawflag)\
- do {\
-       vector imgsize;\
-       imgsize = drawgetimagesize(pic);\
-       imgaspect = imgsize_x/imgsize_y;\
-       vector oldsz, sz;\
-       oldsz = sz = mySize;\
-       aspect = sz_x/sz_y;\
-       if(aspect > imgaspect) {\
-               sz_x = sz_y * imgaspect;\
-               drawpic(pos + eX * (oldsz_x - sz_x) * 0.5, pic, sz, color, alpha, drawflag);\
-       } else {\
-               sz_y = sz_x / imgaspect;\
-               drawpic(pos + eY * (oldsz_y - sz_y) * 0.5, pic, sz, color, alpha, drawflag);\
-       }\
- } while(0)
      do {\
+               vector imgsize;\
+               imgsize = drawgetimagesize(pic);\
+               imgaspect = imgsize_x/imgsize_y;\
+               vector oldsz, sz;\
+               oldsz = sz = mySize;\
+               aspect = sz_x/sz_y;\
+               if(aspect > imgaspect) {\
+                       sz_x = sz_y * imgaspect;\
+                       drawpic(pos + eX * (oldsz_x - sz_x) * 0.5, pic, sz, color, alpha, drawflag);\
+               } else {\
+                       sz_y = sz_x / imgaspect;\
+                       drawpic(pos + eY * (oldsz_y - sz_y) * 0.5, pic, sz, color, alpha, drawflag);\
+               }\
      } while(0)
  
  // draw HUD element with image from gfx/hud/hud_skin/foo.tga if it exists, otherwise gfx/hud/default/foo.tga
  #define drawpic_aspect_skin(pos,pic,sz,color,alpha,drawflag)\
- do{\
-       picpath = strcat(hud_skin_path, "/", pic);\
-       if(precache_pic(picpath) == "") {\
-               picpath = strcat("gfx/hud/default/", pic);\
-       }\
-       drawpic_aspect(pos, picpath, sz, color, alpha, drawflag);\
- } while(0)
      do{\
+               picpath = strcat(hud_skin_path, "/", pic);\
+               if(precache_pic(picpath) == "") {\
+                       picpath = strcat("gfx/hud/default/", pic);\
+               }\
+               drawpic_aspect(pos, picpath, sz, color, alpha, drawflag);\
      } while(0)
  
  // draw HUD element with image from gfx/hud/hud_skin/foo.tga if it exists, otherwise gfx/hud/default/foo.tga
  #define drawpic_skin(pos,pic,sz,color,alpha,drawflag)\
- do{\
-       picpath = strcat(hud_skin_path, "/", pic);\
-       if(precache_pic(picpath) == "") {\
-               picpath = strcat("gfx/hud/default/", pic);\
-       }\
-       drawpic(pos, picpath, sz, color, alpha, drawflag);\
- } while(0)
      do{\
+               picpath = strcat(hud_skin_path, "/", pic);\
+               if(precache_pic(picpath) == "") {\
+                       picpath = strcat("gfx/hud/default/", pic);\
+               }\
+               drawpic(pos, picpath, sz, color, alpha, drawflag);\
      } while(0)
  
  void drawpic_aspect_skin_expanding(vector position, string pic, vector scale, vector rgb, float alpha, float flag, float fadelerp)
  {
@@@ -513,7 -530,7 +517,7 @@@ void drawpic_aspect_skin_expanding_two(
  void drawstring_aspect(vector pos, string text, vector sz, vector color, float alpha, float drawflag) {
        vector textsize;
        textsize = eX * stringwidth(text, FALSE, '1 1 1' * sz_y) + eY * sz_y;
-       
        float textaspect;
        textaspect = textsize_x/textsize_y;
  
  void drawcolorcodedstring_aspect(vector pos, string text, vector sz, float alpha, float drawflag) {
        vector textsize;
        textsize = eX * stringwidth(text, TRUE, '1 1 1' * sz_y) + eY * sz_y;
-       
        float textaspect;
        textaspect = textsize_x/textsize_y;
  
@@@ -561,7 -578,7 +565,7 @@@ void drawstring_expanding(vector positi
  
        drawfontscale = sz * '1 1 0';
        dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
-         drawstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, FALSE, scale * (sz / drawfontscale_x)) / (scale_x * sz)), text, scale * (sz / drawfontscale_x), rgb, alpha * (1 - fadelerp), flag);
+       drawstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, FALSE, scale * (sz / drawfontscale_x)) / (scale_x * sz)), text, scale * (sz / drawfontscale_x), rgb, alpha * (1 - fadelerp), flag);
        // width parameter:
        //    (scale_x * sz / drawfontscale_x) * drawfontscale_x * SIZE1 / (scale_x * sz)
        //    SIZE1
  void drawstring_aspect_expanding(vector pos, string text, vector sz, vector color, float alpha, float drawflag, float fadelerp) {
        vector textsize;
        textsize = eX * stringwidth(text, FALSE, '1 1 1' * sz_y) + eY * sz_y;
-       
        float textaspect;
        textaspect = textsize_x/textsize_y;