]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/newpanelhud
authorterencehill <piuntn@gmail.com>
Wed, 15 Dec 2010 23:09:08 +0000 (00:09 +0100)
committerterencehill <piuntn@gmail.com>
Wed, 15 Dec 2010 23:09:08 +0000 (00:09 +0100)
Conflicts:
qcsrc/client/scoreboard.qc

1  2 
defaultXonotic.cfg
qcsrc/client/hud.qc
qcsrc/client/scoreboard.qc
qcsrc/common/util.qh

diff --combined defaultXonotic.cfg
index 620711f5181951e4b50dd77be330528ac61394ef,57ae352abaebb949fb1dd92bb52d8ff0d74d44ee..d5c7d0c907cbe1d75ff0bf4e4abb6cf4b2f6a0d5
@@@ -387,25 -387,6 +387,6 @@@ set ekg 0 "Throw huge amounts of gibs
  
  cl_movement 1
  cl_stairsmoothspeed 200
- cl_forwardspeed $sv_maxspeed
- cl_backspeed $sv_maxspeed
- cl_sidespeed $sv_maxspeed
- cl_upspeed $sv_maxspeed
- cl_movement_accelerate $sv_accelerate
- cl_movement_airaccel_qw $sv_airaccel_qw
- cl_movement_airaccel_sideways_friction $sv_airaccel_sideways_friction
- cl_movement_airaccelerate $sv_airaccelerate
- cl_movement_edgefriction $edgefriction
- cl_movement_friction $sv_friction
- cl_movement_jumpvelocity $sv_jumpvelocity
- cl_movement_maxairspeed $sv_maxairspeed
- cl_movement_maxspeed $sv_maxspeed
- cl_movement_stepheight $sv_stepheight
- cl_movement_stopspeed $sv_stopspeed
- cl_movement_track_canjump 0 // till DP bug gets fixed
- cl_movement_wallfriction $sv_wallfriction
- cl_movement_wateraccelerate $sv_wateraccelerate
- cl_movement_waterfriction $sv_waterfriction
  
  seta cl_autoswitch 1 "automatically switch to newly picked up weapons if they are better than what you are carrying"
  alias autoswitch "set cl_autoswitch $1 ; cmd autoswitch $1"
@@@ -437,9 -418,9 +418,9 @@@ set bot_ai_keyboard_treshold 0.5
  set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
  set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
  set bot_ai_custom_weapon_priority_distances "300 850" "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
- set bot_ai_custom_weapon_priority_far   "minstanex nex campingrifle rocketlauncher minelayer grenadelauncher electro hagar hlac crylink laser uzi fireball seeker shotgun tuba"       "Desired weapons for far distances ordered by priority"
- set bot_ai_custom_weapon_priority_mid   "minstanex rocketlauncher nex fireball seeker minelayer grenadelauncher electro uzi campingrifle crylink hlac hagar shotgun laser tuba"       "Desired weapons for middle distances ordered by priority"
- set bot_ai_custom_weapon_priority_close "minstanex nex uzi hlac tuba seeker hagar crylink minelayer grenadelauncher shotgun electro campingrifle rocketlauncher laser fireball"       "Desired weapons for close distances ordered by priority"
+ set bot_ai_custom_weapon_priority_far   "minstanex nex campingrifle electro rocketlauncher grenadelauncher hagar hlac crylink laser uzi fireball seeker shotgun tuba minelayer"       "Desired weapons for far distances ordered by priority"
+ set bot_ai_custom_weapon_priority_mid   "minstanex rocketlauncher nex fireball seeker grenadelauncher electro uzi campingrifle crylink hlac hagar shotgun laser tuba minelayer"       "Desired weapons for middle distances ordered by priority"
+ set bot_ai_custom_weapon_priority_close "minstanex shotgun nex uzi hlac tuba seeker hagar crylink grenadelauncher electro campingrifle rocketlauncher laser fireball minelayer"       "Desired weapons for close distances ordered by priority"
  set bot_ai_weapon_combo 1     "Enable bots to do weapon combos"
  set bot_ai_weapon_combo_threshold 0.3 "Try to make a combo N seconds after the last attack"
  set bot_ai_friends_aware_pickup_radius "500"  "Bots will not pickup items if a team mate is this distance near the item"
@@@ -596,40 -577,56 +577,56 @@@ set g_respawn_waves 0 "respawn in wave
  // to force disable delay or waves, set them to 0.125
  set g_ctf_respawn_delay 0
  set g_ctf_respawn_waves 0
+ set g_ctf_weapon_stay 0
  set g_dm_respawn_delay 0
  set g_dm_respawn_waves 0
+ set g_dm_weapon_stay 0
  set g_dom_respawn_delay 0
  set g_dom_respawn_waves 0
+ set g_dom_weapon_stay 0
  set g_lms_respawn_delay 0
  set g_lms_respawn_waves 0
+ set g_lms_weapon_stay 0
  set g_rune_respawn_delay 0
  set g_rune_respawn_waves 0
+ set g_rune_weapon_stay 0
  set g_tdm_respawn_delay 0
  set g_tdm_respawn_waves 0
+ set g_tdm_weapon_stay 0
  set g_kh_respawn_delay 0
  set g_kh_respawn_waves 0
+ set g_kh_weapon_stay 0
  set g_arena_respawn_delay 0
  set g_arena_respawn_waves 0
+ set g_arena_weapon_stay 0
  set g_ca_respawn_delay 0
  set g_ca_respawn_waves 0
+ set g_ca_weapon_stay 0
  set g_ca_damage2score_multiplier 0.01
  set g_ca_round_timelimit 180
  set g_nexball_respawn_delay 0
  set g_nexball_respawn_waves 0
+ set g_nexball_weapon_stay 0
  set g_as_respawn_delay 0
  set g_as_respawn_waves 0
+ set g_as_weapon_stay 0
  set g_ons_respawn_delay 0
  set g_ons_respawn_waves 0
+ set g_ons_weapon_stay 0
  set g_rc_respawn_waves 0
  set g_rc_respawn_delay 0
+ set g_rc_weapon_stay 0
  set g_cts_respawn_waves 0
- set g_cts_respawn_delay 0.25
+ set g_cts_respawn_delay 0
  set g_cts_selfdamage 1 "0 = disable all selfdamage and falldamage in cts"
  set g_cts_finish_kill_delay 10 "prevent cheating by running back to the start line, and starting out with more speed than otherwise possible"
+ set g_cts_weapon_stay 1
  set g_freezetag_respawn_waves 0
- set g_freezetag_respawn_delay 0.25
+ set g_freezetag_respawn_delay 0
+ set g_freezetag_weapon_stay 0
  set g_ka_respawn_delay 0
  set g_ka_respawn_waves 0
+ set g_ka_weapon_stay 0
  
  // overtime
  seta timelimit_overtime 2 "duration in minutes of one added overtime, added to the timelimit"
@@@ -1409,23 -1406,12 +1406,23 @@@ seta hud_panel_radar_rotation 0      "rotati
  seta hud_panel_radar_zoommode 0       "zoom mode: 0 = zoomed by default, 1 = zoomed when +zoom, 2 = always zoomed, 3 = always zoomed out"
  alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4"
  
 +seta hud_panel_score_rankings 0 "show rankings in non-team games instead of the score difference: 1 always show my own score; 2 pure rankings"
 +
  seta hud_panel_engineinfo_framecounter_time 0.1 "time between framerate display updates"
  seta hud_panel_engineinfo_framecounter_decimals 0 "amount of decimals to show"
  seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averaging method for calculating fps instead of counting frametime like engine does"
  seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight 0.1 "weight of latest data point"
  seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold 0.5 "threshold for fps change when to update instantly, to make big fps changes update faster"
  
 +seta hud_panel_physics_speed_unit 3 "speed unit (1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots)"
 +seta hud_panel_physics_speed_unit_show 1 "also show speed unit"
 +seta hud_panel_physics_speed_max 1800 "speed progressbar gets filled up completely by this value (in qu/s)"
 +seta hud_panel_physics_speed_z 0 "include the speed on the Z-axis"
 +seta hud_panel_physics_topspeed 1 "also show top speed"
 +seta hud_panel_physics_topspeed_time 4 "how many seconds the top speed takes to fade out"
 +seta hud_panel_physics_acceleration_max 2 "acceleration progressbar gets filled up completely by this value"
 +seta hud_panel_physics_acceleration_z 0 "include the acceleration on the Z-axis"
 +
  seta hud_showbinds 1  "the way to show the keys to press in HUD messages: 0 displays commands, 1 bound keys, 2 both"
  seta hud_showbinds_limit 2    "maximum number of bound keys to show for a command. 0 for unlimited"
  
@@@ -1549,7 -1535,8 +1546,8 @@@ sv_gameplayfix_q2airaccelerate 
  sv_gameplayfix_stepmultipletimes 1
  
  // delay for "kill" to prevent abuse
- set g_balance_kill_delay 5
+ set g_balance_kill_delay 2
+ set g_balance_kill_antispam 5
  
  // this feature is currently buggy in the engine (it appears to PREVENT any dropping in lots of maps, leading to weirdly aligned entities, and in some cases even CAUSES them to drop through solid, like in facing worlds nex)
  sv_gameplayfix_droptofloorstartsolid 0
@@@ -1637,7 -1624,7 +1635,7 @@@ if_dedicated set g_start_delay 15       "dela
  
  alias ons_map           "cl_cmd radar" // legacy alias
  alias radar             "cl_cmd radar"
- alias scoreboard_columns_set  "cl_cmd scoreboard_columns_set $*"
+ alias scoreboard_columns_set  "" // aliased later
  alias scoreboard_columns_help "cl_cmd scoreboard_columns_help $*"
  
  alias _gl_flashblend_update_00 "gl_flashblend 1"
@@@ -1655,7 -1642,6 +1653,6 @@@ set cl_handicap 1       "the higher, the mor
  alias menu_showteamselect "menu_cmd directmenu TeamSelect"
  alias menu_showhudexit "menu_cmd directmenu HUDExit"
  alias menu_showhudoptions "menu_cmd directpanelhudmenu $*"
- alias menu_sync "menu_cmd sync"
  bind f5 menu_showteamselect
  
  set g_bugrigs 0
@@@ -1750,6 -1736,25 +1747,6 @@@ seta cl_gentle_gibs 0          "client side gen
  seta cl_gentle_messages 0     "client side gentle mode (only replaces frag messages/centerprints)"
  seta cl_gentle_damage 0               "client side gentle mode (only replaces damage flash); when set to 1, a white flash replaces the blood image, when set to 2, a randomily colored flash is used instead"
  
 -seta cl_racetimer_position 0.25 "Y-axis positioning of the race timer (from 0 to 1)"
 -seta cl_showpressedkeys       0       "Show which movement keys someone is pressing: 1 for spectating, 2 for always"
 -seta cl_showpressedkeys_position "0.5 0.8"    "1 0 would be upper right corner, 0.5 0.5 the center"
 -
 -seta cl_showspeed 0 "show the XY speed of the player"
 -seta cl_showspeed_unit 0 "unit selection (0 = qu/s (no postfix), 1 = qu/s, 2 = m/s, 3 = km/h, 4 = mph, 5 = knots)"
 -seta cl_showspeed_z 0 "include the speed on the Z-axis"
 -seta cl_showspeed_size 30 "size of the numbers"
 -seta cl_showspeed_position 0.7 "Y-axis positioning of the numbers"
 -
 -seta cl_showacceleration 0 "show the XY acceleration of the player"
 -seta cl_showacceleration_z 0 "include the speed on the Z-axis"
 -seta cl_showacceleration_size 40 "height of the bar"
 -seta cl_showacceleration_scale 1 "X-axis scale of the bar"
 -seta cl_showacceleration_alpha 0.5 "alpha of the bar"
 -seta cl_showacceleration_color_custom 0 "0 = dynamic color depending on acceleration, 1 = use custom color"
 -seta cl_showacceleration_color "1 0 0" "color of the bar, needs cl_showacceleration_color_custom to be 1"
 -seta cl_showacceleration_position 0.6 "Y-axis positioning of the bar"
 -
  set g_jetpack 0 "Jetpack mutator (uses the hook's button, can't coexist with the offhand hook, but only with the onhand one)"
  
  set g_running_guns 0 "... or wonder, till it drives you mad, what would have followed if you had."
@@@ -1977,6 -1982,7 +1974,7 @@@ scr_loadingscreen_background 
  scr_loadingscreen_barcolor "0 0.5 1"
  scr_loadingscreen_barheight 20
  scr_loadingscreen_count 1
+ scr_conforcewhiledisconnected 0
  
  // DP cannot properly detect this, so rather turn off the detection
  r_texture_dds_load_dxt1_noalpha 1
@@@ -2056,15 -2062,25 +2054,25 @@@ set g_playerstats_uri "
  // create this cvar in case the engine did not
  set snd_soundradius 1200
  
+ // loading screen
+ scr_loadingscreen_scale 1
+ scr_loadingscreen_scale_base 1
+ scr_loadingscreen_scale_limit 1
  // other config files
  exec balanceXonotic.cfg
  exec ctfscoring-ai.cfg
  exec effects-normal.cfg
  exec physicsX0.cfg
  exec turrets.cfg
+ exec font-nimbussansl.cfg
  
  // hud cvar descriptions
  exec _hud_descriptions.cfg
  // exec the default skin config
  // please add any new cvars into the hud_save script in qcsrc/client/hud.qc for consistency
  exec hud_luminos.cfg
+ // enable menu syncing
+ alias menu_sync "menu_cmd sync"
+ alias scoreboard_columns_set  "cl_cmd scoreboard_columns_set $*"
diff --combined qcsrc/client/hud.qc
index 51015fe6ab631f12d6cd02d02b9447be0732e5c0,476eb607e48b6be0b28f05bba4a7aeef19d6e532..0910c7a7811281be2484eaa6bb436cff89721de8
@@@ -498,6 -498,7 +498,7 @@@ void HUD_Panel_ExportCfg(string cfgname
                                        HUD_Write_PanelCvar_q("_iconalign");
                                        HUD_Write_PanelCvar_q("_progressbar");
                                        HUD_Write_PanelCvar_q("_progressbar_name");
+                                       HUD_Write_PanelCvar_q("_progressbar_xoffset");
                                        HUD_Write_PanelCvar_q("_text");
                                        break;
                                case HUD_PANEL_POWERUPS:
                                case HUD_PANEL_INFOMESSAGES:
                                        HUD_Write_PanelCvar_q("_flip");
                                        break;
 +                              case HUD_PANEL_PHYSICS:
 +                                      HUD_Write_PanelCvar_q("_flip");
 +                                      HUD_Write_PanelCvar_q("_baralign");
 +                                      HUD_Write_PanelCvar_q("_progressbar");
 +                                      break;
                        }
                        HUD_Write("\n");
                }
@@@ -566,80 -562,42 +567,80 @@@ void HUD_Panel_HlBorder(float myBorder
  #define HUD_Panel_DrawBg(alpha)\
  if(panel_bg != "0")\
        draw_BorderPicture(panel_pos - '1 1 0' * panel_bg_border, panel_bg, panel_size + '1 1 0' * 2 * panel_bg_border, panel_bg_color, panel_bg_alpha * alpha, '1 1 0' * (panel_bg_border/BORDER_MULTIPLIER));\
 -if(highlightedPanel_prev == active_panel && autocvar__hud_configure)\
 +if(highlightedPanel == hud_configure_active_panel && autocvar__hud_configure)\
  {\
        HUD_Panel_HlBorder(panel_bg_border + 1.5 * hlBorderSize, '0 0.5 1', 0.25 * (1 - autocvar__menu_alpha) * alpha);\
  } ENDS_WITH_CURLY_BRACE
  
 -void HUD_Panel_DrawProgressBar(vector pos, vector mySize, string pic, float vertical, float barflip, float x, vector color, float alpha, float drawflag)
 +//basically the same code of draw_ButtonPicture and draw_VertButtonPicture for the menu
 +void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float lenght_ratio, float vertical, float right_align, vector theColor, float theAlpha, float drawflag)
  {
 -      if(!alpha || x == 0)
 +      if(lenght_ratio <= 0 || !theAlpha)
                return;
 +      if(lenght_ratio > 1)
 +              lenght_ratio = 1;
  
 -    x = bound(0, x, 1);
 -
 +      vector square;
 +      vector width, height;
        if(vertical) {
                pic = strcat(hud_skin_path, "/", pic, "_vertical");
                if(precache_pic(pic) == "") {
                        pic = "gfx/hud/default/statusbar_vertical";
                }
  
 -        if(barflip)
 -            drawsetcliparea(pos_x, pos_y + mySize_y * (1 - x), mySize_x, mySize_y * x);
 -        else
 -            drawsetcliparea(pos_x, pos_y, mySize_x, mySize_y * x);
 +              if (right_align)
 +                      theOrigin_y += (1 - lenght_ratio) * theSize_y;
 +              theSize_y *= lenght_ratio;
 +
 +              vector bH;
 +              width = eX * theSize_x;
 +              height = eY * theSize_y;
 +              if(theSize_y <= theSize_x * 2)
 +              {
 +                      // button not high enough
 +                      // draw just upper and lower part then
 +                      square = eY * theSize_y * 0.5;
 +                      bH = eY * (0.25 * theSize_y / (theSize_x * 2));
 +                      drawsubpic(theOrigin,          square + width, pic, '0 0 0', eX + bH, theColor, theAlpha, drawflag);
 +                      drawsubpic(theOrigin + square, square + width, pic, eY - bH, eX + bH, theColor, theAlpha, drawflag);
 +              }
 +              else
 +              {
 +                      square = eY * theSize_x;
 +                      drawsubpic(theOrigin,                   width   +     square, pic, '0 0    0', '1 0.25 0', theColor, theAlpha, drawflag);
 +                      drawsubpic(theOrigin +          square, theSize - 2 * square, pic, '0 0.25 0', '1 0.5  0', theColor, theAlpha, drawflag);
 +                      drawsubpic(theOrigin + height - square, width   +     square, pic, '0 0.75 0', '1 0.25 0', theColor, theAlpha, drawflag);
 +              }
        } else {
                pic = strcat(hud_skin_path, "/", pic);
                if(precache_pic(pic) == "") {
                        pic = "gfx/hud/default/statusbar";
                }
  
 -        if(barflip)
 -            drawsetcliparea(pos_x + mySize_x * (1 - x), pos_y, mySize_x * x, mySize_y);
 -        else
 -            drawsetcliparea(pos_x, pos_y, mySize_x * x, mySize_y);
 -      }
 +              if (right_align)
 +                      theOrigin_x += (1 - lenght_ratio) * theSize_x;
 +              theSize_x *= lenght_ratio;
  
 -    drawpic(pos, pic, mySize, color, alpha, drawflag);
 -    drawresetcliparea();
 +              vector bW;
 +              width = eX * theSize_x;
 +              height = eY * theSize_y;
 +              if(theSize_x <= theSize_y * 2)
 +              {
 +                      // button not wide enough
 +                      // draw just left and right part then
 +                      square = eX * theSize_x * 0.5;
 +                      bW = eX * (0.25 * theSize_x / (theSize_y * 2));
 +                      drawsubpic(theOrigin,          square + height, pic, '0 0 0', eY + bW, theColor, theAlpha, drawflag);
 +                      drawsubpic(theOrigin + square, square + height, pic, eX - bW, eY + bW, theColor, theAlpha, drawflag);
 +              }
 +              else
 +              {
 +                      square = eX * theSize_y;
 +                      drawsubpic(theOrigin,                  height  +     square, pic, '0    0 0', '0.25 1 0', theColor, theAlpha, drawflag);
 +                      drawsubpic(theOrigin +         square, theSize - 2 * square, pic, '0.25 0 0', '0.5  1 0', theColor, theAlpha, drawflag);
 +                      drawsubpic(theOrigin + width - square, height  +     square, pic, '0.75 0 0', '0.25 1 0', theColor, theAlpha, drawflag);
 +              }
 +      }
  }
  
  void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float alpha, float drawflag)
  vector HUD_Panel_CheckMove(vector myPos, vector mySize)
  {
        float i;
 -
 +      float myCenter_x, myCenter_y, targCenter_x, targCenter_y;
        vector myTarget;
        myTarget = myPos;
  
 -      vector myCenter;
 -      vector targCenter;
 -      myCenter = '0 0 0'; // shut up fteqcc, there IS a reference
 -      targCenter = '0 0 0'; // shut up fteqcc, there IS a reference
 -
        for (i = 0; i < HUD_PANEL_NUM; ++i) {
                if(i == highlightedPanel || !panel_enabled)
                        continue;
@@@ -740,8 -703,8 +741,8 @@@ void HUD_Panel_SetPos(vector pos
  
        if(autocvar_hud_configure_grid)
        {
 -              pos_x = floor((pos_x/vid_conwidth)/bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) + 0.5) * bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) * vid_conwidth;
 -              pos_y = floor((pos_y/vid_conheight)/bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) + 0.5) * bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) * vid_conheight;
 +              pos_x = floor((pos_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x;
 +              pos_y = floor((pos_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y;
        }
  
        if(hud_configure_checkcollisions)
@@@ -799,7 -762,7 +800,7 @@@ vector HUD_Panel_CheckResize(vector myS
                        // (which side the resize direction finds for first) and reduce the size up to there
                        //
                        // dist is the distance between resizeorigin and the "analogous" point of the panel
 -                      // in this case resizeorigin (bottom-right point) and the bottom-right point of the panel
 +                      // in this case between resizeorigin (bottom-right point) and the bottom-right point of the panel
                        dist_x = resizeorigin_x - targEndPos_x;
                        dist_y = resizeorigin_y - targEndPos_y;
                        if (dist_y <= 0 || dist_x / dist_y > ratio)
@@@ -921,8 -884,8 +922,8 @@@ void HUD_Panel_SetPosSize(vector mySize
        // before checkresize, otherwise panel can be snapped partially inside another panel or panel aspect ratio can be broken
        if(autocvar_hud_configure_grid)
        {
 -              mySize_x = floor((mySize_x/vid_conwidth)/bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) + 0.5) * bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) * vid_conwidth;
 -              mySize_y = floor((mySize_y/vid_conheight)/bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) + 0.5) * bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) * vid_conheight;
 +              mySize_x = floor((mySize_x/vid_conwidth)/hud_configure_gridSize_x + 0.5) * hud_configure_realGridSize_x;
 +              mySize_y = floor((mySize_y/vid_conheight)/hud_configure_gridSize_y + 0.5) * hud_configure_realGridSize_y;
        }
  
        if(hud_configure_checkcollisions)
@@@ -965,10 -928,9 +966,10 @@@ float prevMouseClickedTime; // time dur
  vector prevMouseClickedPos; // pos during previous mouse click, to check for doubleclicks
  
  float pressed_key_time;
 +vector highlightedPanel_initial_pos, highlightedPanel_initial_size;
  void HUD_Panel_Arrow_Action(float nPrimary)
  {
 -      if (highlightedPanel_prev == -1 || mouseClicked)
 +      if (highlightedPanel == -1 || mouseClicked)
                return;
  
        hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
                if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW)
                {
                        if (hudShiftState & S_SHIFT)
 -                              step = bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) * vid_conheight;
 +                              step = hud_configure_realGridSize_y;
                        else
 -                              step = 2 * bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) * vid_conheight;
 +                              step = 2 * hud_configure_realGridSize_y;
                }
                else
                {
                        if (hudShiftState & S_SHIFT)
 -                              step = bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) * vid_conwidth;
 +                              step = hud_configure_realGridSize_x;
                        else
 -                              step = 2 * bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) * vid_conwidth;
 +                              step = 2 * hud_configure_realGridSize_x;
                }
        }
        else
                        step = (step / 64) * (1 + 2 * (time - pressed_key_time));
        }
  
 -      highlightedPanel = highlightedPanel_prev;
 -
        HUD_Panel_UpdatePosSizeForId(highlightedPanel);
  
 -      vector prev_pos, prev_size;
 -      prev_pos = panel_pos;
 -      prev_size = panel_size;
 +      highlightedPanel_initial_pos = panel_pos;
 +      highlightedPanel_initial_size = panel_size;
  
        if (hudShiftState & S_ALT) // resize
        {
  
        HUD_Panel_UpdatePosSizeForId(highlightedPanel);
  
 -      if (prev_pos != panel_pos || prev_size != panel_size)
 +      if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size)
        {
                // backup!
 -              panel_pos_backup = prev_pos;
 -              panel_size_backup = prev_size;
 +              panel_pos_backup = highlightedPanel_initial_pos;
 +              panel_size_backup = highlightedPanel_initial_size;
                highlightedPanel_backup = highlightedPanel;
        }
  }
  
 +void HUD_Panel_EnableMenu();
 +float tab_panels[HUD_PANEL_NUM];
 +float tab_panel, tab_backward;
 +vector tab_panel_pos;
 +void HUD_Panel_FirstInDrawQ(float id);
 +void reset_tab_panels()
 +{
 +      int i;
 +      for(i = 0; i < HUD_PANEL_NUM; ++i)
 +              tab_panels[i] = -1;
 +}
  float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
  {
        string s;
                if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
        }
  
 +      if(nPrimary == K_CTRL)
 +      {
 +              if (bInputType == 1) //ctrl has been released
 +              {
 +                      if (tab_panel != -1)
 +                      {
 +                              //switch to selected panel
 +                              highlightedPanel = tab_panel;
 +                              highlightedAction = 0;
 +                              HUD_Panel_FirstInDrawQ(highlightedPanel);
 +                      }
 +                      tab_panel = -1;
 +                      reset_tab_panels();
 +              }
 +      }
 +
        if(nPrimary == K_MOUSE1)
        {
                if(bInputType == 0) { // key pressed
                menu_enabled_time = time;
                localcmd("menu_showhudexit\n");
        }
 -      else if(hudShiftState & S_CTRL)
 +      else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // select and highlight another panel
        {
 -              if (mouseClicked)
 +              if (bInputType == 1 || mouseClicked)
                        return true;
  
 -              if(nPrimary == K_SPACE) // enable/disable highlighted panel or dock
 -              {
 -                      if (bInputType == 1)
 -                              return true;
 +              //FIXME: if a panel is highlighted, has the same pos_x and lays in the same level
 +              //of other panels then next consecutive ctrl-tab will select the highlighted panel too
 +              //(it should only after every other panel of the hud)
 +              //It's a minor bug anyway, we can live with it
  
 -                      if (highlightedPanel_prev != -1)
 -                              cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled)));
 +              float starting_panel;
 +              float old_tab_panel = tab_panel;
 +              if (tab_panel == -1) //first press of TAB
 +              {
 +                      if (highlightedPanel != -1)
 +                              HUD_Panel_UpdatePosSizeForId(highlightedPanel)
                        else
 -                              cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : "");
 +                              panel_pos = '0 0 0';
 +                      starting_panel = highlightedPanel; //can be -1, it means no starting panel
 +                      tab_panel_pos = panel_pos; //to compute level
                }
 -              if(nPrimary == 'c') // copy highlighted panel size
 +              else
                {
 -                      if (bInputType == 1)
 -                              return true;
 -
 -                      if (highlightedPanel_prev != -1)
 +                      if ( ((!tab_backward) && (hudShiftState & S_SHIFT)) || (tab_backward && !(hudShiftState & S_SHIFT)) ) //tab direction changed?
 +                              reset_tab_panels();
 +                      starting_panel = tab_panel;
 +              }
 +              tab_backward = (hudShiftState & S_SHIFT);
 +
 +              float k, level, start_pos_x;
 +              vector candidate_pos;
 +              const float LEVELS_NUM = 4;
 +              const float level_height = vid_conheight / LEVELS_NUM;
 +:find_tab_panel
 +              level = floor(tab_panel_pos_y / level_height) * level_height; //starting level
 +              candidate_pos_x = (!tab_backward) ? vid_conwidth : 0;
 +              start_pos_x = tab_panel_pos_x;
 +              tab_panel = -1;
 +              k=0;
 +              while(++k)
 +              {
 +                      for(i = 0; i < HUD_PANEL_NUM; ++i)
 +                      {
 +                              if (i == tab_panels[i] || i == starting_panel)
 +                                      continue;
 +                              HUD_Panel_UpdatePosSizeForId(i)
 +                              if (panel_pos_y >= level && (panel_pos_y - level) < level_height)
 +                              if (  ( !tab_backward && panel_pos_x >= start_pos_x && (panel_pos_x < candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y <= candidate_pos_y)) )
 +                                      || ( tab_backward && panel_pos_x <= start_pos_x && (panel_pos_x > candidate_pos_x || (panel_pos_x == candidate_pos_x && panel_pos_y >= candidate_pos_y)) )  )
 +                              {
 +                                      tab_panel = i;
 +                                      tab_panel_pos = candidate_pos = panel_pos;
 +                              }
 +                      }
 +                      if (tab_panel != -1)
 +                              break;
 +                      if (k == LEVELS_NUM) //tab_panel not found
 +                      {
 +                              reset_tab_panels();
 +                              if (old_tab_panel == -2) //this prevents an infinite loop (should not happen normally)
 +                              {
 +                                      tab_panel = -1;
 +                                      return true;
 +                              }
 +                              starting_panel = old_tab_panel;
 +                              old_tab_panel = -2;
 +                              goto find_tab_panel; //u must find tab_panel!
 +                      }
 +                      if (!tab_backward)
 +                      {
 +                              level = mod(level + level_height, vid_conheight);
 +                              start_pos_x = 0;
 +                              candidate_pos_x = vid_conwidth;
 +                      }
 +                      else
                        {
 -                              panel_size_copied = panel_size;
 -                              highlightedPanel_copied = highlightedPanel_prev;
 +                              level = mod(level - level_height, vid_conheight);
 +                              start_pos_x = vid_conwidth;
 +                              candidate_pos_x = 0;
                        }
                }
 -              else if(nPrimary == 'v') // past copied size on the highlighted panel
 +
 +              tab_panels[tab_panel] = tab_panel;
 +      }
 +      else if(nPrimary == K_SPACE && hudShiftState & S_CTRL) // enable/disable highlighted panel or dock
 +      {
 +              if (bInputType == 1 || mouseClicked)
 +                      return true;
 +
 +              if (highlightedPanel != -1)
 +              {
 +                      HUD_Panel_GetName(highlightedPanel);
 +                      cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled)));
 +              }
 +              else
 +                      cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : "");
 +      }
 +      else if(nPrimary == 'c' && hudShiftState & S_CTRL) // copy highlighted panel size
 +      {
 +              if (bInputType == 1 || mouseClicked)
 +                      return true;
 +
 +              if (highlightedPanel != -1)
                {
 -                      if (bInputType == 1)
 -                              return true;
 +                      HUD_Panel_UpdatePosSizeForId(highlightedPanel);
 +                      panel_size_copied = panel_size;
 +                      highlightedPanel_copied = highlightedPanel;
 +              }
 +      }
 +      else if(nPrimary == 'v' && hudShiftState & S_CTRL) // past copied size on the highlighted panel
 +      {
 +              if (bInputType == 1 || mouseClicked)
 +                      return true;
  
 -                      if (highlightedPanel_copied == -1 || highlightedPanel_prev == -1)
 -                              return true;
 +              if (highlightedPanel_copied == -1 || highlightedPanel == -1)
 +                      return true;
  
 -                      HUD_Panel_UpdatePosSizeForId(highlightedPanel_prev);
 +              HUD_Panel_UpdatePosSizeForId(highlightedPanel);
  
 -                      // reduce size if it'd go beyond screen boundaries
 -                      vector tmp_size = panel_size_copied;
 -                      if (panel_pos_x + panel_size_copied_x > vid_conwidth)
 -                              tmp_size_x = vid_conwidth - panel_pos_x;
 -                      if (panel_pos_y + panel_size_copied_y > vid_conheight)
 -                              tmp_size_y = vid_conheight - panel_pos_y;
 +              // reduce size if it'd go beyond screen boundaries
 +              vector tmp_size = panel_size_copied;
 +              if (panel_pos_x + panel_size_copied_x > vid_conwidth)
 +                      tmp_size_x = vid_conwidth - panel_pos_x;
 +              if (panel_pos_y + panel_size_copied_y > vid_conheight)
 +                      tmp_size_y = vid_conheight - panel_pos_y;
  
 -                      if (panel_size == tmp_size)
 -                              return true;
 +              if (panel_size == tmp_size)
 +                      return true;
  
 -                      // backup first!
 -                      panel_pos_backup = panel_pos;
 -                      panel_size_backup = panel_size;
 -                      highlightedPanel_backup = highlightedPanel_prev;
 +              // backup first!
 +              panel_pos_backup = panel_pos;
 +              panel_size_backup = panel_size;
 +              highlightedPanel_backup = highlightedPanel;
  
 -                      s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight));
 -                      cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
 -              }
 -              else if(nPrimary == 'z') // undo last action
 +              s = strcat(ftos(tmp_size_x/vid_conwidth), " ", ftos(tmp_size_y/vid_conheight));
 +              HUD_Panel_GetName(highlightedPanel);
 +              cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
 +      }
 +      else if(nPrimary == 'z' && hudShiftState & S_CTRL) // undo last action
 +      {
 +              if (bInputType == 1 || mouseClicked)
 +                      return true;
 +              //restore previous values
 +              if (highlightedPanel_backup != -1)
                {
 -                      if (bInputType == 1)
 -                              return true;
 -                      //restore previous values
 -                      if (highlightedPanel_backup != -1)
 -                      {
 -                              HUD_Panel_GetName(highlightedPanel_backup);
 -                              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;
 -                      }
 +                      HUD_Panel_GetName(highlightedPanel_backup);
 +                      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)
  
                HUD_Panel_Arrow_Action(nPrimary); //move or resize panel
        }
 +      else if(nPrimary == K_ENTER || nPrimary == K_SPACE || nPrimary == K_KP_ENTER)
 +      {
 +              if (bInputType == 1)
 +                      return true;
 +              if (highlightedPanel != -1)
 +                      HUD_Panel_EnableMenu();
 +      }
        else if(hit_con_bind)
                return false;
  
 -      return true; // Suppress ALL other input
 +      return true;
  }
  
  float HUD_Panel_HighlightCheck()
  {
        float i, j, border;
 -      vector panelPos;
 -      vector panelSize;
  
 -      while(j <= HUD_PANEL_NUM)
 +      while(j < HUD_PANEL_NUM)
        {
                i = panel_order[j];
                j += 1;
  
                HUD_Panel_UpdatePosSizeForId(i);
  
 -              panelPos = panel_pos;
 -              panelSize = panel_size;
                border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize
  
                // move
 -              if(mousepos_x >= panelPos_x && mousepos_y >= panelPos_y && mousepos_x <= panelPos_x + panelSize_x && mousepos_y <= panelPos_y + panelSize_y)
 +              if(mousepos_x >= panel_pos_x && mousepos_y >= panel_pos_y && mousepos_x <= panel_pos_x + panel_size_x && mousepos_y <= panel_pos_y + panel_size_y)
                {
                        return 1;
                }
                // resize from topleft border
 -              else if(mousepos_x >= panelPos_x - border && mousepos_y >= panelPos_y - border && mousepos_x <= panelPos_x + 0.5 * panelSize_x && mousepos_y <= panelPos_y + 0.5 * panelSize_y)
 +              else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
                {
                        return 2;
                }
                // resize from topright border
 -              else if(mousepos_x >= panelPos_x + 0.5 * panelSize_x && mousepos_y >= panelPos_y - border && mousepos_x <= panelPos_x + panelSize_x + border && mousepos_y <= panelPos_y + 0.5 * panelSize_y)
 +              else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
                {
                        return 3;
                }
                // resize from bottomleft border
 -              else if(mousepos_x >= panelPos_x - border && mousepos_y >= panelPos_y + 0.5 * panelSize_y && mousepos_x <= panelPos_x + 0.5 * panelSize_x && mousepos_y <= panelPos_y + panelSize_y + border)
 +              else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + panel_size_y + border)
                {
                        return 3;
                }
                // resize from bottomright border
 -              else if(mousepos_x >= panelPos_x + 0.5 * panelSize_x && mousepos_y >= panelPos_y + 0.5 * panelSize_y && mousepos_x <= panelPos_x + panelSize_x + border && mousepos_y <= panelPos_y + panelSize_y + border)
 +              else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + panel_size_y + border)
                {
                        return 2;
                }
@@@ -1411,84 -1263,84 +1412,84 @@@ void HUD_Panel_FirstInDrawQ(float id
  void HUD_Panel_Highlight()
  {
        float i, j, border;
 -      vector panelPos;
 -      vector panelSize;
  
 -      while(j <= HUD_PANEL_NUM)
 +      while(j < HUD_PANEL_NUM)
        {
                i = panel_order[j];
                j += 1;
  
                HUD_Panel_UpdatePosSizeForId(i);
  
 -              panelPos = panel_pos;
 -              panelSize = panel_size;
                border = max(8, panel_bg_border); // FORCED border so a small border size doesn't mean you can't resize
  
                // move
 -              if(mousepos_x >= panelPos_x && mousepos_y >= panelPos_y && mousepos_x <= panelPos_x + panelSize_x && mousepos_y <= panelPos_y + panelSize_y)
 +              if(mousepos_x >= panel_pos_x && mousepos_y >= panel_pos_y && mousepos_x <= panel_pos_x + panel_size_x && mousepos_y <= panel_pos_y + panel_size_y)
                {
                        highlightedPanel = i;
                        HUD_Panel_FirstInDrawQ(i);
                        highlightedAction = 1;
 -                      panel_click_distance = mousepos - panelPos;
 +                      panel_click_distance = mousepos - panel_pos;
                        return;
                }
                // resize from topleft border
 -              else if(mousepos_x >= panelPos_x - border && mousepos_y >= panelPos_y - border && mousepos_x <= panelPos_x + 0.5 * panelSize_x && mousepos_y <= panelPos_y + 0.5 * panelSize_y)
 +              else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
                {
                        highlightedPanel = i;
                        HUD_Panel_FirstInDrawQ(i);
                        highlightedAction = 2;
                        resizeCorner = 1;
 -                      panel_click_distance = mousepos - panelPos;
 -                      panel_click_resizeorigin = panelPos + panelSize;
 +                      panel_click_distance = mousepos - panel_pos;
 +                      panel_click_resizeorigin = panel_pos + panel_size;
                        return;
                }
                // resize from topright border
 -              else if(mousepos_x >= panelPos_x + 0.5 * panelSize_x && mousepos_y >= panelPos_y - border && mousepos_x <= panelPos_x + panelSize_x + border && mousepos_y <= panelPos_y + 0.5 * panelSize_y)
 +              else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y - border && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + 0.5 * panel_size_y)
                {
                        highlightedPanel = i;
                        HUD_Panel_FirstInDrawQ(i);
                        highlightedAction = 2;
                        resizeCorner = 2;
 -                      panel_click_distance_x = panelSize_x - mousepos_x + panelPos_x;
 -                      panel_click_distance_y = mousepos_y - panelPos_y;
 -                      panel_click_resizeorigin = panelPos + eY * panelSize_y;
 +                      panel_click_distance_x = panel_size_x - mousepos_x + panel_pos_x;
 +                      panel_click_distance_y = mousepos_y - panel_pos_y;
 +                      panel_click_resizeorigin = panel_pos + eY * panel_size_y;
                        return;
                }
                // resize from bottomleft border
 -              else if(mousepos_x >= panelPos_x - border && mousepos_y >= panelPos_y + 0.5 * panelSize_y && mousepos_x <= panelPos_x + 0.5 * panelSize_x && mousepos_y <= panelPos_y + panelSize_y + border)
 +              else if(mousepos_x >= panel_pos_x - border && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + 0.5 * panel_size_x && mousepos_y <= panel_pos_y + panel_size_y + border)
                {
                        highlightedPanel = i;
                        HUD_Panel_FirstInDrawQ(i);
                        highlightedAction = 2;
                        resizeCorner = 3;
 -                      panel_click_distance_x = mousepos_x - panelPos_x;
 -                      panel_click_distance_y = panelSize_y - mousepos_y + panelPos_y;
 -                      panel_click_resizeorigin = panelPos + eX * panelSize_x;
 +                      panel_click_distance_x = mousepos_x - panel_pos_x;
 +                      panel_click_distance_y = panel_size_y - mousepos_y + panel_pos_y;
 +                      panel_click_resizeorigin = panel_pos + eX * panel_size_x;
                        return;
                }
                // resize from bottomright border
 -              else if(mousepos_x >= panelPos_x + 0.5 * panelSize_x && mousepos_y >= panelPos_y + 0.5 * panelSize_y && mousepos_x <= panelPos_x + panelSize_x + border && mousepos_y <= panelPos_y + panelSize_y + border)
 +              else if(mousepos_x >= panel_pos_x + 0.5 * panel_size_x && mousepos_y >= panel_pos_y + 0.5 * panel_size_y && mousepos_x <= panel_pos_x + panel_size_x + border && mousepos_y <= panel_pos_y + panel_size_y + border)
                {
                        highlightedPanel = i;
                        HUD_Panel_FirstInDrawQ(i);
                        highlightedAction = 2;
                        resizeCorner = 4;
 -                      panel_click_distance = panelSize - mousepos + panelPos;
 -                      panel_click_resizeorigin = panelPos;
 +                      panel_click_distance = panel_size - mousepos + panel_pos;
 +                      panel_click_resizeorigin = panel_pos;
                        return;
                }
 -              else
 -              {
 -                      highlightedPanel_prev = -1;
 -              }
        }
 +      highlightedPanel = -1;
 +      highlightedAction = 0;
  }
  
 +void HUD_Panel_EnableMenu()
 +{
 +      menu_enabled = 2;
 +      menu_enabled_time = time;
 +      HUD_Panel_GetName(highlightedPanel);
 +      localcmd("menu_showhudoptions ", panel_name, "\n");
 +}
  float highlightcheck;
 -vector prev_pos, prev_size;
  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(menu_enabled == 1 || (menu_enabled == 2 && !hud_fade_alpha))
                return;
  
 -      if(mouseClicked == 0 && menu_enabled != 2 && highlightedPanel >= 0) { // don't reset these variables in menu_enabled mode 2!
 -              highlightedPanel = -1;
 -              highlightedAction = 0;
 -      }
 -      if(highlightedPanel != -1)
 -              highlightedPanel_prev = highlightedPanel;
 -
        mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
  
        mousepos_x = bound(0, mousepos_x, vid_conwidth);
        {
                if(prevMouseClicked == 0)
                {
 +                      if (tab_panel != -1)
 +                      {
 +                              //stop ctrl-tab selection
 +                              tab_panel = -1;
 +                              reset_tab_panels();
 +                      }
                        HUD_Panel_Highlight(); // sets highlightedPanel, highlightedAction, panel_click_distance, panel_click_resizeorigin
                                                                        // and calls HUD_Panel_UpdatePosSizeForId() for the highlighted panel
 -                      prev_pos = panel_pos;
 -                      prev_size = panel_size;
 +                      if (highlightedPanel != -1)
 +                      {
 +                              highlightedPanel_initial_pos = panel_pos;
 +                              highlightedPanel_initial_size = panel_size;
 +                      }
                }
                else
                        HUD_Panel_UpdatePosSizeForId(highlightedPanel);
  
 -              if (prev_pos != panel_pos || prev_size != panel_size)
 +              if (highlightedPanel != -1)
                {
 -                      hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
 -                      // backup!
 -                      panel_pos_backup = prev_pos;
 -                      panel_size_backup = prev_size;
 -                      highlightedPanel_backup = highlightedPanel;
 +                      if (highlightedPanel_initial_pos != panel_pos || highlightedPanel_initial_size != panel_size)
 +                      {
 +                              hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
 +                              // backup!
 +                              panel_pos_backup = highlightedPanel_initial_pos;
 +                              panel_size_backup = highlightedPanel_initial_size;
 +                              highlightedPanel_backup = highlightedPanel;
 +                      }
 +                      else
 +                              // in case the clicked panel is inside another panel and we aren't
 +                              // moving it, avoid the immediate "fix" of its position/size
 +                              // (often unwanted and hateful) by disabling collisions check
 +                              hud_configure_checkcollisions = false;
                }
 -              else
 -                      // in case the clicked panel is inside another panel and we aren't
 -                      // moving it, avoid the immediate "fix" of its position/size
 -                      // (often unwanted and hateful) by disabling collisions check
 -                      hud_configure_checkcollisions = false;
  
                if(highlightedAction == 1)
                        HUD_Panel_SetPos(mousepos - panel_click_distance);
                if(time - prevMouseClickedTime < 0.4 && prevMouseClicked == 0 && prevMouseClickedPos == mousepos && highlightedPanel >= 0)
                {
                        mouseClicked = 0; // to prevent spam, I guess.
 -                      menu_enabled = 2;
 -                      menu_enabled_time = time;
 -                      HUD_Panel_GetName(highlightedPanel);
 -                      localcmd("menu_showhudoptions ", panel_name, "\n");
 +                      HUD_Panel_EnableMenu();
                        return;
                }
                if(prevMouseClicked == 0)
        cursorsize = '32 32 0';
  
        if(highlightcheck == 0)
 -              drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
 +              drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
        else if(highlightcheck == 1)
 -              drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_move.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
 +              drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_move.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
        else if(highlightcheck == 2)
 -              drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
 +              drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
        else
 -              drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize2.tga"), '32 32 0', '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
 +              drawpic(mousepos - cursorsize * 0.5, strcat("gfx/menu/", autocvar_menu_skin, "/cursor_resize2.tga"), cursorsize, '1 1 1', hud_fade_alpha, DRAWFLAG_NORMAL);
  
        prevMouseClicked = mouseClicked;
  }
@@@ -1671,13 -1521,8 +1672,13 @@@ void HUD_Weapons(void
        float f, screen_ar;
        float center_x, center_y;
  
 -      if(!autocvar_hud_panel_weapons && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_weapons) return;
 +              if(spectatee_status == -1) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_WEAPONS;
  
        float timeout = autocvar_hud_panel_weapons_timeout;
        float timeout_effect_length, timein_effect_length;
                return;
        }
  
 -      active_panel = HUD_PANEL_WEAPONS;
        HUD_Panel_UpdateCvars(weapons);
  
        if (timeout && time >= weapontime + timeout && !autocvar__hud_configure)
        vector wpnpos;
        vector wpnsize;
        
 -      float fullammo_shells, fullammo_nails, fullammo_rockets, fullammo_cells, fullammo_fuel;
        vector ammo_color;
        float ammo_alpha;
        wpnsize = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
        float barsize_x, barsize_y, baroffset_x, baroffset_y;
 -      float show_ammo = autocvar_hud_panel_weapons_ammo;
 -      if (show_ammo)
 -      {
 -              fullammo_shells = autocvar_hud_panel_weapons_ammo_full_shells;
 -              fullammo_nails = autocvar_hud_panel_weapons_ammo_full_nails;
 -              fullammo_rockets = autocvar_hud_panel_weapons_ammo_full_rockets;
 -              fullammo_cells = autocvar_hud_panel_weapons_ammo_full_cells;
 -              fullammo_fuel = autocvar_hud_panel_weapons_ammo_full_fuel;
 +      if (autocvar_hud_panel_weapons_ammo)
 +      {
                ammo_color = stov(autocvar_hud_panel_weapons_ammo_color);
                ammo_alpha = panel_fg_alpha * autocvar_hud_panel_weapons_ammo_alpha;
  
                                drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * wpnsize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
  
                        // draw ammo status bar
 -                      if(show_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO)
 +                      if(autocvar_hud_panel_weapons_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO)
                        {
                                a = 0;
                                type = GetAmmoTypeForWep(weapid);
                                if(a > 0)
                                {
                                        switch(type) {
 -                                              case 0: fullammo = fullammo_shells; break;
 -                                              case 1: fullammo = fullammo_nails; break;
 -                                              case 2: fullammo = fullammo_rockets; break;
 -                                              case 3: fullammo = fullammo_cells; break;
 -                                              case 4: fullammo = fullammo_fuel; break;
 +                                              case 0: fullammo = autocvar_hud_panel_weapons_ammo_full_shells; break;
 +                                              case 1: fullammo = autocvar_hud_panel_weapons_ammo_full_nails; break;
 +                                              case 2: fullammo = autocvar_hud_panel_weapons_ammo_full_rockets; break;
 +                                              case 3: fullammo = autocvar_hud_panel_weapons_ammo_full_cells; break;
 +                                              case 4: fullammo = autocvar_hud_panel_weapons_ammo_full_fuel; break;
                                                default: fullammo = 60;
                                        }
  
@@@ -2031,7 -1884,7 +2032,7 @@@ void DrawAmmoItem(vector myPos, vector 
        if(autocvar__hud_configure)
        {
                currently_selected = (itemcode == 2); //rockets always selected
 -              a = 100;
 +              a = 31 + mod(itemcode*93, 128);
        }
        else
                a = getstati(GetAmmoStat(itemcode)); // how much ammo do we have of type itemcode?
                drawpic_aspect_skin(myPos, "ammo_current_bg", mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
  
      if(a > 0 && autocvar_hud_panel_ammo_progressbar)
 -        HUD_Panel_DrawProgressBar(myPos + eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x, mySize - eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x, autocvar_hud_panel_ammo_progressbar_name, 0, 0, min(1, a/autocvar_hud_panel_ammo_maxammo), color, autocvar_hud_progressbar_alpha * panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
 +        HUD_Panel_DrawProgressBar(myPos + eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x, mySize - eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x, autocvar_hud_panel_ammo_progressbar_name, 0, 0, a/autocvar_hud_panel_ammo_maxammo, color, autocvar_hud_progressbar_alpha * panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
  
      if(autocvar_hud_panel_ammo_text)
      {
  
  void HUD_Ammo(void)
  {
 -      if(!autocvar_hud_panel_ammo && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_ammo) return;
 +              if(spectatee_status == -1) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_AMMO;
  
 -      active_panel = HUD_PANEL_AMMO;
        HUD_Panel_UpdateCvars(ammo);
        vector pos, mySize;
        pos = panel_pos;
        drawfont = hud_font;
  }
  
 -void DrawNumIcon(float iconalign, vector myPos, vector mySize, float x, string icon, float left, vector color, float alpha)
 +void DrawNumIcon(vector myPos, vector mySize, float x, string icon, float vertical, float icon_right_align, vector color, float alpha)
  {
 -      vector newPos;
 -      float newSize_x, newSize_y;
 +      vector newPos, newSize;
 +      vector picpos, numpos;
 +
 +      if (vertical)
 +      {
 +              if(mySize_y/mySize_x > 2)
 +              {
 +                      newSize_y = 2 * mySize_x;
 +                      newSize_x = mySize_x;
 +
 +                      newPos_y = myPos_y + (mySize_y - newSize_y) / 2;
 +                      newPos_x = myPos_x;
 +              }
 +              else
 +              {
 +                      newSize_x = 1/2 * mySize_y;
 +                      newSize_y = mySize_y;
 +
 +                      newPos_x = myPos_x + (mySize_x - newSize_x) / 2;
 +                      newPos_y = myPos_y;
 +              }
 +
 +              if(icon_right_align)
 +              {
 +                      numpos = newPos;
 +                      picpos = newPos + eY * newSize_x;
 +              }
 +              else
 +              {
 +                      picpos = newPos;
 +                      numpos = newPos + eY * newSize_x;
 +              }
 +
 +              newSize_y /= 2;
 +              drawpic_aspect_skin(picpos, icon, newSize, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
 +              // make number smaller than icon, it looks better
 +              // reduce only y to draw numbers with different number of digits with the same y size
 +              numpos_y += newSize_y * ((1 - 0.7) / 2);
 +              newSize_y *= 0.7;
 +              drawstring_aspect(numpos, ftos(x), newSize, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
 +              return;
 +      }
 +
        if(mySize_x/mySize_y > 3)
        {
                newSize_x = 3 * mySize_y;
                newPos_x = myPos_x;
        }
  
 -      vector picpos, numpos;
 -      if(left)
 +      if(icon_right_align) // right align
        {
 -              if(iconalign == 1 || iconalign == 3) // right align
 -              {
 -                      numpos = newPos;
 -                      picpos = newPos + eX * 2 * newSize_y;
 -              }
 -              else // left align
 -              {
 -                      numpos = newPos + eX * newSize_y;
 -                      picpos = newPos;
 -              }
 +              numpos = newPos;
 +              picpos = newPos + eX * 2 * newSize_y;
        }
 -      else
 +      else // left align
        {
 -              if(iconalign == 0 || iconalign == 3) // left align
 -              {
 -                      numpos = newPos + eX * newSize_y;
 -                      picpos = newPos;
 -              } 
 -              else // right align
 -              {
 -                      numpos = newPos;
 -                      picpos = newPos + eX * 2 * newSize_y;
 -              }
 +              numpos = newPos + eX * newSize_y;
 +              picpos = newPos;
        }
  
 -      drawfont = hud_bigfont;
 -      drawstring_aspect(numpos, ftos(x), eX * (2/3) * newSize_x + eY * newSize_y, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
 -      drawfont = hud_font;
 +      drawstring_aspect(numpos, ftos(x), '2 1 0' * newSize_y, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
        drawpic_aspect_skin(picpos, icon, '1 1 0' * newSize_y, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
  }
  
 -void DrawNumIcon_expanding(float iconalign, vector myPos, vector mySize, float x, string icon, float left, vector color, float fadelerp)
 +void DrawNumIcon_expanding(vector myPos, vector mySize, float x, string icon, float vertical, float icon_right_align, vector color, float fadelerp)
  {
        float sz;
        sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
  
 -      DrawNumIcon(iconalign, myPos + expandingbox_resize_centered_box_offset(sz, mySize, 1), mySize * sz, x, icon, left, color, (1 - fadelerp));
 +      DrawNumIcon(myPos + expandingbox_resize_centered_box_offset(sz, mySize, 1), mySize * sz, x, icon, vertical, icon_right_align, color, (1 - fadelerp));
  }
  
  // Powerups (#2)
  //
 -void HUD_Powerups(void) {
 -      if(!autocvar_hud_panel_powerups && !autocvar__hud_configure)
 -              return;
 -
 +void HUD_Powerups(void)
 +{
 +      float strength_time, shield_time;
        if(!autocvar__hud_configure)
        {
 -              if not(getstati(STAT_ITEMS) & (IT_STRENGTH | IT_INVINCIBLE))
 -                      return;
 +              if(!autocvar_hud_panel_powerups) return;
 +              if(spectatee_status == -1) return;
 +              if not(getstati(STAT_ITEMS) & (IT_STRENGTH | IT_INVINCIBLE)) return;
 +              if (getstati(STAT_HEALTH) <= 0) return;
  
 -              if (getstati(STAT_HEALTH) <= 0)
 -                      return;
 +              strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99);
 +              shield_time = bound(0, getstatf(STAT_INVINCIBLE_FINISHED) - time, 99);
 +      }
 +      else
 +      {
 +              hud_configure_active_panel = HUD_PANEL_POWERUPS;
 +
 +              strength_time = 15;
 +              shield_time = 27;
        }
  
 -      active_panel = HUD_PANEL_POWERUPS;
        HUD_Panel_UpdateCvars(powerups);
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
  
 -      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;
        }
  
 -      vector barpos, barsize;
 +      vector barsize;
        vector picpos;
        vector numpos;
  
      string leftprogressname, rightprogressname;
        float leftcnt, rightcnt;
        float leftexact, rightexact;
 -      float flip = autocvar_hud_panel_powerups_flip;
 -      if (flip) {
 +      if (autocvar_hud_panel_powerups_flip) {
                leftname = "strength";
          leftprogressname = autocvar_hud_panel_powerups_progressbar_strength;
                leftcnt = ceil(strength_time);
  
        drawfont = hud_bigfont;
        float baralign = autocvar_hud_panel_powerups_baralign;
 -    float barflip;
        float iconalign = autocvar_hud_panel_powerups_iconalign;
 -      float progressbar = autocvar_hud_panel_powerups_progressbar;
 -      if (mySize_x/mySize_y > 4)
 +
 +      float panel_ar = mySize_x/mySize_y;
 +      float is_vertical = (panel_ar < 1);
 +      if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
        {
          barsize = eX * 0.5 * mySize_x + eY * mySize_y;
                if(leftcnt)
                {
 -                      if(baralign == 1 || baralign == 3) { // right align
 -                barpos = pos + eX * 0.5 * mySize_x;
 -                barflip = 1;
 -                      } else { // left align
 -                barpos = pos;
 -                barflip = 0;
 -                      }
 -
 -                      if(progressbar)
 +                      if(autocvar_hud_panel_powerups_progressbar)
                        {
                                HUD_Panel_GetProgressBarColorForString(leftname);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, leftprogressname, 0, barflip, min(1, leftcnt/30), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
 +                              HUD_Panel_DrawProgressBar(pos, barsize, leftprogressname, leftcnt/30, is_vertical, (baralign == 1 || baralign == 2), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
                        }
              if(autocvar_hud_panel_powerups_text)
              {
 -                if(leftcnt > 1)
 -                    DrawNumIcon(iconalign, pos, eX * 0.5 * mySize_x + eY * mySize_y, leftcnt, leftname, 1, '1 1 1', 1);
 -                if(leftcnt <= 5)
 -                    DrawNumIcon_expanding(iconalign, pos, eX * 0.5 * mySize_x + eY * mySize_y, leftcnt, leftname, 1, '1 1 1', bound(0, (leftcnt - leftexact) / 0.5, 1));
 -            }
 -              }
 -
 -              if(rightcnt)
 -              {
 -                      if(baralign == 0 || baralign == 3) { // left align
 -                barpos = pos;
 -                barflip = 0;
 -                      } else { // right align
 -                barpos = pos + eX * 0.5 * mySize_x;
 -                barflip = 1;
 -                      }
 -
 -                      if(progressbar)
 -                      {
 -                              HUD_Panel_GetProgressBarColorForString(rightname);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, rightprogressname, 0, barflip, min(1, rightcnt/30), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
 +                              if(leftcnt > 1)
 +                                      DrawNumIcon(pos, barsize, leftcnt, leftname, is_vertical, (iconalign == 1 || iconalign == 2), '1 1 1', 1);
 +                              if(leftcnt <= 5)
 +                                      DrawNumIcon_expanding(pos, barsize, leftcnt, leftname, is_vertical, (iconalign == 1 || iconalign == 2), '1 1 1', bound(0, (leftcnt - leftexact) / 0.5, 1));
                        }
 -            if(autocvar_hud_panel_powerups_text)
 -            {
 -                if(rightcnt > 1)
 -                    DrawNumIcon(iconalign, pos + eX * 0.5 * mySize_x, eX * 0.5 * mySize_x + eY * mySize_y, rightcnt, rightname, 0, '1 1 1', 1);
 -                if(rightcnt <= 5)
 -                    DrawNumIcon_expanding(iconalign, pos + eX * 0.5 * mySize_x, eX * 0.5 * mySize_x + eY * mySize_y, rightcnt, rightname, 0, '1 1 1', bound(0, (rightcnt - rightexact) / 0.5, 1));
 -            }
 -              }
 -      }
 -      else if (mySize_x/mySize_y > 1.5)
 -      {
 -        barsize = eX * mySize_x + eY * 0.5 * mySize_y;
 -              if(leftcnt)
 -              {
 -            barpos = pos;
 -                      if(baralign == 1 || baralign == 3) { // right/down align
 -                barflip = 1;
 -                      } else { // left/up align
 -                barflip = 0;
 -                      }
 -
 -                      if(progressbar)
 -                      {
 -                              HUD_Panel_GetProgressBarColorForString(leftname);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, leftprogressname, 0, barflip, min(1, leftcnt/30), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
 -                      }
 -            if(autocvar_hud_panel_powerups_text)
 -            {
 -                if(leftcnt > 1)
 -                    DrawNumIcon(iconalign, pos, eX * mySize_x + eY * 0.5 * mySize_y, leftcnt, leftname, 1, '1 1 1', 1);
 -                if(leftcnt <= 5)
 -                    DrawNumIcon_expanding(iconalign, pos, eX * mySize_x + eY * 0.5 * mySize_y, leftcnt, leftname, 1, '1 1 1', bound(0, (leftcnt - leftexact) / 0.5, 1));
 -            }
                }
  
                if(rightcnt)
                {
 -            barpos = pos + eY * 0.5 * mySize_y;
 -                      if(baralign == 0 || baralign == 3) { // left align
 -                barflip = 0;
 -                      } else { // right align
 -                barflip = 1;
 -                      }
 -
 -                      if(progressbar)
 +                      pos_x += barsize_x;
 +                      if(autocvar_hud_panel_powerups_progressbar)
                        {
                                HUD_Panel_GetProgressBarColorForString(rightname);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, rightprogressname, 0, barflip, min(1, rightcnt/30), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
 +                              HUD_Panel_DrawProgressBar(pos, barsize, rightprogressname, rightcnt/30, is_vertical, (baralign == 1 || baralign == 3), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
                        }
              if(autocvar_hud_panel_powerups_text)
              {
 -                if(rightcnt > 1)
 -                    DrawNumIcon(iconalign, pos + eY * 0.5 * mySize_y, eX * mySize_x + eY * 0.5 * mySize_y, rightcnt, rightname, 0, '1 1 1', 1);
 -                if(rightcnt <= 5)
 -                    DrawNumIcon_expanding(iconalign, pos + eY * 0.5 * mySize_y, eX * mySize_x + eY * 0.5 * mySize_y, rightcnt, rightname, 0, '1 1 1', bound(0, (rightcnt - rightexact) / 0.5, 1));
 -            }
 +                              if(rightcnt > 1)
 +                                      DrawNumIcon(pos, barsize, rightcnt, rightname, is_vertical, (iconalign == 1 || iconalign == 3), '1 1 1', 1);
 +                              if(rightcnt <= 5)
 +                                      DrawNumIcon_expanding(pos, eX * 0.5 * mySize_x + eY * mySize_y, rightcnt, rightname, is_vertical, (iconalign == 1 || iconalign == 3), '1 1 1', bound(0, (rightcnt - rightexact) / 0.5, 1));
 +                      }
                }
        }
        else
        {
 -        barsize = eX * 0.5 * mySize_x + eY * mySize_y;
 +        barsize = eX * mySize_x + eY * 0.5 * mySize_y;
                if(leftcnt)
                {
 -            barpos = pos;
 -                      if(baralign == 1 || baralign == 3) { // down align
 -                barflip = 1;
 -                      } else { // up align
 -                barflip = 0;
 -                      }
 -
 -                      if(iconalign == 1 || iconalign == 3) { // down align
 -                              picpos = pos + eX * 0.05 * mySize_x + eY * (mySize_y - 0.65 * mySize_x);
 -                              numpos = pos + eY * mySize_y - eY * 0.25 * mySize_x;
 -                      } else { // up align
 -                              picpos = pos + eX * 0.05 * mySize_x;
 -                              numpos = pos + eY * 0.4 * mySize_x;
 -                      }
 -
 -                      if(progressbar)
 +                      if(autocvar_hud_panel_powerups_progressbar)
                        {
                                HUD_Panel_GetProgressBarColorForString(leftname);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, leftprogressname, 1, barflip, min(1, leftcnt/30), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
 +                              HUD_Panel_DrawProgressBar(pos, barsize, leftprogressname, leftcnt/30, is_vertical, (baralign == 1 || baralign == 2), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
                        }
              if(autocvar_hud_panel_powerups_text)
              {
 -                if(leftcnt <= 5)
 -                    drawpic_aspect_skin_expanding(picpos, leftname, '0.4 0.4 0' * mySize_x, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, bound(0, (leftcnt - leftexact) / 0.5, 1));
 -                if(leftcnt > 1)
 -                    drawpic_aspect_skin(picpos, leftname, '0.4 0.4 0' * mySize_x, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                drawstring_aspect(numpos, ftos(leftcnt), eX * 0.5 * mySize_x + eY * 0.25 * mySize_x, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -            }
 +                              if(leftcnt > 1)
 +                                      DrawNumIcon(pos, barsize, leftcnt, leftname, is_vertical, (iconalign == 1 || iconalign == 2), '1 1 1', 1);
 +                              if(leftcnt <= 5)
 +                                      DrawNumIcon_expanding(pos, barsize, leftcnt, leftname, is_vertical, (iconalign == 1 || iconalign == 2), '1 1 1', bound(0, (leftcnt - leftexact) / 0.5, 1));
 +                      }
                }
  
                if(rightcnt)
                {
 -            barpos = pos + eX * 0.5 * mySize_x;
 -                      if(baralign == 0 || baralign == 3) { // down align
 -                barflip = 1;
 -                      } else { // up align
 -                barflip = 0;
 -                      }
 -
 -                      if(iconalign == 0 || iconalign == 3) { // up align
 -                              picpos = pos + eX * 0.05 * mySize_x + eX * 0.5 * mySize_x;
 -                              numpos = pos + eY * 0.4 * mySize_x + eX * 0.5 * mySize_x;
 -                      } else { // down align
 -                              picpos = pos + eX * 0.05 * mySize_x + eY * (mySize_y - 0.65 * mySize_x) + eX * 0.5 * mySize_x;
 -                              numpos = pos + eY * mySize_y - eY * 0.25 * mySize_x + eX * 0.5 * mySize_x;
 -                      }
 -
 -                      if(progressbar)
 +                      pos_y += barsize_y;
 +                      if(autocvar_hud_panel_powerups_progressbar)
                        {
                                HUD_Panel_GetProgressBarColorForString(rightname);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, rightprogressname, 1, barflip, min(1, rightcnt/30), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
 +                              HUD_Panel_DrawProgressBar(pos, barsize, rightprogressname, rightcnt/30, is_vertical, (baralign == 1 || baralign == 3), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * bound(0, max(strength_time, shield_time), 1), DRAWFLAG_NORMAL);
                        }
              if(autocvar_hud_panel_powerups_text)
              {
 -                if(rightcnt <= 5)
 -                    drawpic_aspect_skin_expanding(picpos, rightname, '0.4 0.4 0' * mySize_x, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, bound(0, (rightcnt - rightexact) / 0.5, 1));
 -                if(rightcnt > 1)
 -                    drawpic_aspect_skin(picpos, rightname, '0.4 0.4 0' * mySize_x, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                drawstring_aspect(numpos, ftos(rightcnt), eX * 0.5 * mySize_x + eY * 0.25 * mySize_x, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -            }
 +                              if(rightcnt > 1)
 +                                      DrawNumIcon(pos, barsize, rightcnt, rightname, is_vertical, (iconalign == 1 || iconalign == 3), '1 1 1', 1);
 +                              if(rightcnt <= 5)
 +                                      DrawNumIcon_expanding(pos, barsize, rightcnt, rightname, is_vertical, (iconalign == 1 || iconalign == 3), '1 1 1', bound(0, (rightcnt - rightexact) / 0.5, 1));
 +                      }
                }
        }
        drawfont = hud_font;
  //
  void HUD_HealthArmor(void)
  {
 -      if(!autocvar_hud_panel_healtharmor && !autocvar__hud_configure)
 -              return;
 +      float armor, health, fuel;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_healtharmor) return;
 +              if(spectatee_status == -1) return;
 +
 +              health = getstati(STAT_HEALTH);
 +              if(health <= 0)
 +                      return;
 +              armor = getstati(STAT_ARMOR);
 +              fuel = getstati(STAT_FUEL);
 +      }
 +      else
 +      {
 +              hud_configure_active_panel = HUD_PANEL_HEALTHARMOR;
 +
 +              health = 150;
 +              armor = 75;
 +              fuel = 20;
 +      }
  
 -      active_panel = HUD_PANEL_HEALTHARMOR;
        HUD_Panel_UpdateCvars(healtharmor);
        vector pos, mySize;
        pos = panel_pos;
                mySize -= '2 2 0' * panel_bg_padding;
        }
  
 -      float armor, health, fuel;
 -      armor = getstati(STAT_ARMOR);
 -      health = getstati(STAT_HEALTH);
 -      fuel = getstati(STAT_FUEL);
 -
 -      if(autocvar__hud_configure)
 -      {
 -              armor = 75;
 -              health = 150;
 -              fuel = 20;
 -      }
 -
 -      if(health <= 0)
 -              return;
 -
 -      vector barpos, barsize;
 -      vector picpos;
 -      vector numpos;
 +      vector barsize;
 +      vector picpos, numpos;
  
        drawfont = hud_bigfont;
        float baralign = autocvar_hud_panel_healtharmor_baralign;
        float iconalign = autocvar_hud_panel_healtharmor_iconalign;
 -      float progressbar = autocvar_hud_panel_healtharmor_progressbar;
  
      float maxhealth = autocvar_hud_panel_healtharmor_maxhealth;
      float maxarmor = autocvar_hud_panel_healtharmor_maxarmor;
                x = floor(v_x + 1);
  
          float maxtotal = maxhealth + maxarmor;
 -
 -        barpos = pos;
 -        barsize = mySize;
 -
                string biggercount;
                if(v_z) // NOT fully armored
                {
                        biggercount = "health";
 -                      if(progressbar)
 +                      if(autocvar_hud_panel_healtharmor_progressbar)
                        {
                                HUD_Panel_GetProgressBarColor(health);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, autocvar_hud_panel_healtharmor_progressbar_health, 0, mod(baralign, 2), x/maxtotal, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              HUD_Panel_DrawProgressBar(pos, mySize, autocvar_hud_panel_healtharmor_progressbar_health, x/maxtotal, 0, (baralign == 1 || baralign == 2), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                        }
                        if(armor)
              if(autocvar_hud_panel_healtharmor_text)
                else
                {
                        biggercount = "armor";
 -                      if(progressbar)
 +                      if(autocvar_hud_panel_healtharmor_progressbar)
                        {
                                HUD_Panel_GetProgressBarColor(armor);
 -                              HUD_Panel_DrawProgressBar(barpos, barsize, autocvar_hud_panel_healtharmor_progressbar_armor, 0, mod(baralign, 2), x/maxtotal, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              HUD_Panel_DrawProgressBar(pos, mySize, autocvar_hud_panel_healtharmor_progressbar_armor, x/maxtotal, 0, (baralign == 1 || baralign == 2), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                        }
                        if(health)
              if(autocvar_hud_panel_healtharmor_text)
                                drawpic_aspect_skin(pos + eX * mySize_x - eX * 0.5 * mySize_y, "health", '0.5 0.5 0' * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                }
          if(autocvar_hud_panel_healtharmor_text)
 -            DrawNumIcon(iconalign, pos, mySize, x, biggercount, 1, HUD_Get_Num_Color(x, maxtotal), 1);
 +                      DrawNumIcon(pos, mySize, x, biggercount, 0, iconalign, HUD_Get_Num_Color(x, maxtotal), 1);
  
 -              // fuel
                if(fuel)
                {
 -            barpos = pos;
 -            barsize = eX * mySize_x + eY * 0.2 * mySize_y;
                        HUD_Panel_GetProgressBarColor(fuel);
 -            HUD_Panel_DrawProgressBar(barpos, barsize, "progressbar", 0, mod(baralign, 2), min(1, fuel/100), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
 +                      HUD_Panel_DrawProgressBar(pos, eX * mySize_x + eY * 0.2 * mySize_y, "progressbar", fuel/100, 0, (baralign == 1 || baralign == 3), progressbar_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
                }
        }
        else
                float leftmax, rightmax;
                float leftactive, rightactive;
                float leftalpha, rightalpha;
 -              float flip = autocvar_hud_panel_healtharmor_flip;
 -        float barflip;
 -              if (flip) { // old style layout with armor left/top of health
 +              if (autocvar_hud_panel_healtharmor_flip) { // old style layout with armor left/top of health
                        leftname = "armor";
              leftprogressname = autocvar_hud_panel_healtharmor_progressbar_armor;
                        leftcnt = armor;
              rightmax = maxarmor;
                }
  
 -              if (mySize_x/mySize_y > 4)
 +              float panel_ar = mySize_x/mySize_y;
 +              float is_vertical = (panel_ar < 1);
 +              if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
                {
              barsize = eX * 0.5 * mySize_x + eY * mySize_y;
                        if(leftactive)
                        {
 -                barpos = pos;
 -                              if(baralign == 1 || baralign == 3) { // right align
 -                    barflip = 1;
 -                              } else { // left align
 -                    barflip = 0;
 -                              }
 -
 -                              if(progressbar)
 +                              if(autocvar_hud_panel_healtharmor_progressbar)
                                {
                                        HUD_Panel_GetProgressBarColorForString(leftname);
 -                    HUD_Panel_DrawProgressBar(barpos, barsize, leftprogressname, 0, barflip, min(1, leftcnt/leftmax), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      HUD_Panel_DrawProgressBar(pos, barsize, leftprogressname, leftcnt/leftmax, is_vertical, (baralign == 1 || baralign == 2), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                                }
 -                if(autocvar_hud_panel_healtharmor_text)
 -                    DrawNumIcon(iconalign, pos, eX * 0.5 * mySize_x + eY * mySize_y, leftcnt, leftname, 1, HUD_Get_Num_Color(leftcnt, leftmax), 1);
 +                              if(autocvar_hud_panel_healtharmor_text)
 +                                      DrawNumIcon(pos, barsize, leftcnt, leftname, is_vertical, (iconalign == 1 || iconalign == 2), HUD_Get_Num_Color(leftcnt, leftmax), 1);
                        }
  
                        if(rightactive)
                        {
 -                barpos = pos + eX * 0.5 * mySize_x;
 -                              if(baralign == 0 || baralign == 3) { // left align
 -                    barflip = 0;
 -                              } else { // right align
 -                    barflip = 1;
 -                              }
 -
 -                              if(progressbar)
 +                              if(autocvar_hud_panel_healtharmor_progressbar)
                                {
                                        HUD_Panel_GetProgressBarColorForString(rightname);
 -                    HUD_Panel_DrawProgressBar(barpos, barsize, rightprogressname, 0, barflip, min(1, rightcnt/rightmax), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      HUD_Panel_DrawProgressBar(pos + eX * 0.5 * mySize_x, barsize, rightprogressname, rightcnt/rightmax, is_vertical, (baralign == 1 || baralign == 3), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                                }
 -                if(autocvar_hud_panel_healtharmor_text)
 -                    DrawNumIcon(iconalign, pos + eX * 0.5 * mySize_x, eX * 0.5 * mySize_x + eY * mySize_y, rightcnt, rightname, 0, HUD_Get_Num_Color(rightcnt, rightmax), 1);
 +                              if(autocvar_hud_panel_healtharmor_text)
 +                                      DrawNumIcon(pos + eX * 0.5 * mySize_x, barsize, rightcnt, rightname, is_vertical, (iconalign == 1 || iconalign == 3), HUD_Get_Num_Color(rightcnt, rightmax), 1);
                        }
  
                        if(fuel)
                        {
 -                barpos = pos;
 -                barsize = eX * mySize_x + eY * 0.2 * mySize_y;
 -                HUD_Panel_GetProgressBarColor(fuel);
 -                HUD_Panel_DrawProgressBar(barpos, barsize, "progressbar", 0, mod(baralign, 2), min(1, fuel/100), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
 -                      }
 -              }
 -              else if (mySize_x/mySize_y > 1.5)
 -              {
 -            barsize = eX * mySize_x + eY * 0.5 * mySize_y;
 -                      if(leftactive)
 -                      {
 -                barpos = pos;
 -                              if(baralign == 1 || baralign == 3) { // right align
 -                    barflip = 1;
 -                              } else { // left align
 -                    barflip = 0;
 -                              }
 -
 -                              if(progressbar)
 -                              {
 -                                      HUD_Panel_GetProgressBarColorForString(leftname);
 -                    HUD_Panel_DrawProgressBar(barpos, barsize, leftprogressname, 0, barflip, min(1, leftcnt/leftmax), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              }
 -                if(autocvar_hud_panel_healtharmor_text)
 -                    DrawNumIcon(iconalign, pos, eX * mySize_x + eY * 0.5 * mySize_y, leftcnt, leftname, 1, HUD_Get_Num_Color(leftcnt, leftmax), 1);
 -                      }
 -
 -                      if(rightactive)
 -                      {
 -                barpos = pos + eY * 0.5 * mySize_y;
 -                              if(baralign == 0 || baralign == 3) { // left align
 -                    barflip = 0;
 -                              } else { // right align
 -                    barflip = 1;
 -                              }
 -
 -                              if(progressbar)
 -                              {
 -                                      HUD_Panel_GetProgressBarColorForString(rightname);
 -                    HUD_Panel_DrawProgressBar(barpos, barsize, rightprogressname, 0, barflip, min(1, rightcnt/rightmax), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              }
 -                if(autocvar_hud_panel_healtharmor_text)
 -                    DrawNumIcon(iconalign, pos + eY * 0.5 * mySize_y, eX * mySize_x + eY * 0.5 * mySize_y, rightcnt, rightname, 0, HUD_Get_Num_Color(rightcnt, rightmax), 1);
 -                      }
 -
 -                      if(fuel)
 -                      {
 -                barpos = pos;
 -                barsize = eX * mySize_x + eY * 0.2 * mySize_y;
 -                HUD_Panel_GetProgressBarColor(fuel);
 -                HUD_Panel_DrawProgressBar(barpos, barsize, "progressbar", 0, mod(baralign, 2), min(1, fuel/100), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
 +                              HUD_Panel_GetProgressBarColor(fuel);
 +                              if (is_vertical) //if vertical always halve x to not cover too much numbers with 3 digits
 +                                      mySize_x *= 0.2 * 0.5 / 2;
 +                              else
 +                                      mySize_y *= 0.2;
 +                              HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, (baralign == 1 || baralign == 3), progressbar_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
                        }
                }
                else
                {
 -            barsize = eX * 0.5 * mySize_x + eY * mySize_y;
 +            barsize = eX * mySize_x + eY * 0.5 * mySize_y;
                        if(leftactive)
                        {
 -                barpos = pos;
 -                              if(baralign == 1 || baralign == 3) { // right align
 -                    barflip = 1;
 -                              } else { // left align
 -                    barflip = 0;
 -                              }
 -
 -                              if(iconalign == 1 || iconalign == 3) { // down align
 -                                      picpos = pos + eX * 0.05 * mySize_x + eY * (mySize_y - 0.65 * mySize_x);
 -                                      numpos = pos + eY * mySize_y - eY * 0.25 * mySize_x;
 -                              } else { // up align
 -                                      picpos = pos + eX * 0.05 * mySize_x;
 -                                      numpos = pos + eY * 0.4 * mySize_x;
 -                              }
 -
 -                              if(progressbar)
 +                              if(autocvar_hud_panel_healtharmor_progressbar)
                                {
                                        HUD_Panel_GetProgressBarColorForString(leftname);
 -                    HUD_Panel_DrawProgressBar(barpos, barsize, leftprogressname, 1, barflip, min(1, leftcnt/leftmax), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      HUD_Panel_DrawProgressBar(pos, barsize, leftprogressname, leftcnt/leftmax, is_vertical, (baralign == 1 || baralign == 2), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                                }
 -                if(autocvar_hud_panel_healtharmor_text)
 -                {
 -                    drawpic_aspect_skin(picpos, leftname, '0.4 0.4 0' * mySize_x, '1 1 1', leftalpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 -                    drawstring_aspect(numpos, ftos(leftcnt), eX * 0.5 * mySize_x + eY * 0.25 * mySize_x, HUD_Get_Num_Color(leftcnt, leftmax), panel_fg_alpha, DRAWFLAG_NORMAL);
 -                }
 +                              if(autocvar_hud_panel_healtharmor_text)
 +                                      DrawNumIcon(pos, barsize, leftcnt, leftname, is_vertical, (iconalign == 1 || iconalign == 2), HUD_Get_Num_Color(leftcnt, leftmax), 1);
                        }
  
                        if(rightactive)
                        {
 -                barpos = pos + eX * 0.5 * mySize_x;
 -                              if(baralign == 0 || baralign == 3) { // left align
 -                    barflip = 0;
 -                              } else { // right align
 -                    barflip = 1;
 -                              }
 -
 -                              if(iconalign == 0 || iconalign == 3) { // up align
 -                                      picpos = pos + eX * 0.05 * mySize_x + eX * 0.5 * mySize_x;
 -                                      numpos = pos + eY * 0.4 * mySize_x + eX * 0.5 * mySize_x;
 -                              } else { // down align
 -                                      picpos = pos + eX * 0.05 * mySize_x + eY * (mySize_y - 0.65 * mySize_x) + eX * 0.5 * mySize_x;
 -                                      numpos = pos + eY * mySize_y - eY * 0.25 * mySize_x + eX * 0.5 * mySize_x;
 -                              }
 -
 -                              if(progressbar)
 +                              if(autocvar_hud_panel_healtharmor_progressbar)
                                {
                                        HUD_Panel_GetProgressBarColorForString(rightname);
 -                    HUD_Panel_DrawProgressBar(barpos, barsize, rightprogressname, 1, barflip, min(1, rightcnt/rightmax), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      HUD_Panel_DrawProgressBar(pos + eY * 0.5 * mySize_y, barsize, rightprogressname, rightcnt/rightmax, is_vertical, (baralign == 1 || baralign == 3), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                                }
 -                if(autocvar_hud_panel_healtharmor_text)
 -                {
 -                    drawpic_aspect_skin(picpos, rightname, '0.4 0.4 0' * mySize_x, '1 1 1', rightalpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 -                    drawstring_aspect(numpos, ftos(rightcnt), eX * 0.5 * mySize_x + eY * 0.25 * mySize_x, HUD_Get_Num_Color(rightcnt, rightmax), panel_fg_alpha, DRAWFLAG_NORMAL);
 -                }
 +                              if(autocvar_hud_panel_healtharmor_text)
 +                                      DrawNumIcon(pos + eY * 0.5 * mySize_y, barsize, rightcnt, rightname, is_vertical, (iconalign == 1 || iconalign == 3), HUD_Get_Num_Color(rightcnt, rightmax), 1);
                        }
  
                        if(fuel)
                        {
 -                barpos = pos;
 -                barsize = eX * 0.05 * mySize_x + eY * mySize_y;
 -                HUD_Panel_GetProgressBarColor(fuel);
 -                HUD_Panel_DrawProgressBar(barpos, barsize, "progressbar", 1, mod(baralign, 2), min(1, fuel/100), progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
 +                              HUD_Panel_GetProgressBarColor(fuel);
 +                              if (is_vertical) //if vertical always halve x to not cover numbers with 3 digits
 +                                      mySize_x *= 0.2 / 2;
 +                              else
 +                                      mySize_y *= 0.2 * 0.5;
 +                              HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, (baralign == 1 || baralign == 3), progressbar_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
                        }
                }
        }
@@@ -3102,13 -3129,10 +3103,13 @@@ void HUD_Centerprint(string s1, string 
  
  void HUD_Notify (void)
  {
 -      if(!autocvar_hud_panel_notify && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_notify) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_NOTIFY;
  
 -      active_panel = HUD_PANEL_NOTIFY;
        HUD_Panel_UpdateCvars(notify);
        vector pos, mySize;
        pos = panel_pos;
@@@ -3418,13 -3442,10 +3419,13 @@@ string seconds_tostring(float sec
  
  void HUD_Timer(void)
  {
 -      if(!autocvar_hud_panel_timer && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_timer) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_TIMER;
  
 -      active_panel = HUD_PANEL_TIMER;
        HUD_Panel_UpdateCvars(timer);
        vector pos, mySize;
        pos = panel_pos;
  //
  void HUD_Radar(void)
  {
 -      if ((autocvar_hud_panel_radar == 0 || (autocvar_hud_panel_radar != 2 && !teamplay)) && !autocvar__hud_configure)
 -              return;
 +      if (!autocvar__hud_configure)
 +      {
 +              if (autocvar_hud_panel_radar == 0) return;
 +              if (autocvar_hud_panel_radar != 2 && !teamplay) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_RADAR;
  
 -      active_panel = HUD_PANEL_RADAR;
        HUD_Panel_UpdateCvars(radar);
        vector pos, mySize;
        pos = panel_pos;
                mySize -= '2 2 0' * panel_bg_padding;
        }
  
 -      local float color1, color2; // color already declared as a global in hud.qc
 -      local vector rgb;
 +      local float color2;
        local entity tm;
        float scale2d, normalsize, bigsize;
        float f;
        if(hud_panel_radar_rotation == 0)
        {
                // max-min distance must fit the radar in any rotation
-               bigsize = vlen_minnorm2d(teamradar_size2d) * scale2d / (1.05 * vlen2d(mi_max - mi_min));
+               bigsize = vlen_minnorm2d(teamradar_size2d) * scale2d / (1.05 * vlen2d(mi_scale));
        }
        else
        {
                  f * bigsize
                + (1 - f) * normalsize;
        teamradar_origin3d_in_texcoord = teamradar_3dcoord_to_texcoord(
-                 f * (mi_min + mi_max) * 0.5
+                 f * mi_center
                + (1 - f) * view_origin);
  
 -      color1 = GetPlayerColor(player_localentnum-1);
 -      rgb = GetTeamRGB(color1);
 -
        drawsetcliparea(
                pos_x,
                pos_y,
  
  // Score (#7)
  //
 +void HUD_UpdatePlayerTeams();
  void HUD_Score(void)
  {
 -      if(!autocvar_hud_panel_score && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_score) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_SCORE;
  
 -      active_panel = HUD_PANEL_SCORE;
        HUD_Panel_UpdateCvars(score);
        vector pos, mySize;
        pos = panel_pos;
                mySize -= '2 2 0' * panel_bg_padding;
        }
  
 -      float score, distribution, leader;
 +      float score, distribution;
        string sign;
        vector distribution_color;
        entity tm, pl, me;
                drawstring_aspect(pos, timer, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                drawfont = hud_font;
        } else if (!teamplay) { // non-teamgames
 +              if ((spectatee_status == -1 && !autocvar__hud_configure) || autocvar_hud_panel_score_rankings)
 +              {
 +#define SCOREPANEL_MAX_ENTRIES 6
 +#define SCOREPANEL_ASPECTRATIO 2
 +                      const float entries = bound(1, floor(SCOREPANEL_MAX_ENTRIES * mySize_y/mySize_x * SCOREPANEL_ASPECTRATIO), SCOREPANEL_MAX_ENTRIES);
 +                      const float height = mySize_y/entries;
 +                      const vector fontsize = '0.9 0.9 0' * height;
 +                      pos_y += height * (1 - 0.9) / 2;
 +
 +                      vector rgb;
 +                      rgb = '1 1 1';
 +
 +                      const float name_size = mySize_x*0.75;
 +                      const float highlight_alpha = 0.2;
 +                      float i, me_printed;
 +                      string s;
 +                      if (autocvar__hud_configure)
 +                      {
 +                              score = 10 + SCOREPANEL_MAX_ENTRIES * 3;
 +                              for (i=0; i<entries; ++i)
 +                              {
 +                                      //simulate my score is lower than all displayed players,
 +                                      //so that I don't appear at all showing pure rankings.
 +                                      //This is to better show the difference between the 2 ranking views
 +                                      if (i == entries-1 && autocvar_hud_panel_score_rankings == 1)
 +                                      {
 +                                              rgb = '1 1 0';
 +                                              drawfill(pos - eY * (height * (1 - 0.9) / 2), eX * mySize_x + eY * height, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                              s = GetPlayerName(pl.sv_entnum);
 +                                              score = 7;
 +                                      }
 +                                      else
 +                                      {
 +                                              s = strcat("Player", ftos(i+1));
 +                                              score -= 3;
 +                                      }
 +
 +                                      s = textShortenToWidth(s, name_size, fontsize, stringwidth_colors);
 +                                      drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, TRUE, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      drawstring(pos + eX * mySize_x*0.79, ftos(score), fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +                                      pos_y += height;
 +                              }
 +                              return;
 +                      }
 +
 +                      if (!scoreboard_fade_alpha) // the scoreboard too calls HUD_UpdatePlayerTeams
 +                              HUD_UpdatePlayerTeams();
 +
 +                      for (pl = players.sort_next, i=0; pl && i<entries; pl = pl.sort_next, ++i)
 +                      {
 +                              if (pl.team == COLOR_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 != COLOR_SPECTATOR)
 +                                                      break;
 +
 +                                      if (pl)
 +                                              rgb = '1 1 0'; //not last but not among the leading players: yellow
 +                                      else
 +                                              rgb = '1 0 0'; //last: red
 +                                      pl = me;
 +                              }
 +
 +                              if (pl == me)
 +                              {
 +                                      if (i == 0)
 +                                              rgb = '0 1 0'; //first: green
 +                                      me_printed = 1;
 +                                      drawfill(pos - eY * (height * (1 - 0.9) / 2), eX * mySize_x + eY * height, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              }
 +                              s = textShortenToWidth(GetPlayerName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
 +                              drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, TRUE, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring(pos + eX * mySize_x*0.79, ftos(pl.(scores[ps_primary])), fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              pos_y += height;
 +                      }
 +                      return;
 +              }
                // me vector := [team/connected frags id]
                pl = players.sort_next;
                if(pl == me)
                if(autocvar__hud_configure)
                        score = 123;
  
 -              if(distribution >= 5) {
 +              if(distribution >= 5)
                        distribution_color = eY;
 -                      leader = 1;
 -              } else if(distribution >= 0) {
 +              else if(distribution >= 0)
                        distribution_color = '1 1 1';
 -                      leader = 1;
 -              } else if(distribution >= -5)
 +              else if(distribution >= -5)
                        distribution_color = '1 1 0';
                else
                        distribution_color = eX;
  
 -              drawstring_aspect(pos + eX * 0.75 * mySize_x, ftos(distribution), eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
 -              if (leader)
 +              string distribution_str;
 +              distribution_str = ftos(distribution);
 +              if (distribution >= 0)
 +              {
 +                      if (distribution > 0)
 +                              distribution_str = strcat("+", distribution_str);
                        HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +              }
                drawfont = hud_bigfont;
                drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
                drawfont = hud_font;
 +              drawstring_aspect(pos + eX * 0.75 * mySize_x, distribution_str, eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
        } else { // teamgames
                float max_fragcount;
                max_fragcount = -99;
  
 -              float teamnum;
 +              float scores_count, row, column, rows, columns;
 +              vector offset;
 +              vector score_pos, score_size; //for scores other than myteam
 +              if (spectatee_status == -1)
 +              {
 +                      if (autocvar__hud_configure)
 +                              scores_count = 4;
 +                      else for(tm = teams.sort_next; tm; tm = tm.sort_next) {
 +                              if(tm.team == COLOR_SPECTATOR)
 +                                      continue;
 +                              ++scores_count;
 +                      }
 +                      rows = mySize_y/mySize_x;
 +                      rows = bound(1, floor((sqrt(4 * (3/1) * rows * scores_count + rows * rows) + rows + 0.5) / 2), scores_count);
 +                      //                               ^^^ ammo item aspect goes here
 +
 +                      columns = ceil(scores_count/rows);
 +
 +                      score_size = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
 +
 +                      float newSize;
 +                      if(score_size_x/score_size_y > 3)
 +                      {
 +                              newSize = 3 * score_size_y;
 +                              offset_x = score_size_x - newSize;
 +                              pos_x += offset_x/2;
 +                              score_size_x = newSize;
 +                      }
 +                      else
 +                      {
 +                              newSize = 1/3 * score_size_x;
 +                              offset_y = score_size_y - newSize;
 +                              pos_y += offset_y/2;
 +                              score_size_y = newSize;
 +                      }
 +              }
 +              else
 +                      score_size = eX * mySize_x*(1/4) + eY * mySize_y*(1/3);
                for(tm = teams.sort_next; tm; tm = tm.sort_next) {
 -                      if(tm.team == COLOR_SPECTATOR || (!tm.team_size && !autocvar__hud_configure)) // no players? don't display
 +                      if(tm.team == COLOR_SPECTATOR)
                                continue;
                        score = tm.(teamscores[ts_primary]);
                        if(autocvar__hud_configure)
                                score = 123;
 -                      leader = 0;
                        
                        if (score > max_fragcount)
                                max_fragcount = score;
  
 -                      if(tm.team == myteam) {
 +                      if (spectatee_status == -1)
 +                      {
 +                              score_pos = pos + eX * column * (score_size_x + offset_x) + eY * row * (score_size_y + offset_y);
 +                              if (max_fragcount == score)
 +                                      HUD_Panel_DrawHighlight(score_pos, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawfont = hud_bigfont;
 +                              drawstring_aspect(score_pos, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawfont = hud_font;
 +                              ++row;
 +                              if(row >= rows)
 +                              {
 +                                      row = 0;
 +                                      ++column;
 +                              }
 +                      }
 +                      else if(tm.team == myteam) {
                                if (max_fragcount == score)
 -                                      leader = 1;
 -                              if (leader)
                                        HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                                drawfont = hud_bigfont;
                                drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                                drawfont = hud_font;
                        } else {
                                if (max_fragcount == score)
 -                                      leader = 1;
 -                              if (leader)
 -                                      HUD_Panel_DrawHighlight(pos + eX * 0.75 * mySize_x + eY * (1/3) * teamnum * mySize_y, eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              drawstring_aspect(pos + eX * 0.75 * mySize_x + eY * (1/3) * teamnum * mySize_y, ftos(score), eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              teamnum += 1;
 +                                      HUD_Panel_DrawHighlight(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring_aspect(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              ++rows;
                        }
                }
        }
  
  // Race timer (#8)
  //
 -void HUD_RaceTimer (void) {
 -      if(!autocvar_hud_panel_racetimer && !(gametype == GAME_RACE || gametype == GAME_CTS) && !autocvar__hud_configure)
 -              return;
 +void HUD_RaceTimer (void)
 +{
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_racetimer) return;
 +              if(!(gametype == GAME_RACE || gametype == GAME_CTS)) return;
 +              if(spectatee_status == -1) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_RACETIMER;
  
 -      active_panel = HUD_PANEL_RACETIMER;
        HUD_Panel_UpdateCvars(racetimer);
        vector pos, mySize;
        pos = panel_pos;
@@@ -4028,24 -3907,19 +4029,24 @@@ float vote_change; // "time" when vote_
  
  void HUD_VoteWindow(void) 
  {
 -    uid2name_dialog = 0;
        if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
        {
                vote_active = 1;
 -              vote_called_vote = strzone(strcat("^2Name ^7instead of \"^1Unregistered player\"", " ^7in stats"));
 -        uid2name_dialog = 1;
 +              if (autocvar__hud_configure)
 +              {
 +                      vote_yescount = 0;
 +                      vote_nocount = 0;
 +                      print("^1You have to answer before entering hud configure mode\n");
 +                      cvar_set("_hud_configure", "0");
 +              }
 +              vote_called_vote = strzone("^2Name ^7instead of \"^1Unregistered player^7\" in stats");
 +              uid2name_dialog = 1;
        }
  
 -      if(!autocvar_hud_panel_vote && !autocvar__hud_configure)
 -              return;
 -
        if(!autocvar__hud_configure)
        {
 +              if(!autocvar_hud_panel_vote) return;
 +
                panel_fg_alpha = autocvar_hud_panel_fg_alpha;
                panel_bg_alpha_str = autocvar_hud_panel_vote_bg_alpha;
  
                }
                panel_bg_alpha = stof(panel_bg_alpha_str);
        }
 +      else
 +      {
 +              hud_configure_active_panel = HUD_PANEL_VOTE;
 +
 +              vote_yescount = 3;
 +              vote_nocount = 2;
 +              vote_needed = 4;
 +      }
  
        string s;
        float a;
        else
                vote_alpha = bound(0, 1 - (time - vote_change) * 2, 1);
  
 -      if(autocvar__hud_configure)
 -      {
 -              vote_yescount = 3;
 -              vote_nocount = 2;
 -              vote_needed = 4;
 -      }
 -
        if(!vote_alpha)
                return;
  
 -      active_panel = HUD_PANEL_VOTE;
        HUD_Panel_UpdateCvars(vote);
  
        if(uid2name_dialog)
@@@ -4560,11 -4434,17 +4561,11 @@@ void HUD_Mod_NexBall(vector pos, vecto
                        p = 2 - p;
  
                //Draw the filling
 -              float vertical;
 +              HUD_Panel_GetProgressBarColor(nexball);
                if(mySize_x > mySize_y)
 -              {
 -                      vertical = 0;
 -              }
 +                      HUD_Panel_DrawProgressBar(pos, mySize, "statusbar", p, 0, 0, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                else
 -              {
 -                      vertical = 1;
 -              }
 -              HUD_Panel_GetProgressBarColor(nexball);
 -        HUD_Panel_DrawProgressBar(pos, mySize, "statusbar", vertical, 0, p, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      HUD_Panel_DrawProgressBar(pos, mySize, "statusbar", p, 1, 0, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
        }
  
        if (stat_items & IT_KEY1)
@@@ -4725,14 -4605,13 +4726,14 @@@ float mod_change; // "time" when mod_ac
  
  void HUD_ModIcons(void)
  {
 -      if(!autocvar_hud_panel_modicons && !autocvar__hud_configure)
 -              return;
 -
 -      if (gametype != GAME_KEYHUNT && gametype != GAME_CTF && gametype != GAME_NEXBALL && gametype != GAME_CTS && gametype != GAME_RACE && gametype != GAME_CA && gametype != GAME_FREEZETAG && gametype != GAME_KEEPAWAY && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_modicons) return;
 +              if (gametype != GAME_CTF && gametype != GAME_KEYHUNT && gametype != GAME_NEXBALL && gametype != GAME_CTS && gametype != GAME_RACE && gametype != GAME_CA && gametype != GAME_FREEZETAG && gametype != GAME_KEEPAWAY) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_MODICONS;
  
 -      active_panel = HUD_PANEL_MODICONS;
        HUD_Panel_UpdateCvars(modicons);
        vector pos, mySize;
        pos = panel_pos;
  //
  void HUD_DrawPressedKeys(void)
  {
 -      if(!autocvar_hud_panel_pressedkeys && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_pressedkeys) return;
 +              if(spectatee_status <= 0 && autocvar_hud_panel_pressedkeys < 2) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_PRESSEDKEYS;
  
 -      if(!(spectatee_status > 0 || autocvar_hud_panel_pressedkeys >= 2 || autocvar__hud_configure))
 -              return;
  
 -      active_panel = HUD_PANEL_PRESSEDKEYS;
        HUD_Panel_UpdateCvars(pressedkeys);
        vector pos, mySize;
        pos = panel_pos;
        vector keysize;
        keysize = eX * mySize_x * (1/3) + eY * mySize_y * 0.5;
        float pressedkeys;
 -
        pressedkeys = getstatf(STAT_PRESSED_KEYS);
 +
        drawpic_aspect_skin(pos, ((pressedkeys & KEY_CROUCH) ? "key_crouch_inv.tga" : "key_crouch.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -      drawpic_aspect_skin(pos + eX * mySize_x * (1/3), ((pressedkeys & KEY_FORWARD) ? "key_forward_inv.tga" : "key_forward.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -      drawpic_aspect_skin(pos + eX * mySize_x * (2/3), ((pressedkeys & KEY_JUMP) ? "key_jump_inv.tga" : "key_jump.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -      drawpic_aspect_skin(pos + eY * 0.5 * mySize_y, ((pressedkeys & KEY_LEFT) ? "key_left_inv.tga" : "key_left.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -      drawpic_aspect_skin(pos + eY * 0.5 * mySize_y + eX * mySize_x * (1/3), ((pressedkeys & KEY_BACKWARD) ? "key_backward_inv.tga" : "key_backward.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -      drawpic_aspect_skin(pos + eY * 0.5 * mySize_y + eX * mySize_x * (2/3), ((pressedkeys & KEY_RIGHT) ? "key_right_inv.tga" : "key_right.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      drawpic_aspect_skin(pos + eX * keysize_x, ((pressedkeys & KEY_FORWARD) ? "key_forward_inv.tga" : "key_forward.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      drawpic_aspect_skin(pos + eX * keysize_x * 2, ((pressedkeys & KEY_JUMP) ? "key_jump_inv.tga" : "key_jump.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      pos_y += keysize_y;
 +      drawpic_aspect_skin(pos, ((pressedkeys & KEY_LEFT) ? "key_left_inv.tga" : "key_left.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      drawpic_aspect_skin(pos + eX * keysize_x, ((pressedkeys & KEY_BACKWARD) ? "key_backward_inv.tga" : "key_backward.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      drawpic_aspect_skin(pos + eX * keysize_x * 2, ((pressedkeys & KEY_RIGHT) ? "key_right_inv.tga" : "key_right.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
  }
  
  // Handle chat as a panel (#12)
  //
  void HUD_Chat(void)
  {
 -      if(!autocvar_hud_panel_chat && !autocvar__hud_configure)
 +      if(!autocvar__hud_configure)
        {
 -              cvar_set("con_chatrect", "0");
 -              return;
 +              if (!autocvar_hud_panel_chat)
 +              {
 +                      if (!autocvar_con_chatrect)
 +                              cvar_set("con_chatrect", "0");
 +                      return;
 +              }
        }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_CHAT;
  
 -      active_panel = HUD_PANEL_CHAT;
        HUD_Panel_UpdateCvars(chat);
  
        if(autocvar__con_chat_maximized && !autocvar__hud_configure) // draw at full screen height if maximized
                mySize -= '2 2 0' * panel_bg_padding;
        }
  
 -      cvar_set("con_chatrect", "1");
 +      if (!autocvar_con_chatrect)
 +              cvar_set("con_chatrect", "1");
  
        cvar_set("con_chatrect_x", ftos(pos_x/vid_conwidth));
        cvar_set("con_chatrect_y", ftos(pos_y/vid_conheight));
  
        if(autocvar__hud_configure)
        {
 -              float chatsize;
 -              chatsize = autocvar_con_chatsize;
 +              vector chatsize;
 +              chatsize = '1 1 0' * autocvar_con_chatsize;
                cvar_set("con_chatrect_x", "9001"); // over 9000, we'll fake it instead for more control over alpha and such
                float i, a;
                for(i = 0; i < autocvar_con_chat; ++i)
                                a = panel_fg_alpha;
                        else
                                a = panel_fg_alpha * floor(((i + 1) * 7 + autocvar_con_chattime)/45);
 -                      drawcolorcodedstring(pos + eY * i * chatsize, textShortenToWidth("^3Player^7: This is the chat area.", mySize_x, '1 1 0' * chatsize, stringwidth_colors), '1 1 0' * chatsize, a, DRAWFLAG_NORMAL);
 +                      drawcolorcodedstring(pos, textShortenToWidth("^3Player^7: This is the chat area.", mySize_x, chatsize, stringwidth_colors), chatsize, a, DRAWFLAG_NORMAL);
 +                      pos_y += chatsize_y;
                }
        }
  }
@@@ -4917,13 -4786,10 +4918,13 @@@ float frametimeavg1; // 1 frame ag
  float frametimeavg2; // 2 frames ago
  void HUD_EngineInfo(void)
  {
 -      if(!autocvar_hud_panel_engineinfo && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_engineinfo) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_ENGINEINFO;
  
 -      active_panel = HUD_PANEL_ENGINEINFO;
        HUD_Panel_UpdateCvars(engineinfo);
        vector pos, mySize;
        pos = panel_pos;
        o_y += fontsize_y;
  void HUD_InfoMessages(void)
  {
 -      if(!autocvar_hud_panel_infomessages && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_infomessages) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_INFOMESSAGES;
  
 -      active_panel = HUD_PANEL_INFOMESSAGES;
        HUD_Panel_UpdateCvars(infomessages);
        vector pos, mySize;
        pos = panel_pos;
        }
  }
  
 -/*
 -==================
 -Main HUD system
 -==================
 -*/
 +// Physics panel (#15)
 +//
 +vector acc_prevspeed;
 +float acc_prevtime, acc_avg, top_speed, top_speed_time;
  
 -void HUD_ShowSpeed(void)
 +void HUD_Physics(void)
  {
 -      vector numsize;
 -      float pos, conversion_factor;
 -      string speed, zspeed, unit;
 +      if(!autocvar_hud_panel_physics)
 +      {
 +              if(!autocvar__hud_configure) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_PHYSICS;
 +
 +      HUD_Panel_UpdateCvars(physics);
 +
 +      HUD_Panel_DrawBg(1);
 +      if(panel_bg_padding)
 +      {
 +              panel_pos += '1 1 0' * panel_bg_padding;
 +              panel_size -= '2 2 0' * panel_bg_padding;
 +      }
 +
 +      //compute speed
 +      float speed, conversion_factor;
 +      string unit;
  
        switch(autocvar_cl_showspeed_unit)
        {
                default:
 -              case 0:
 -                      unit = "";
 -                      conversion_factor = 1.0;
 -                      break;
                case 1:
 -                      unit = " qu/s";
 +                      unit = "qu/s";
                        conversion_factor = 1.0;
                        break;
                case 2:
 -                      unit = " m/s";
 +                      unit = "m/s";
                        conversion_factor = 0.0254;
                        break;
                case 3:
 -                      unit = " km/h";
 +                      unit = "km/h";
                        conversion_factor = 0.0254 * 3.6;
                        break;
                case 4:
 -                      unit = " mph";
 +                      unit = "mph";
                        conversion_factor = 0.0254 * 3.6 * 0.6213711922;
                        break;
                case 5:
 -                      unit = " knots";
 +                      unit = "knots";
                        conversion_factor = 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
                        break;
        }
  
 -      speed = strcat(ftos(floor( vlen(pmove_vel - pmove_vel_z * '0 0 1') * conversion_factor + 0.5 )), unit);
 +      float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
 +      if (autocvar__hud_configure)
 +              speed = floor( max_speed * 0.65 + 0.5 );
 +      else if(autocvar_hud_panel_physics_speed_z)
 +              speed = floor( vlen(pmove_vel) * conversion_factor + 0.5 );
 +      else
 +              speed = floor( vlen(pmove_vel - pmove_vel_z * '0 0 1') * conversion_factor + 0.5 );
  
 -      numsize_x = numsize_y = autocvar_cl_showspeed_size;
 -      pos = (vid_conheight - numsize_y) * autocvar_cl_showspeed_position;
 +      //compute acceleration
 +      float acceleration, f;
 +      if (autocvar__hud_configure)
 +              acceleration = autocvar_hud_panel_physics_acceleration_max * 0.3;
 +      else
 +      {
 +              f = time - acc_prevtime;
 +              if(autocvar_hud_panel_physics_acceleration_z)
 +                      acceleration = (vlen(pmove_vel) - vlen(acc_prevspeed)) * (1 / f);
 +              else
 +                      acceleration = (vlen(pmove_vel - '0 0 1' * pmove_vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z)) * (1 / f);
 +              acc_prevspeed = pmove_vel;
 +              acc_prevtime = time;
  
 -      drawfont = hud_bigfont;
 -      drawstringcenter(eX + pos * eY, speed, numsize, '1 1 1', autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL);
 +              f = bound(0, f * 10, 1);
 +              acc_avg = acc_avg * (1 - f) + acceleration * f;
 +              acceleration = acc_avg / getstatf(STAT_MOVEVARS_MAXSPEED);
 +      }
  
 -      if (autocvar_cl_showspeed_z == 1) {
 -              zspeed = strcat(ftos(fabs(floor( pmove_vel_z * conversion_factor + 0.5 ))), unit);
 -              drawstringcenter(eX + pos * eY + numsize_y * eY, zspeed, numsize * 0.5, '1 1 1', autocvar_hud_panel_fg_alpha * hud_fade_alpha, DRAWFLAG_NORMAL);
 +      //compute layout
 +      drawfont = hud_bigfont;
 +      float panel_ar = panel_size_x/panel_size_y;
 +      vector speed_offset, acceleration_offset;
 +      if (panel_ar >= 5)
 +      {
 +              panel_size_x *= 0.5;
 +              if (autocvar_hud_panel_physics_flip)
 +                      speed_offset_x = panel_size_x;
 +              else
 +                      acceleration_offset_x = panel_size_x;
 +      }
 +      else
 +      {
 +              panel_size_y *= 0.5;
 +              if (autocvar_hud_panel_physics_flip)
 +                      speed_offset_y = panel_size_y;
 +              else
 +                      acceleration_offset_y = panel_size_y;
 +      }
 +      float speed_baralign, acceleration_baralign;
 +      if (autocvar_hud_panel_physics_baralign == 1)
 +              acceleration_baralign = speed_baralign = 1;
 +      else if (autocvar_hud_panel_physics_flip)
 +      {
 +              acceleration_baralign = (autocvar_hud_panel_physics_baralign == 2);
 +              speed_baralign = (autocvar_hud_panel_physics_baralign == 3);
 +      }
 +      else
 +      {
 +              speed_baralign = (autocvar_hud_panel_physics_baralign == 2);
 +              acceleration_baralign = (autocvar_hud_panel_physics_baralign == 3);
        }
  
 -      drawfont = hud_font;
 -}
 +      //draw speed
 +      if(speed && autocvar_hud_panel_physics_progressbar)
 +      {
 +              HUD_Panel_GetProgressBarColor(speed);
 +              HUD_Panel_DrawProgressBar(panel_pos + speed_offset, panel_size, "progressbar", speed/max_speed, 0, speed_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +      }
  
 -vector acc_prevspeed;
 -float acc_prevtime;
 -float acc_avg;
 +      vector tmp_offset, tmp_size;
 +      tmp_size_x = panel_size_x * 0.75;
 +      tmp_size_y = panel_size_y;
 +      if (speed_baralign)
 +              tmp_offset_x = panel_size_x - tmp_size_x;
 +      //else
 +              //tmp_offset_x = 0;
 +      drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(speed), tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
  
 -void HUD_ShowAcceleration(void)
 -{
 -      float acceleration, sz, scale, alpha, f;
 -      vector pos, top, rgb;
 -      top_x = vid_conwidth/2;
 -      top_y = 0;
 -
 -      f = time - acc_prevtime;
 -      if(autocvar_cl_showacceleration_z)
 -              acceleration = (vlen(pmove_vel) - vlen(acc_prevspeed)) * (1 / f);
 +      //draw speed unit
 +      if (speed_baralign)
 +              tmp_offset_x = 0;
        else
 -              acceleration = (vlen(pmove_vel - '0 0 1' * pmove_vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z)) * (1 / f);
 -      acc_prevspeed = pmove_vel;
 -      acc_prevtime = time;
 -
 -      f = bound(0, f * 10, 1);
 -      acc_avg = acc_avg * (1 - f) + acceleration * f;
 -      acceleration = acc_avg / getstatf(STAT_MOVEVARS_MAXSPEED);
 -      if (acceleration == 0)
 -              return;
 +              tmp_offset_x = tmp_size_x;
 +      if (autocvar_hud_panel_physics_speed_unit_show)
 +      {
 +              //tmp_offset_y = 0;
 +              tmp_size_x = panel_size_x * (1 - 0.75);
 +              tmp_size_y = panel_size_y * 0.4;
 +              drawstring_aspect(panel_pos + speed_offset + tmp_offset, unit, tmp_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      }
  
 -      pos = top - sz/2 * eY + (autocvar_cl_showacceleration_position * vid_conheight) * eY;
 +      //compute and draw top speed
 +      if (autocvar_hud_panel_physics_topspeed)
 +      {
 +              if (autocvar__hud_configure)
 +              {
 +                      top_speed = floor( max_speed * 0.75 + 0.5 );
 +                      f = 1;
 +              }
 +              else
 +              {
 +                      if (speed >= top_speed)
 +                      {
 +                              top_speed = speed;
 +                              top_speed_time = time;
 +                      }
 +                      if (top_speed == 0) //hide top speed 0, it would be stupid
 +                              f = 0;
 +                      else
 +                      {
 +                              f = max(1, autocvar_hud_panel_physics_topspeed_time);
 +                              // divide by f to make it start from 1
 +                              f = cos( ((time - top_speed_time) / f) * PI/2 );
 +                      }
 +              }
 +              if (f > 0)
 +              {
 +                      //top speed progressbar peek
 +                      if(autocvar_hud_panel_physics_progressbar && speed < top_speed)
 +                      {
 +                              float peek_offset_x, peek_size_x;
 +                              if (speed_baralign)
 +                                      peek_offset_x = (1 - min(top_speed, max_speed)/max_speed) * panel_size_x;
 +                              else
 +                                      peek_offset_x = min(top_speed, max_speed)/max_speed * panel_size_x;
 +                              //if speed is not 0 the speed progressbar already fetched the color
 +                              if (speed == 0)
 +                                      HUD_Panel_GetProgressBarColor(speed);
 +                              peek_size_x = panel_size_x * 0.01;
 +                              drawfill(panel_pos + speed_offset + eX * (peek_offset_x - peek_size_x), eX * peek_size_x + eY * panel_size_y, progressbar_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      }
  
 -      sz = autocvar_cl_showacceleration_size;
 -      scale = autocvar_cl_showacceleration_scale;
 -      alpha = autocvar_cl_showacceleration_alpha;
 -      if (autocvar_cl_showacceleration_color_custom)
 -              rgb = stov(autocvar_cl_showacceleration_color);
 -      else {
 -              if (acceleration < 0)
 -                      rgb = '1 .5 .5' - '0 .5 .5' * bound(0, -acceleration * 0.2, 1);
 +                      //top speed
 +                      tmp_offset_y = panel_size_y * 0.4;
 +                      tmp_size_x = panel_size_x * (1 - 0.75);
 +                      tmp_size_y = panel_size_y - tmp_offset_y;
 +                      drawstring_aspect(panel_pos + speed_offset + tmp_offset, ftos(top_speed), tmp_size, '1 0 0', f * panel_fg_alpha, DRAWFLAG_NORMAL);
 +              }
                else
 -                      rgb = '.5 1 .5' - '.5 0 .5' * bound(0, +acceleration * 0.2, 1);
 +                      top_speed = 0;
        }
  
 -      if (acceleration > 0)
 -        HUD_Panel_DrawProgressBar(pos, eX * (vid_conwidth - pos_x) + eY * sz, "statusbar", 0, 0, acceleration * scale, rgb, alpha * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 -      else
 -        HUD_Panel_DrawProgressBar(eY * pos_y, eX * pos_x + eY * sz, "statusbar", 0, 1, -acceleration * scale, rgb, alpha * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +      //draw acceleration
 +      if(acceleration && autocvar_hud_panel_physics_progressbar)
 +      {
 +              if (acceleration < 0)
 +                      HUD_Panel_GetProgressBarColor(acceleration_neg);
 +              else
 +                      HUD_Panel_GetProgressBarColor(acceleration);
 +              HUD_Panel_DrawProgressBar(panel_pos + acceleration_offset, panel_size, "progressbar", fabs(acceleration)/autocvar_hud_panel_physics_acceleration_max, 0, acceleration_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +      }
 +      drawstring_aspect(panel_pos + acceleration_offset, ftos_decimals(acceleration, 3), panel_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      drawfont = hud_font;
  }
  
 +/*
 +==================
 +Main HUD system
 +==================
 +*/
 +
  void HUD_Reset (void)
  {
        // reset gametype specific icons
@@@ -5414,8 -5167,6 +5415,8 @@@ switch (id) {
                HUD_EngineInfo(); break;\
        case (HUD_PANEL_INFOMESSAGES):\
                 HUD_InfoMessages(); break;\
 +      case (HUD_PANEL_PHYSICS):\
 +               HUD_Physics(); break;\
  } ENDS_WITH_CURLY_BRACE
  
  void HUD_Main (void)
        else if(autocvar__menu_alpha == 0 && scoreboard_fade_alpha == 0)
                hud_fade_alpha = 1;
  
 -      hud_fontsize = HUD_GetFontsize("hud_fontsize");
 -
        if(!autocvar__hud_configure && !hud_fade_alpha)
                return;
  
        // HUD configure visible grid
        if(autocvar__hud_configure && autocvar_hud_configure_grid && autocvar_hud_configure_grid_alpha)
        {
 +              hud_configure_gridSize_x = bound(0.005, cvar("hud_configure_grid_xsize"), 0.2);
 +              hud_configure_gridSize_y = bound(0.005, cvar("hud_configure_grid_ysize"), 0.2);
 +              hud_configure_realGridSize_x = hud_configure_gridSize_x * vid_conwidth;
 +              hud_configure_realGridSize_y = hud_configure_gridSize_y * vid_conheight;
                // x-axis
 -              for(i = 0; i < 1/bound(0.005, autocvar_hud_configure_grid_xsize, 0.2); ++i)
 -              {
 -                      drawfill(eX * i * vid_conwidth * bound(0.005, autocvar_hud_configure_grid_xsize, 0.2), eX + eY * vid_conheight, '0.5 0.5 0.5', autocvar_hud_configure_grid_alpha, DRAWFLAG_NORMAL);
 -              }
 +              for(i = 0; i < 1/hud_configure_gridSize_x; ++i)
 +                      drawfill(eX * i * hud_configure_realGridSize_x, eX + eY * vid_conheight, '0.5 0.5 0.5', autocvar_hud_configure_grid_alpha, DRAWFLAG_NORMAL);
                // y-axis
 -              for(i = 0; i < 1/bound(0.005, autocvar_hud_configure_grid_ysize, 0.2); ++i)
 -              {
 -                      drawfill(eY * i * vid_conheight * bound(0.005, autocvar_hud_configure_grid_ysize, 0.2), eY + eX * vid_conwidth, '0.5 0.5 0.5', autocvar_hud_configure_grid_alpha, DRAWFLAG_NORMAL);
 -              }
 +              for(i = 0; i < 1/hud_configure_gridSize_y; ++i)
 +                      drawfill(eY * i * hud_configure_realGridSize_y, eY + eX * vid_conwidth, '0.5 0.5 0.5', autocvar_hud_configure_grid_alpha, DRAWFLAG_NORMAL);
        }
  
        // draw the dock
  
        // cache the panel order into the panel_order array
        if(autocvar__hud_panelorder != hud_panelorder_prev) {
 +              for(i = 0; i < HUD_PANEL_NUM; ++i)
 +                      panel_order[i] = -1;
 +              string s;
 +              float p_num, warning;
 +              float argc = tokenize_console(autocvar__hud_panelorder);
 +              if (argc > HUD_PANEL_NUM)
 +                      warning = true;
 +              //first detect wrong/missing panel numbers
 +              for(i = 0; i < HUD_PANEL_NUM; ++i) {
 +                      p_num = stof(argv(i));
 +                      if (p_num >= 0 && p_num < HUD_PANEL_NUM) { //correct panel number?
 +                              if (panel_order[p_num] == -1) //found for the first time?
 +                                      s = strcat(s, ftos(p_num), " ");
 +                              panel_order[p_num] = 1; //mark as found
 +                      }
 +                      else
 +                              warning = true;
 +              }
 +              for(i = 0; i < HUD_PANEL_NUM; ++i) {
 +                      if (panel_order[i] == -1) {
 +                              warning = true;
 +                              s = strcat(s, ftos(i), " "); //add missing panel number
 +                      }
 +              }
 +              if (warning)
 +                      print("Automatically fixed wrong/missing panel numbers in _hud_panelorder\n");
 +
 +              cvar_set("_hud_panelorder", s);
                if(hud_panelorder_prev)
                        strunzone(hud_panelorder_prev);
 -              hud_panelorder_prev = strzone(autocvar__hud_panelorder);
 -              tokenize_console(autocvar__hud_panelorder);
 +              hud_panelorder_prev = strzone(s);
 +
 +              //now properly set panel_order
 +              tokenize_console(s);
                for(i = 0; i < HUD_PANEL_NUM; ++i) {
                        panel_order[i] = stof(argv(i));
                }
        }
 +
        // draw panels in order specified by panel_order array
        for(i = HUD_PANEL_NUM - 1; i >= 0; --i) {
                if(i != HUD_PANEL_CHAT || !autocvar__con_chat_maximized) // don't draw maximized chat panel twice!
        if(autocvar__con_chat_maximized)
                HUD_Chat(); // HUD_DrawPanel(HUD_PANEL_CHAT);
  
 -      // TODO hud_'ify these
 -      if (autocvar_cl_showspeed)
 -              HUD_ShowSpeed();
 -      if (autocvar_cl_showacceleration)
 -              HUD_ShowAcceleration();
 -
        if (autocvar__hud_configure && spectatee_status && hud_configure_prev == -1) // try to join if we are in hud_configure mode, but still spectating, and in the first frame (in order to get rid of motd when launching a server via the menu "HUD Setup" button)
                localcmd("cmd selectteam auto; cmd join\n");
  
 +      if(autocvar__hud_configure && tab_panel != -1)
 +      {
 +              HUD_Panel_UpdatePosSizeForId(tab_panel)
 +              drawfill(panel_pos - '1 1 0' * panel_bg_border, panel_size + '2 2 0' * panel_bg_border, '1 1 1', .2, DRAWFLAG_NORMAL);
 +      }
 +
        hud_configure_prev = autocvar__hud_configure;
  
        if (!autocvar__hud_configure) // hud config mode disabled, enable normal alpha stuff again
index 0896689749f2f7329d95b218a2be577f35af879c,31cdc45bfa04b4bcffe5697e0bbf47d4fcc4ccec..7de456043afd6dad71a155ffaabca3d3e9c0ebf3
@@@ -883,8 -883,10 +883,10 @@@ float HUD_WouldDrawScoreboard() 
                return 1;
        else if (intermission == 1)
                return 1;
-       else if (spectatee_status != -1 && getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard)
 -      else if (getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != GAME_CTS)
++      else if (spectatee_status != -1 && getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != GAME_CTS)
                return 1;
+     else if (spectatee_status == -1)
+         return 1;
        else if (scoreboard_showscores_force)
                return 1;
        return 0;
diff --combined qcsrc/common/util.qh
index f46dc6535db74dc51a8e55938ee6dd85c0128e23,79b93d3ede3d238d5e6d8ad4eaf4f787aa331ea0..ec0d833fa7a0b37dcd1abe7e119e7df2829b0352
@@@ -219,7 -219,6 +219,7 @@@ float get_model_parameters(string mod, 
  switch(id) {\
        case HUD_PANEL_ENGINEINFO: panel_name = HUD_PANELNAME_ENGINEINFO; break; \
        case HUD_PANEL_INFOMESSAGES: panel_name = HUD_PANELNAME_INFOMESSAGES; break; \
 +      case HUD_PANEL_PHYSICS: panel_name = HUD_PANELNAME_PHYSICS; break; \
  } ENDS_WITH_CURLY_BRACE
  
  // Get name of specified panel id
@@@ -248,3 -247,5 +248,5 @@@ vector NearestPointOnBox(entity box, ve
  #endif
  
  float vercmp(string v1, string v2);
+ float u8_strsize(string s);