]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/master' into fruitiex/panelhud
authorFruitieX <fruitiex@gmail.com>
Sun, 1 May 2011 10:44:52 +0000 (13:44 +0300)
committerFruitieX <fruitiex@gmail.com>
Sun, 1 May 2011 10:44:52 +0000 (13:44 +0300)
Conflicts:
qcsrc/common/constants.qh
qcsrc/server/cl_client.qc

13 files changed:
1  2 
defaultXonotic.cfg
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/scoreboard.qc
qcsrc/common/constants.qh
qcsrc/menu/xonotic/util.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/defs.qh
qcsrc/server/domination.qc
qcsrc/server/miscfunctions.qc

diff --combined defaultXonotic.cfg
index 80dc21befbf92734b1f9715aa3ddac5856f9e15e,65a6554e0a282854f0bc839930a4023077d375c5..d725d5e1f9e1a8a1c83103cea64a866079a40626
@@@ -242,7 -242,7 +242,7 @@@ v_deathtilt 0 // needed for spectators 
  
  // these settings determine how much the view is affected by movement/damage
  cl_smoothviewheight 0.05 // time of the averaging to the viewheight value so that it creates a smooth transition for crouching and such. 0 for instant transition
- cl_deathfade 1 // fade screen to dark red when dead, value represents how fast the fade is (higher is faster)
+ cl_deathfade 0 // fade screen to dark red when dead, value represents how fast the fade is (higher is faster)
  cl_bobcycle 0 // how long the cycle of up/down view movement takes (only works if cl_bob is not 0), default is 0.6
  cl_bob 0.01 // how much view moves up/down when moving (does not move if cl_bobcycle is 0, but still enables cl_bobmodel), default is 0.02
  cl_bob2cycle 0 // how long the cycle of left/right view movement takes (only works if cl_bob2 is not 0), default is 0.6
@@@ -316,6 -316,11 +316,11 @@@ set sv_ready_restart_repeatable 0        "allo
  seta cl_hitsound 1 "play a hit notifier sound when you have hit an enemy"
  set cl_hitsound_antispam_time 0.05 "don't play the hitsound more often than this"
  
+ seta cl_eventchase_death 0 "camera goes into 3rd person mode when the player is dead"
+ seta cl_eventchase_intermission 0 "camera goes into 3rd person mode when the match ends"
+ seta cl_eventchase_distance 140 "final camera distance"
+ seta cl_eventchase_speed 1.3 "how fast the camera slides back, 0 is instant"
  //nifreks lockonrestart feature, used in team-based game modes, if set to 1 and all players readied up no other player can then join the game anymore, useful to block spectators from joining
  set teamplay_lockonrestart 0 "it set to 1 in a team-based game, the teams are locked once all players readied up and the game restarted (no new players can join after restart unless using the server-command unlockteams)"
  
@@@ -402,8 -407,6 +407,8 @@@ net_connecttimeout 3
  sv_jumpstep 1 // step up stairs while jumping, makes it easier to reach ledges
  set ekg 0     "Throw huge amounts of gibs"
  
 +seta sv_shownames_cull_distance 2500 "distance after which to not send origin/health/armor of another player"
 +
  cl_movement 1
  cl_movement_track_canjump 0
  cl_stairsmoothspeed 200
@@@ -418,6 -421,9 +423,9 @@@ set bot_nofire 0   "When set, bots never 
  seta bot_prefix [BOT] "Prefix in front of the bot names"
  seta bot_suffix ""    "Suffix behind the bot names"
  seta skill_auto 0     "when 1, \"skill\" gets adjusted to match the best player on the map"
+ set bot_debug_tracewalk 0 "Enable visual indicators for short-term navigation. Green: Goal Reached / Yellow: Obstacle found / Red: Unsolvable obstacle found"
+ set bot_debug_goalstack 0 "Visualize the current path that each bot is following. Use with as few bots as possible."
+ set bot_wander_enable 1 "Have bots wander around if they are unable to reach any useful goal. Disable only for debugging purposes."
  // general bot AI cvars
  set bot_ai_thinkinterval 0.05
  set bot_ai_strategyinterval 5 "How often a new objective is chosen"
@@@ -519,7 -525,7 +527,7 @@@ set g_casings 2 "specifies which casing
  set g_norecoil 0 "if set to 1 shooting weapons won't make you crosshair to move upwards (recoil)"
  set g_maplist_mostrecent "" "contains the name of the maps that were most recently played"
  seta g_maplist_mostrecent_count 3     "number of most recent maps that are blocked from being played again"
- seta g_maplist "g-23" "the list of maps to be cycled among (is autogenerated if empty)"
+ seta g_maplist "" "the list of maps to be cycled among (is autogenerated if empty)"
  seta g_maplist_index 0        "this is used internally for saving position in maplist cycle"
  seta g_maplist_selectrandom 0 "if 1, a random map will be chosen as next map - DEPRECATED in favor of g_maplist_shuffle"
  seta g_maplist_shuffle 1      "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
@@@ -1184,10 -1190,13 +1192,10 @@@ seta sv_servermodelsonly 
  cl_curl_enabled 1
  cl_curl_maxspeed 300
  sv_curl_defaulturl "http://www.xonotic.com/contentdownload/getmap.php?file="
- set sv_curl_serverpackages_auto 0 "automatically add packs with *.serverpackage files to sv_curl_serverpackages"
+ set sv_curl_serverpackages_auto 1 "automatically add packs with *.serverpackage files to sv_curl_serverpackages"
  
  set sv_motd ""
  
 -seta cl_shownames 1   "show player names pointed to (0: never, 1: teamplay only, 2: always)"
 -set sv_allow_shownames 1
 -
  set g_waypoints_for_items 1   "make waypoints out of items, values: 0 = never, 1 = unless the mapper prevents it by worldspawn.spawnflags & 1, 2 = always"
  
  seta g_maplist_votable 6 "number of maps that are shown in the map voting at the end of a match"
@@@ -1421,16 -1430,10 +1429,16 @@@ seta hud_panel_ammo_maxammo "40" "when 
  
  seta hud_panel_healtharmor_maxhealth "200" "when you have this much health, the health status bar is full"
  seta hud_panel_healtharmor_maxarmor "200" "when you have this much armor, the armor status bar is full"
 +seta hud_panel_healtharmor_progressbar_gfx 1 "enable graphic effects on the progressbars"
 +seta hud_panel_healtharmor_progressbar_gfx_damage 5 "show damage effect when damaged at least by this amount; 0 disables the effect"
 +seta hud_panel_healtharmor_progressbar_gfx_lowhealth 40 "health progressbar blinks when health is lower than this amount"
 +seta hud_panel_healtharmor_progressbar_gfx_smooth 2 "smooth changes of the progressbar when health/armor change at least by this amount; 0 disables the effect"
  
  seta hud_panel_notify_time 10 "time that a new entry stays until it fades out"
  seta hud_panel_notify_fadetime 3 "fade out time"
  
 +seta hud_panel_modicons_dom_layout 1 "3 possible layouts: 0) only icons; 1) icons and percentage of average pps (points per second); 2) icons and average pps"
 +
  seta hud_panel_timer_increment 0 "show elapsed time instead of remaining time"
  
  seta hud_panel_radar_scale 4096 "distance you can see on the team radar"
@@@ -1438,24 -1441,13 +1446,24 @@@ 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: 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_showbinds 1  "the way to show the keys to press in HUD messages: 0 displays commands, 1 bound keys, 2 both"
 +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_vertical 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 1.5 "acceleration progressbar gets completely filled up by this value (in g)"
 +seta hud_panel_physics_acceleration_vertical 0 "include the acceleration on the Z-axis"
 +
 +seta hud_showbinds 1  "what to show in the HUD to indicate certain keys to press: 0 display commands, 1 bound keys, 2 both"
  seta hud_showbinds_limit 2    "maximum number of bound keys to show for a command. 0 for unlimited"
  
  seta hud_colorflash_alpha 0.5 "starting alpha of the color flash"
@@@ -1484,18 -1476,6 +1492,18 @@@ seta hud_contents_slime_color "0 0.4 0.
  seta hud_contents_water_alpha 0.5 "alpha of the water color blend when inside it"
  seta hud_contents_water_color "0.4 0.3 0.3"
  
 +seta hud_shownames 1 "draw names and health/armor of nearby players"
 +seta hud_shownames_enemies 2 "1 = draw names of enemies you point at, 2 = draw names of all enemies in view"
 +seta hud_shownames_status 2 "1 = draw health/armor status of teammates, 2 = same as 1, but draw health/armor icons with a question mark on enemies in teamgames"
 +seta hud_shownames_height 15 "height of icons"
 +seta hud_shownames_aspect 8 "aspect ratio of total drawing area per name"
 +seta hud_shownames_fontsize 13 "font size"
 +seta hud_shownames_decolorize 1 "1 = decolorize name in team games, 2 = decolorize always"
 +seta hud_shownames_alpha 0.7 "alpha"
 +seta hud_shownames_resize 1 "enable resizing of the names, then the size cvars will correspond to the maximum size"
 +seta hud_shownames_mindistance 1000 "start fading alpha/size at this distance"
 +seta hud_shownames_maxdistance 2500 "alpha/size is 0 at this distance"
 +
  // scoreboard
  seta scoreboard_columns default
  seta scoreboard_border_thickness 1 "scoreboard border thickness"
@@@ -1799,6 -1779,25 +1807,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."
diff --combined qcsrc/client/Main.qc
index 21ccb217ce6c04858f4914de03d278fb8935e25a,71998a2d67730235318ecd64e89e83df05fd23d6..9897ebf011b583d60b4c84cd92d9068580eef075
@@@ -63,7 -63,7 +63,7 @@@ void CSQC_Init(void
        check_unacceptable_compiler_bugs();
  
  #ifdef WATERMARK
-       print(sprintf(_("^4CSQC Build information: %s\n"), WATERMARK()));
+       print(sprintf(_("^4CSQC Build information: ^1%s\n"), WATERMARK()));
  #endif
  
        float i;
        minimapname = strzone(minimapname);
  
        WarpZone_Init();
 +
        hud_configure_prev = -1;
 +      tab_panel = -1;
  }
  
  // CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
@@@ -205,6 -203,10 +205,10 @@@ void CSQC_Shutdown(void
        if(camera_active)
                cvar_set("chase_active",ftos(chase_active_backup));
  
+       // unset the event chasecam's chase_active
+       if(autocvar_chase_active < 0)
+               cvar_set("chase_active", "0");
        if not(isdemo())
        {
                if not(calledhooks & HOOK_START)
@@@ -617,7 -619,6 +621,7 @@@ void GameCommand(string msg
              vote_prev = 0;
              cvar_set("cl_allow_uid2name", "1");
              vote_change = -9999;
 +                      uid2name_dialog = 0;
          }
          else
          {
              vote_prev = 0;
              cvar_set("cl_allow_uid2name", "0");
              vote_change = -9999;
 +                      uid2name_dialog = 0;
          }
          else
          {
@@@ -835,15 -835,6 +839,15 @@@ void Ent_ClientData(
                race_laptime = 0;
                race_checkpointtime = 0;
        }
 +      if (autocvar_hud_panel_healtharmor_progressbar_gfx)
 +      {
 +              if ( (spectatee_status == -1 && newspectatee_status > 0) //before observing, now spectating
 +                || (spectatee_status > 0 && newspectatee_status > 0 && spectatee_status != newspectatee_status) //changed spectated player
 +              )
 +                      prev_p_health = -1;
 +              else if(spectatee_status && !newspectatee_status) //before observing/spectating, now playing
 +                      prev_health = -1;
 +      }
        spectatee_status = newspectatee_status;
  }
  
@@@ -916,37 -907,6 +920,37 @@@ void Ent_ReadAccuracy(void
        }
  }
  
 +void Ent_ShowNames()
 +{
 +    float sf;
 +
 +    // entity init, TODO can this be done only once somehow?
 +    self.the_entnum = ReadByte(); // TODO: fixme to only send once somehow
 +    self.draw2d = Draw_ShowNames;
 +    //self.movetype = MOVETYPE_FLY; // movetype needed so we can traceline?
 +    self.mins = '-20 -20 -24';
 +    self.maxs = '20 20 45';
 +
 +    sf = ReadByte();
 +
 +    if(sf & 1)
 +    {
 +        self.origin_x = ReadShort();
 +        self.origin_y = ReadShort();
 +        self.origin_z = ReadShort();
 +    }
 +    if(sf & 2)
 +    {
 +        self.healthvalue = ReadByte();
 +        self.armorvalue = ReadByte();
 +    }
 +
 +    if(sf & 128) // same team
 +        self.sameteam = TRUE;
 +    else
 +        self.sameteam = FALSE;
 +}
 +
  // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
  // The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
  void Ent_RadarLink();
@@@ -1006,12 -966,12 +1010,13 @@@ void(float bIsNewEntity) CSQC_Ent_Updat
                case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break;
                case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
                case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break;
+               case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break;
                case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
                case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
                case ENT_CLIENT_LGBEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_LGBEAM); break;
                case ENT_CLIENT_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break;
                case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
 +              case ENT_CLIENT_SHOWNAMES: Ent_ShowNames(); break;
                default:
                        error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
                        break;
@@@ -1043,6 -1003,15 +1048,6 @@@ void CSQC_Ent_Remove(
  
  void Gamemode_Init()
  {
 -      if(gametype == GAME_ONSLAUGHT) {
 -              print(strcat("Using ", minimapname, " as minimap.\n"));
 -              precache_pic("gfx/ons-cp-neutral.tga");
 -              precache_pic("gfx/ons-cp-red.tga");
 -              precache_pic("gfx/ons-cp-blue.tga");
 -              precache_pic("gfx/ons-frame.tga");
 -              precache_pic("gfx/ons-frame-team.tga");
 -      }
 -
        if not(isdemo())
        {
                localcmd("\n_cl_hook_gamestart ", GametypeNameFromType(gametype), "\n");
@@@ -1449,7 -1418,7 +1454,7 @@@ string getcommandkey(string text, strin
        string keys;
        float n, j, k, l;
  
 -      if (!hud_showbinds)
 +      if (!autocvar_hud_showbinds)
                return text;
  
        keys = db_get(binddb, command);
                                        keys = strcat(keys, ", ", keynumtostring(k));
  
                                ++l;
 -                              if (hud_showbinds_limit > 0 && hud_showbinds_limit >= l) break;
 +                              if (autocvar_hud_showbinds_limit > 0 && autocvar_hud_showbinds_limit >= l) break;
                        }
  
                }
        }
  
        if ("" == keys) {
 -              if (hud_showbinds > 1)
 +              if (autocvar_hud_showbinds > 1)
                        return sprintf(_("%s (not bound)"), text);
                else
                        return text;
        }
 -      else if (hud_showbinds > 1)
 +      else if (autocvar_hud_showbinds > 1)
                return sprintf(_("%s (%s)"), text, keys);
        else
                return keys;
diff --combined qcsrc/client/View.qc
index 7ae320b89bccdcead7dc5c54aae76328d1526efb,0da6406195bc955b32298dc81dd9c385e2fdebf3..fa761910704f925fe1aa60e687be48969bb60d2c
@@@ -366,6 -366,8 +366,8 @@@ vector myhealth_gentlergb
  float contentavgalpha, liquidalpha_prev;
  vector liquidcolor_prev;
  
+ float eventchase_current_distance;
  float checkfail[16];
  
  void CSQC_UpdateView(float w, float h)
        CHECKFAIL_ASSERT(0, cvar_type, "\{100}\{105}\{118}\{48}\{95}\{101}\{118}\{97}\{100}\{101}", 0);
        CHECKFAIL_ASSERT(1, cvar_type, "\{97}\{97}\{95}\{101}\{110}\{97}\{98}\{108}\{101}", 0);
        CHECKFAIL_ASSERT(2, cvar, "\{114}\{95}\{115}\{104}\{111}\{119}\{100}\{105}\{115}\{97}\{98}\{108}\{101}\{100}\{101}\{112}\{116}\{104}\{116}\{101}\{115}\{116}", 0);
+       CHECKFAIL_ASSERT(3, cvar, "\{114}\{95}\{115}\{104}\{111}\{119}\{111}\{118}\{101}\{114}\{100}\{114}\{97}\{119}", 0);
+       CHECKFAIL_ASSERT(4, cvar, "\{114}\{95}\{115}\{104}\{111}\{119}\{108}\{105}\{103}\{104}\{116}", 0);
+       CHECKFAIL_ASSERT(5, cvar, "\{114}\{95}\{115}\{104}\{111}\{119}\{115}\{104}\{97}\{100}\{111}\{119}\{118}\{111}\{108}\{117}\{109}\{101}\{115}", 0);
  
        vf_size = R_SetView3fv(VF_SIZE);
        vf_min = R_SetView3fv(VF_MIN);
        input_angles = warpzone_fixview_cl_viewangles;
        view_angles = warpzone_fixview_angles;
  
-       if(autocvar_cl_lockview || (autocvar__hud_configure && spectatee_status <= 0))
+       if(autocvar_cl_lockview || (autocvar__hud_configure && spectatee_status <= 0) || intermission > 1)
        {
                pmove_org = freeze_pmove_org;
                input_angles = view_angles = freeze_input_angles;
        freeze_pmove_org = pmove_org;
        freeze_input_angles = input_angles;
  
+       // event chase camera
+       if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
+       {
+               if(spectatee_status >= 0 && (autocvar_cl_eventchase_death && getstati(STAT_HEALTH) <= 0 && !intermission) || (autocvar_cl_eventchase_intermission && intermission))
+               {
+                       // We must enable chase_active to get a third person view (weapon viewmodel hidden and own player model showing).
+                       // Ideally, there should be another way to enable third person cameras, such as through R_SetView()
+                       if(!autocvar_chase_active)
+                               cvar_set("chase_active", "-1"); // -1 enables chase_active while marking it as set by this code, and not by the user (which would be 1)
+                       // make the camera smooth back
+                       if(autocvar_cl_eventchase_speed && eventchase_current_distance < autocvar_cl_eventchase_distance)
+                               eventchase_current_distance += autocvar_cl_eventchase_speed * (autocvar_cl_eventchase_distance - eventchase_current_distance) * frametime; // slow down the further we get
+                       else if(eventchase_current_distance != autocvar_cl_eventchase_distance)
+                               eventchase_current_distance = autocvar_cl_eventchase_distance;
+                       vector eventchase_target_origin;
+                       makevectors(view_angles);
+                       // pass 1, used to check where the camera would go and obtain the trace_fraction
+                       eventchase_target_origin = pmove_org - v_forward * eventchase_current_distance;
+                       traceline(pmove_org, eventchase_target_origin, MOVE_WORLDONLY, self);
+                       // pass 2, also multiplying view_forward with trace_fraction, to prevent the camera from going through walls
+                       // The 0.1 subtraction is to not limit the camera precisely at the wall surface, as that allows the view to poke through
+                       eventchase_target_origin = pmove_org - v_forward * eventchase_current_distance * (trace_fraction - 0.1);
+                       R_SetView(VF_ORIGIN, eventchase_target_origin);
+               }
+               else if(autocvar_chase_active < 0) // time to disable chase_active if it was set by this code
+               {
+                       cvar_set("chase_active", "0");
+                       eventchase_current_distance = 0; // start from 0 next time
+               }
+       }
        // Render the Scene
-       if(!intermission || !view_set)
+       if(!intermission || !view_set || (intermission && autocvar_cl_eventchase_intermission))
        {
                view_origin = pmove_org + vo;
                view_angles = input_angles;
        // Draw the Engine Status Bar (the default Quake HUD)
        R_SetView(VF_DRAWENGINEHUD, 0);
  
 -      // fetch this one only once per frame
 -      hud_showbinds = autocvar_hud_showbinds;
 -      hud_showbinds_limit = autocvar_hud_showbinds_limit;
 -
        // Update the mouse position
        /*
           mousepos_x = vid_conwidth;
@@@ -1553,6 -1597,7 +1593,6 @@@ const float STAT_VEHICLESTAT_RELOAD2 = 
  
  }
  
 -
  void CSQC_common_hud(void)
  {
        // HUD_SortFrags(); done in HUD_Draw
index 102ea1e30f96147378c672e0d90cd2d6867855ec,6d157405b04653cadafb3933e162022de10aec41..006775ff70f899711fc74d16b6e40b63b35e47a4
@@@ -60,6 -60,19 +60,6 @@@ float autocvar_cl_readpicture_force
  float autocvar_cl_reticle_item_nex;
  float autocvar_cl_reticle_item_normal;
  float autocvar_cl_reticle_stretch;
 -float autocvar_cl_showacceleration;
 -float autocvar_cl_showacceleration_alpha;
 -string autocvar_cl_showacceleration_color;
 -float autocvar_cl_showacceleration_color_custom;
 -float autocvar_cl_showacceleration_position;
 -float autocvar_cl_showacceleration_scale;
 -float autocvar_cl_showacceleration_size;
 -float autocvar_cl_showacceleration_z;
 -float autocvar_cl_showspeed;
 -float autocvar_cl_showspeed_position;
 -float autocvar_cl_showspeed_size;
 -float autocvar_cl_showspeed_unit;
 -float autocvar_cl_showspeed_z;
  float autocvar_cl_sound_maptime_warning;
  float autocvar_cl_stripcolorcodes;
  var float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6;
@@@ -72,7 -85,6 +72,7 @@@ float autocvar_cl_zoomsensitivity
  float autocvar_cl_zoomspeed;
  float autocvar_con_chat;
  float autocvar_con_chatpos;
 +float autocvar_con_chatrect;
  float autocvar_con_chatsize;
  float autocvar_con_chattime;
  float autocvar_con_notify;
@@@ -198,36 -210,16 +198,36 @@@ float autocvar_hud_panel_healtharmor_ma
  float autocvar_hud_panel_healtharmor_progressbar;
  string autocvar_hud_panel_healtharmor_progressbar_armor;
  string autocvar_hud_panel_healtharmor_progressbar_health;
 +float autocvar_hud_panel_healtharmor_progressbar_gfx;
 +float autocvar_hud_panel_healtharmor_progressbar_gfx_damage;
 +float autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth;
 +float autocvar_hud_panel_healtharmor_progressbar_gfx_smooth;
 +
  float autocvar_hud_panel_healtharmor_text;
  float autocvar_hud_panel_infomessages;
  float autocvar_hud_panel_infomessages_flip;
  float autocvar_hud_panel_modicons;
 +float autocvar_hud_panel_modicons_dom_layout;
  float autocvar_hud_panel_notify;
  float autocvar_hud_panel_notify_fadetime;
  float autocvar_hud_panel_notify_flip;
  float autocvar_hud_panel_notify_fontsize;
  float autocvar_hud_panel_notify_print;
  float autocvar_hud_panel_notify_time;
 +float autocvar_hud_panel_physics;
 +float autocvar_hud_panel_physics_acceleration_progressbar_mode;
 +float autocvar_hud_panel_physics_acceleration_max;
 +float autocvar_hud_panel_physics_progressbar;
 +float autocvar_hud_panel_physics_acceleration_vertical;
 +float autocvar_hud_panel_physics_baralign;
 +float autocvar_hud_panel_physics_flip;
 +float autocvar_hud_panel_physics_speed_max;
 +float autocvar_hud_panel_physics_speed_unit;
 +float autocvar_hud_panel_physics_speed_unit_show;
 +float autocvar_hud_panel_physics_speed_vertical;
 +float autocvar_hud_panel_physics_text;
 +float autocvar_hud_panel_physics_topspeed;
 +float autocvar_hud_panel_physics_topspeed_time;
  float autocvar_hud_panel_powerups;
  float autocvar_hud_panel_powerups_baralign;
  float autocvar_hud_panel_powerups_flip;
@@@ -245,7 -237,6 +245,7 @@@ float autocvar_hud_panel_radar_rotation
  float autocvar_hud_panel_radar_scale;
  float autocvar_hud_panel_radar_zoommode;
  float autocvar_hud_panel_score;
 +float autocvar_hud_panel_score_rankings;
  float autocvar_hud_panel_timer;
  float autocvar_hud_panel_timer_increment;
  float autocvar_hud_panel_vote;
@@@ -276,17 -267,6 +276,17 @@@ float autocvar_hud_panel_weapons_timeou
  float autocvar_hud_progressbar_alpha;
  float autocvar_hud_showbinds;
  float autocvar_hud_showbinds_limit;
 +float autocvar_hud_shownames;
 +float autocvar_hud_shownames_enemies;
 +float autocvar_hud_shownames_status;
 +float autocvar_hud_shownames_height;
 +float autocvar_hud_shownames_aspect;
 +float autocvar_hud_shownames_fontsize;
 +float autocvar_hud_shownames_decolorize;
 +float autocvar_hud_shownames_alpha;
 +float autocvar_hud_shownames_resize;
 +float autocvar_hud_shownames_mindistance;
 +float autocvar_hud_shownames_maxdistance;
  string autocvar_hud_skin;
  float autocvar_loddebug;
  float autocvar_menu_mouse_speed;
@@@ -325,3 -305,7 +325,7 @@@ float autocvar_viewsize
  float autocvar_crosshair_color_by_health;
  float autocvar_cl_hitsound;
  float autocvar_cl_hitsound_antispam_time;
+ var float autocvar_cl_eventchase_death = 1;
+ var float autocvar_cl_eventchase_intermission = 1;
+ var float autocvar_cl_eventchase_distance = 140;
+ var float autocvar_cl_eventchase_speed = 1.3;
diff --combined qcsrc/client/hud.qc
index c70003153727db151802168d2336775ed3380e97,6a5536bcda95e0035ef23dbdb72d4c50d59b2512..c224fcd7ccb386855fe0e96bc35d350bf41d5ce8
@@@ -424,138 -424,1055 +424,138 @@@ HUD panel
  ==================
  */
  
 -#define HUD_Write(s) fputs(fh, s)
 -// q: quoted, n: not quoted
 -#define HUD_Write_Cvar_n(cvar) HUD_Write(strcat("seta ", cvar, " ", cvar_string(cvar), "\n"))
 -#define HUD_Write_Cvar_q(cvar) HUD_Write(strcat("seta ", cvar, " \"", cvar_string(cvar), "\"\n"))
 -#define HUD_Write_PanelCvar_n(cvar_suf) HUD_Write_Cvar_n(strcat("hud_panel_", panel_name, cvar_suf))
 -#define HUD_Write_PanelCvar_q(cvar_suf) HUD_Write_Cvar_q(strcat("hud_panel_", panel_name, cvar_suf))
 -// Save the config
 -void HUD_Panel_ExportCfg(string cfgname)
 -{
 -      float fh;
 -      string filename = strcat("hud_", autocvar_hud_skin, "_", cfgname, ".cfg");
 -      fh = fopen(filename, FILE_WRITE);
 -      if(fh >= 0)
 -      {
 -              HUD_Write_Cvar_q("hud_skin");
 -              HUD_Write_Cvar_q("hud_panel_bg");
 -              HUD_Write_Cvar_q("hud_panel_bg_color");
 -              HUD_Write_Cvar_q("hud_panel_bg_color_team");
 -              HUD_Write_Cvar_q("hud_panel_bg_alpha");
 -              HUD_Write_Cvar_q("hud_panel_bg_border");
 -              HUD_Write_Cvar_q("hud_panel_bg_padding");
 -              HUD_Write_Cvar_q("hud_panel_fg_alpha");
 -              HUD_Write("\n");
 -
 -              HUD_Write_Cvar_q("hud_dock");
 -              HUD_Write_Cvar_q("hud_dock_color");
 -              HUD_Write_Cvar_q("hud_dock_color_team");
 -              HUD_Write_Cvar_q("hud_dock_alpha");
 -              HUD_Write("\n");
 -
 -              HUD_Write_Cvar_q("hud_progressbar_alpha");
 -              HUD_Write_Cvar_q("hud_progressbar_strength_color");
 -              HUD_Write_Cvar_q("hud_progressbar_shield_color");
 -              HUD_Write_Cvar_q("hud_progressbar_health_color");
 -              HUD_Write_Cvar_q("hud_progressbar_armor_color");
 -              HUD_Write_Cvar_q("hud_progressbar_fuel_color");
 -              HUD_Write_Cvar_q("hud_progressbar_nexball_color");
 -              HUD_Write("\n");
 -
 -              HUD_Write_Cvar_q("_hud_panelorder");
 -              HUD_Write("\n");
 -
 -              HUD_Write_Cvar_q("hud_configure_grid");
 -              HUD_Write_Cvar_q("hud_configure_grid_xsize");
 -              HUD_Write_Cvar_q("hud_configure_grid_ysize");
 -              HUD_Write("\n");
 -
 -              HUD_Write_Cvar_q("scr_centerpos");
 -              HUD_Write("\n");
 -
 -              // common cvars for all panels
 -              float i;
 -              for (i = 0; i < HUD_PANEL_NUM; ++i)
 -              {
 -                      HUD_Panel_GetName(i);
 -
 -                      HUD_Write_PanelCvar_n("");
 -                      HUD_Write_PanelCvar_q("_pos");
 -                      HUD_Write_PanelCvar_q("_size");
 -                      HUD_Write_PanelCvar_q("_bg");
 -                      HUD_Write_PanelCvar_q("_bg_color");
 -                      HUD_Write_PanelCvar_q("_bg_color_team");
 -                      HUD_Write_PanelCvar_q("_bg_alpha");
 -                      HUD_Write_PanelCvar_q("_bg_border");
 -                      HUD_Write_PanelCvar_q("_bg_padding");
 -                      switch(i) {
 -                              case HUD_PANEL_WEAPONS:
 -                                      HUD_Write_PanelCvar_q("_complainbubble");
 -                                      HUD_Write_PanelCvar_q("_complainbubble_padding");
 -                                      HUD_Write_PanelCvar_q("_complainbubble_color_outofammo");
 -                                      HUD_Write_PanelCvar_q("_complainbubble_color_donthave");
 -                                      HUD_Write_PanelCvar_q("_complainbubble_color_unavailable");
 -                                      HUD_Write_PanelCvar_q("_ammo_color");
 -                                      HUD_Write_PanelCvar_q("_ammo_alpha");
 -                                      HUD_Write_PanelCvar_q("_aspect");
 -                                      HUD_Write_PanelCvar_q("_timeout");
 -                                      HUD_Write_PanelCvar_q("_timeout_effect");
 -                                      break;
 -                              case HUD_PANEL_AMMO:
 -                                      HUD_Write_PanelCvar_q("_onlycurrent");
 -                                      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:
 -                                      HUD_Write_PanelCvar_q("_flip");
 -                                      HUD_Write_PanelCvar_q("_iconalign");
 -                                      HUD_Write_PanelCvar_q("_baralign");
 -                                      HUD_Write_PanelCvar_q("_progressbar");
 -                                      HUD_Write_PanelCvar_q("_progressbar_strength");
 -                                      HUD_Write_PanelCvar_q("_progressbar_shield");
 -                                      HUD_Write_PanelCvar_q("_text");
 -                                      break;
 -                              case HUD_PANEL_HEALTHARMOR:
 -                                      HUD_Write_PanelCvar_q("_flip");
 -                                      HUD_Write_PanelCvar_q("_iconalign");
 -                                      HUD_Write_PanelCvar_q("_baralign");
 -                                      HUD_Write_PanelCvar_q("_progressbar");
 -                                      HUD_Write_PanelCvar_q("_progressbar_health");
 -                                      HUD_Write_PanelCvar_q("_progressbar_armor");
 -                                      HUD_Write_PanelCvar_q("_text");
 -                                      break;
 -                              case HUD_PANEL_NOTIFY:
 -                                      HUD_Write_PanelCvar_q("_flip");
 -                                      HUD_Write_PanelCvar_q("_fontsize");
 -                                      HUD_Write_PanelCvar_q("_print");
 -                                      break;
 -                              case HUD_PANEL_RADAR:
 -                                      HUD_Write_PanelCvar_q("_foreground_alpha");
 -                                      break;
 -                              case HUD_PANEL_VOTE:
 -                                      HUD_Write_PanelCvar_q("_alreadyvoted_alpha");
 -                                      break;
 -                              case HUD_PANEL_PRESSEDKEYS:
 -                                      HUD_Write_PanelCvar_q("_aspect");
 -                                      break;
 -                              case HUD_PANEL_INFOMESSAGES:
 -                                      HUD_Write_PanelCvar_q("_flip");
 -                                      break;
 -                      }
 -                      HUD_Write("\n");
 -              }
 -              HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated
 -
 -              print(sprintf(_("^2Successfully exported to %s! (Note: It's saved in data/data/)\n"), filename));
 -              fclose(fh);
 -      }
 -      else
 -              print(sprintf(_("^1Couldn't write to %s\n"), filename));
 -}
 -
 -const float hlBorderSize = 4;
 -const string hlBorder = "gfx/hud/default/border_highlighted";
 -const string hlBorder2 = "gfx/hud/default/border_highlighted2";
 -void HUD_Panel_HlBorder(float myBorder, vector color, float alpha)
 -{
 -      drawfill(panel_pos - '1 1 0' * myBorder, panel_size + '2 2 0' * myBorder, '0 0.5 1', .5 * alpha, DRAWFLAG_NORMAL);
 -      drawpic_tiled(panel_pos - '1 1 0' * myBorder, hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, alpha, DRAWFLAG_NORMAL);
 -      drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * (panel_size_y + 2 * myBorder - hlBorderSize), hlBorder, '8 1 0' * hlBorderSize, eX * (panel_size_x + 2 * myBorder) + eY * hlBorderSize, color, alpha, DRAWFLAG_NORMAL);
 -      drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize, hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, alpha, DRAWFLAG_NORMAL);
 -      drawpic_tiled(panel_pos - '1 1 0' * myBorder + eY * hlBorderSize + eX * (panel_size_x + 2 * myBorder - hlBorderSize), hlBorder2, '1 8 0' * hlBorderSize, eY * (panel_size_y + 2 * myBorder - 2 * hlBorderSize) + eX * hlBorderSize, color, alpha, DRAWFLAG_NORMAL);
 -}
 -
  // draw the background/borders
  #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 length_ratio, float vertical, float baralign, vector theColor, float theAlpha, float drawflag)
  {
 -      if(!alpha || x == 0)
 +      if(!length_ratio || !theAlpha)
 +              return;
 +      if(length_ratio > 1)
 +              length_ratio = 1;
 +      if (baralign == 3)
 +      {
 +              if(length_ratio < -1)
 +                      length_ratio = -1;
 +      }
 +      else if(length_ratio < 0)
                return;
  
 -    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);
 -      } 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);
 -      }
 -
 -    drawpic(pos, pic, mySize, color, alpha, drawflag);
 -    drawresetcliparea();
 -}
 -
 -void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float alpha, float drawflag)
 -{
 -      if(!alpha)
 -              return;
 -
 -      string pic;
 -      pic = strcat(hud_skin_path, "/num_leading");
 -      if(precache_pic(pic) == "") {
 -              pic = "gfx/hud/default/num_leading";
 -      }
 -
 -      drawsubpic(pos, eX * min(mySize_x * 0.5, mySize_y) + eY * mySize_y, pic, '0 0 0', '0.25 1 0', color, alpha, drawflag);
 -      if(mySize_x/mySize_y > 2)
 -              drawsubpic(pos + eX * mySize_y, eX * (mySize_x - 2 * mySize_y) + eY * mySize_y, pic, '0.25 0 0', '0.5 1 0', color, alpha, drawflag);
 -      drawsubpic(pos + eX * mySize_x - eX * min(mySize_x * 0.5, mySize_y), eX * min(mySize_x * 0.5, mySize_y) + eY * mySize_y, pic, '0.75 0 0', '0.25 1 0', color, alpha, drawflag);
 -}
 -
 -// check if move will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector
 -vector HUD_Panel_CheckMove(vector myPos, vector mySize)
 -{
 -      float i;
 -
 -      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;
 -
 -              HUD_Panel_UpdatePosSizeForId(i);
 -
 -              panel_pos -= '1 1 0' * panel_bg_border;
 -              panel_size += '2 2 0' * panel_bg_border;
 -
 -              if(myPos_y + mySize_y < panel_pos_y)
 -                      continue;
 -              if(myPos_y > panel_pos_y + panel_size_y)
 -                      continue;
 -
 -              if(myPos_x + mySize_x < panel_pos_x)
 -                      continue;
 -              if(myPos_x > panel_pos_x + panel_size_x)
 -                      continue;
 -
 -              // OK, there IS a collision.
 -
 -              myCenter_x = myPos_x + 0.5 * mySize_x;
 -              myCenter_y = myPos_y + 0.5 * mySize_y;
 -
 -              targCenter_x = panel_pos_x + 0.5 * panel_size_x;
 -              targCenter_y = panel_pos_y + 0.5 * panel_size_y;
 -
 -              if(myCenter_x < targCenter_x && myCenter_y < targCenter_y) // top left (of the target panel)
 -              {
 -                      if(myPos_x + mySize_x - panel_pos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side
 -                              myTarget_x = panel_pos_x - mySize_x;
 -                      else // push it upwards
 -                              myTarget_y = panel_pos_y - mySize_y;
 -              }
 -              else if(myCenter_x > targCenter_x && myCenter_y < targCenter_y) // top right
 -              {
 -                      if(panel_pos_x + panel_size_x - myPos_x < myPos_y + mySize_y - panel_pos_y) // push it to the side
 -                              myTarget_x = panel_pos_x + panel_size_x;
 -                      else // push it upwards
 -                              myTarget_y = panel_pos_y - mySize_y;
 -              }
 -              else if(myCenter_x < targCenter_x && myCenter_y > targCenter_y) // bottom left
 -              {
 -                      if(myPos_x + mySize_x - panel_pos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side
 -                              myTarget_x = panel_pos_x - mySize_x;
 -                      else // push it downwards
 -                              myTarget_y = panel_pos_y + panel_size_y;
 -              }
 -              else if(myCenter_x > targCenter_x && myCenter_y > targCenter_y) // bottom right
 -              {
 -                      if(panel_pos_x + panel_size_x - myPos_x < panel_pos_y + panel_size_y - myPos_y) // push it to the side
 -                              myTarget_x = panel_pos_x + panel_size_x;
 -                      else // push it downwards
 -                              myTarget_y = panel_pos_y + panel_size_y;
 -              }
 -              //if(cvar("hud_configure_checkcollisions_debug"))
 -                      //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL);
 -      }
 -
 -      return myTarget;
 -}
 -
 -void HUD_Panel_SetPos(vector pos)
 -{
 -      HUD_Panel_UpdatePosSizeForId(highlightedPanel);
 -      vector mySize;
 -      mySize = panel_size;
 -
 -      //if(cvar("hud_configure_checkcollisions_debug"))
 -              //drawfill(pos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL);
 -
 -      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;
 -      }
 -
 -      if(hud_configure_checkcollisions)
 -              pos = HUD_Panel_CheckMove(pos, mySize);
 -
 -      pos_x = bound(0, pos_x, vid_conwidth - mySize_x);
 -      pos_y = bound(0, pos_y, vid_conheight - mySize_y);
 -
 -      string s;
 -      s = strcat(ftos(pos_x/vid_conwidth), " ", ftos(pos_y/vid_conheight));
 -
 -      HUD_Panel_GetName(highlightedPanel);
 -      cvar_set(strcat("hud_panel_", panel_name, "_pos"), s);
 -}
 -
 -// check if resize will result in panel being moved into another panel. If so, return snapped vector, otherwise return the given vector
 -vector HUD_Panel_CheckResize(vector mySize, vector resizeorigin) {
 -      float i;
 -
 -      vector targEndPos;
 -
 -      float dist_x, dist_y;
 -      float ratio;
 -      ratio = mySize_x/mySize_y;
 -
 -      for (i = 0; i < HUD_PANEL_NUM; ++i) {
 -              if(i == highlightedPanel || !panel_enabled)
 -                      continue;
 -
 -              HUD_Panel_UpdatePosSizeForId(i);
 -
 -              panel_pos -= '1 1 0' * panel_bg_border;
 -              panel_size += '2 2 0' * panel_bg_border;
 -
 -              targEndPos = panel_pos + panel_size;
 -
 -              // resizeorigin is WITHIN target panel, just abort any collision testing against that particular panel to produce expected behaviour!
 -              if(resizeorigin_x > panel_pos_x && resizeorigin_x < targEndPos_x && resizeorigin_y > panel_pos_y && resizeorigin_y < targEndPos_y)
 -                      continue;
 -
 -              if (resizeCorner == 1)
 -              {
 -                      // check if this panel is on our way
 -                      if (resizeorigin_x <= panel_pos_x)
 -                              continue;
 -                      if (resizeorigin_y <= panel_pos_y)
 -                              continue;
 -                      if (targEndPos_x <= resizeorigin_x - mySize_x)
 -                              continue;
 -                      if (targEndPos_y <= resizeorigin_y - mySize_y)
 -                              continue;
 -
 -                      // there is a collision:
 -                      // detect which side of the panel we are facing is actually limiting the resizing
 -                      // (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
 -                      dist_x = resizeorigin_x - targEndPos_x;
 -                      dist_y = resizeorigin_y - targEndPos_y;
 -                      if (dist_y <= 0 || dist_x / dist_y > ratio)
 -                              mySize_x = min(mySize_x, dist_x);
 -                      else
 -                              mySize_y = min(mySize_y, dist_y);
 +                      pic = "gfx/hud/default/progressbar_vertical";
                }
 -              else if (resizeCorner == 2)
 -              {
 -                      if (resizeorigin_x >= targEndPos_x)
 -                              continue;
 -                      if (resizeorigin_y <= panel_pos_y)
 -                              continue;
 -                      if (panel_pos_x >= resizeorigin_x + mySize_x)
 -                              continue;
 -                      if (targEndPos_y <= resizeorigin_y - mySize_y)
 -                              continue;
  
 -                      dist_x = panel_pos_x - resizeorigin_x;
 -                      dist_y = resizeorigin_y - targEndPos_y;
 -                      if (dist_y <= 0 || dist_x / dist_y > ratio)
 -                              mySize_x = min(mySize_x, dist_x);
 -                      else
 -                              mySize_y = min(mySize_y, dist_y);
 -              }
 -              else if (resizeCorner == 3)
 +        if (baralign == 1) // bottom align
 +                      theOrigin_y += (1 - length_ratio) * theSize_y;
 +        else if (baralign == 2) // center align
 +            theOrigin_y += 0.5 * (1 - length_ratio) * theSize_y;
 +        else if (baralign == 3) // center align, positive values down, negative up
                {
 -                      if (resizeorigin_x <= panel_pos_x)
 -                              continue;
 -                      if (resizeorigin_y >= targEndPos_y)
 -                              continue;
 -                      if (targEndPos_x <= resizeorigin_x - mySize_x)
 -                              continue;
 -                      if (panel_pos_y >= resizeorigin_y + mySize_y)
 -                              continue;
 -
 -                      dist_x = resizeorigin_x - targEndPos_x;
 -                      dist_y = panel_pos_y - resizeorigin_y;
 -                      if (dist_y <= 0 || dist_x / dist_y > ratio)
 -                              mySize_x = min(mySize_x, dist_x);
 +                      theSize_y *= 0.5;
 +                      if (length_ratio > 0)
 +                              theOrigin_y += theSize_y;
                        else
 -                              mySize_y = min(mySize_y, dist_y);
 -              }
 -              else if (resizeCorner == 4)
 -              {
 -                      if (resizeorigin_x >= targEndPos_x)
 -                              continue;
 -                      if (resizeorigin_y >= targEndPos_y)
 -                              continue;
 -                      if (panel_pos_x >= resizeorigin_x + mySize_x)
 -                              continue;
 -                      if (panel_pos_y >= resizeorigin_y + mySize_y)
 -                              continue;
 -
 -                      dist_x = panel_pos_x - resizeorigin_x;
 -                      dist_y = panel_pos_y - resizeorigin_y;
 -                      if (dist_y <= 0 || dist_x / dist_y > ratio)
 -                              mySize_x = min(mySize_x, dist_x);
 -                      else
 -                              mySize_y = min(mySize_y, dist_y);
 +                      {
 +                              theOrigin_y += (1 + length_ratio) * theSize_y;
 +                              length_ratio = -length_ratio;
 +                      }
                }
 -              //if(cvar("hud_configure_checkcollisions_debug"))
 -                      //drawfill(panel_pos, panel_size, '1 1 0', .3, DRAWFLAG_NORMAL);
 -      }
 -
 -      return mySize;
 -}
 -
 -void HUD_Panel_SetPosSize(vector mySize)
 -{
 -      HUD_Panel_UpdatePosSizeForId(highlightedPanel);
 -      vector resizeorigin;
 -      resizeorigin = panel_click_resizeorigin;
 -      vector myPos;
 -
 -      // minimum panel size cap
 -      mySize_x = max(0.025 * vid_conwidth, mySize_x);
 -      mySize_y = max(0.025 * vid_conheight, mySize_y);
 -
 -      if(highlightedPanel == HUD_PANEL_CHAT) // some panels have their own restrictions, like the chat panel (which actually only moves the engine chat print around). Looks bad if it's too small.
 -      {
 -              mySize_x = max(17 * autocvar_con_chatsize, mySize_x);
 -              mySize_y = max(2 * autocvar_con_chatsize + 2 * panel_bg_padding, mySize_y);
 -      }
 -
 -      // collision testing|
 -      // -----------------+
 -
 -      // we need to know pos at this stage, but it might still change later if we hit a screen edge/other panel (?)
 -      if(resizeCorner == 1) {
 -              myPos_x = resizeorigin_x - mySize_x;
 -              myPos_y = resizeorigin_y - mySize_y;
 -      } else if(resizeCorner == 2) {
 -              myPos_x = resizeorigin_x;
 -              myPos_y = resizeorigin_y - mySize_y;
 -      } else if(resizeCorner == 3) {
 -              myPos_x = resizeorigin_x - mySize_x;
 -              myPos_y = resizeorigin_y;
 -      } else { // resizeCorner == 4
 -              myPos_x = resizeorigin_x;
 -              myPos_y = resizeorigin_y;
 -      }
 -
 -      // left/top screen edges
 -      if(myPos_x < 0)
 -              mySize_x = mySize_x + myPos_x;
 -      if(myPos_y < 0)
 -              mySize_y = mySize_y + myPos_y;
 -
 -      // bottom/right screen edges
 -      if(myPos_x + mySize_x > vid_conwidth)
 -              mySize_x = vid_conwidth - myPos_x;
 -      if(myPos_y + mySize_y > vid_conheight)
 -              mySize_y = vid_conheight - myPos_y;
 -
 -      //if(cvar("hud_configure_checkcollisions_debug"))
 -              //drawfill(myPos, mySize, '1 1 1', .2, DRAWFLAG_NORMAL);
 -
 -      // 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;
 -      }
 -
 -      if(hud_configure_checkcollisions)
 -              mySize = HUD_Panel_CheckResize(mySize, resizeorigin);
 -
 -      // minimum panel size cap, do this once more so we NEVER EVER EVER have a panel smaller than this, JUST IN CASE above code still makes the panel eg negative (impossible to resize back without changing cvars manually then)
 -      mySize_x = max(0.025 * vid_conwidth, mySize_x);
 -      mySize_y = max(0.025 * vid_conheight, mySize_y);
 -
 -      // do another pos check, as size might have changed by now
 -      if(resizeCorner == 1) {
 -              myPos_x = resizeorigin_x - mySize_x;
 -              myPos_y = resizeorigin_y - mySize_y;
 -      } else if(resizeCorner == 2) {
 -              myPos_x = resizeorigin_x;
 -              myPos_y = resizeorigin_y - mySize_y;
 -      } else if(resizeCorner == 3) {
 -              myPos_x = resizeorigin_x - mySize_x;
 -              myPos_y = resizeorigin_y;
 -      } else { // resizeCorner == 4
 -              myPos_x = resizeorigin_x;
 -              myPos_y = resizeorigin_y;
 -      }
 -
 -      //if(cvar("hud_configure_checkcollisions_debug"))
 -              //drawfill(myPos, mySize, '0 1 0', .3, DRAWFLAG_NORMAL);
 -
 -      HUD_Panel_GetName(highlightedPanel);
 -      string s;
 -      s = strcat(ftos(mySize_x/vid_conwidth), " ", ftos(mySize_y/vid_conheight));
 -      cvar_set(strcat("hud_panel_", panel_name, "_size"), s);
 -
 -      s = strcat(ftos(myPos_x/vid_conwidth), " ", ftos(myPos_y/vid_conheight));
 -      cvar_set(strcat("hud_panel_", panel_name, "_pos"), s);
 -}
 +              theSize_y *= length_ratio;
  
 -float mouseClicked;
 -float prevMouseClicked; // previous state
 -float prevMouseClickedTime; // time during previous mouse click, to check for doubleclicks
 -vector prevMouseClickedPos; // pos during previous mouse click, to check for doubleclicks
 -
 -float pressed_key_time;
 -void HUD_Panel_Arrow_Action(float nPrimary)
 -{
 -      if (highlightedPanel_prev == -1 || mouseClicked)
 -              return;
 -
 -      hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
 -
 -      float step;
 -      if(autocvar_hud_configure_grid)
 -      {
 -              if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW)
 +              vector bH;
 +              width = eX * theSize_x;
 +              height = eY * theSize_y;
 +              if(theSize_y <= theSize_x * 2)
                {
 -                      if (hudShiftState & S_SHIFT)
 -                              step = bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) * vid_conheight;
 -                      else
 -                              step = 2 * bound(0.005, autocvar_hud_configure_grid_ysize, 0.2) * vid_conheight;
 +                      // 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
                {
 -                      if (hudShiftState & S_SHIFT)
 -                              step = bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) * vid_conwidth;
 -                      else
 -                              step = 2 * bound(0.005, autocvar_hud_configure_grid_xsize, 0.2) * vid_conwidth;
 -              }
 -      }
 -      else
 -      {
 -              if (nPrimary == K_UPARROW || nPrimary == K_DOWNARROW)
 -                      step = vid_conheight;
 -              else
 -                      step = vid_conwidth;
 -              if (hudShiftState & S_SHIFT)
 -                      step = (step / 256); // more precision
 -              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;
 -
 -      if (hudShiftState & S_ALT) // resize
 -      {
 -              highlightedAction = 1;
 -              if(nPrimary == K_UPARROW)
 -                      resizeCorner = 1;
 -              else if(nPrimary == K_RIGHTARROW)
 -                      resizeCorner = 2;
 -              else if(nPrimary == K_LEFTARROW)
 -                      resizeCorner = 3;
 -              else // if(nPrimary == K_DOWNARROW)
 -                      resizeCorner = 4;
 -
 -              // ctrl+arrow reduces the size, instead of increasing it
 -              // Note that ctrl disables collisions check too, but it's fine
 -              // since we don't collide with anything reducing the size
 -              if (hudShiftState & S_CTRL) {
 -                      step = -step;
 -                      resizeCorner = 5 - resizeCorner;
 -              }
 -
 -              vector mySize;
 -              mySize = panel_size;
 -              panel_click_resizeorigin = panel_pos;
 -              if(resizeCorner == 1) {
 -                      panel_click_resizeorigin += mySize;
 -                      mySize_y += step;
 -              } else if(resizeCorner == 2) {
 -                      panel_click_resizeorigin_y += mySize_y;
 -                      mySize_x += step;
 -              } else if(resizeCorner == 3) {
 -                      panel_click_resizeorigin_x += mySize_x;
 -                      mySize_x += step;
 -              } else { // resizeCorner == 4
 -                      mySize_y += step;
 +                      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);
                }
 -              HUD_Panel_SetPosSize(mySize);
 -      }
 -      else // move
 -      {
 -              highlightedAction = 2;
 -              vector pos;
 -              pos = panel_pos;
 -              if(nPrimary == K_UPARROW)
 -                      pos_y -= step;
 -              else if(nPrimary == K_DOWNARROW)
 -                      pos_y += step;
 -              else if(nPrimary == K_LEFTARROW)
 -                      pos_x -= step;
 -              else // if(nPrimary == K_RIGHTARROW)
 -                      pos_x += step;
 -
 -              HUD_Panel_SetPos(pos);
 -      }
 -
 -      HUD_Panel_UpdatePosSizeForId(highlightedPanel);
 -
 -      if (prev_pos != panel_pos || prev_size != panel_size)
 -      {
 -              // backup!
 -              panel_pos_backup = prev_pos;
 -              panel_size_backup = prev_size;
 -              highlightedPanel_backup = highlightedPanel;
 -      }
 -}
 -
 -float HUD_Panel_InputEvent(float bInputType, float nPrimary, float nSecondary)
 -{
 -      string s;
 -
 -      if(!autocvar__hud_configure)
 -              return false;
 -
 -      // allow console bind to work
 -      string con_keys;
 -      float keys;
 -      con_keys = findkeysforcommand("toggleconsole");
 -      keys = tokenize(con_keys);
 -
 -      float hit_con_bind, i;
 -      for (i = 0; i < keys; ++i)
 -      {
 -              if(nPrimary == stof(argv(i)))
 -                      hit_con_bind = 1;
 -      }
 -
 -      if(bInputType == 0) {
 -              if(nPrimary == K_ALT) hudShiftState |= S_ALT;
 -              if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
 -              if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
 -      }
 -      else if(bInputType == 1) {
 -              if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
 -              if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
 -              if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
 -      }
 -
 -      if(nPrimary == K_MOUSE1)
 -      {
 -              if(bInputType == 0) { // key pressed
 -                      mouseClicked = 1;
 -                      return true;
 -              }
 -              else if(bInputType == 1) {// key released
 -                      mouseClicked = 0;
 -                      return true;
 +      } else {
 +              pic = strcat(hud_skin_path, "/", pic);
 +              if(precache_pic(pic) == "") {
 +                      pic = "gfx/hud/default/progressbar";
                }
 -      }
 -      else if(nPrimary == K_ESCAPE)
 -      {
 -              if (bInputType == 1)
 -                      return true;
 -              menu_enabled = 1;
 -              menu_enabled_time = time;
 -              localcmd("menu_showhudexit\n");
 -      }
 -      else if(hudShiftState & S_CTRL)
 -      {
 -              if (mouseClicked)
 -                      return true;
  
 -              if(nPrimary == K_SPACE) // enable/disable highlighted panel or dock
 +              if (baralign == 1) // right align
 +                      theOrigin_x += (1 - length_ratio) * theSize_x;
 +        else if (baralign == 2) // center align
 +            theOrigin_x += 0.5 * (1 - length_ratio) * theSize_x;
 +        else if (baralign == 3) // center align, positive values on the right, negative on the left
                {
 -                      if (bInputType == 1)
 -                              return true;
 -
 -                      if (highlightedPanel_prev != -1)
 -                              cvar_set(strcat("hud_panel_", panel_name), ftos(!(panel_enabled)));
 +                      theSize_x *= 0.5;
 +                      if (length_ratio > 0)
 +                              theOrigin_x += theSize_x;
                        else
 -                              cvar_set(strcat("hud_dock"), (autocvar_hud_dock == "") ? "dock" : "");
 -              }
 -              if(nPrimary == 'c') // copy highlighted panel size
 -              {
 -                      if (bInputType == 1)
 -                              return true;
 -
 -                      if (highlightedPanel_prev != -1)
                        {
 -                              panel_size_copied = panel_size;
 -                              highlightedPanel_copied = highlightedPanel_prev;
 +                              theOrigin_x += (1 + length_ratio) * theSize_x;
 +                              length_ratio = -length_ratio;
                        }
                }
 -              else if(nPrimary == 'v') // past copied size on the highlighted panel
 -              {
 -                      if (bInputType == 1)
 -                              return true;
 -
 -                      if (highlightedPanel_copied == -1 || highlightedPanel_prev == -1)
 -                              return true;
 -
 -                      HUD_Panel_UpdatePosSizeForId(highlightedPanel_prev);
 -
 -                      // 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;
 +              theSize_x *= length_ratio;
  
 -                      if (panel_size == tmp_size)
 -                              return true;
 -
 -                      // backup first!
 -                      panel_pos_backup = panel_pos;
 -                      panel_size_backup = panel_size;
 -                      highlightedPanel_backup = highlightedPanel_prev;
 -
 -                      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
 -              {
 -                      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;
 -                      }
 -              }
 -      }
 -      else if(nPrimary == K_UPARROW || nPrimary == K_DOWNARROW || nPrimary == K_LEFTARROW || nPrimary == K_RIGHTARROW)
 -      {
 -              if (bInputType == 1)
 +              vector bW;
 +              width = eX * theSize_x;
 +              height = eY * theSize_y;
 +              if(theSize_x <= theSize_y * 2)
                {
 -                      pressed_key_time = 0;
 -                      return true;
 -              }
 -              else if (pressed_key_time == 0)
 -                      pressed_key_time = time;
 -
 -              HUD_Panel_Arrow_Action(nPrimary); //move or resize panel
 -      }
 -      else if(hit_con_bind)
 -              return false;
 -
 -      return true; // Suppress ALL other input
 -}
 -
 -float HUD_Panel_HighlightCheck()
 -{
 -      float i, j, border;
 -      vector panelPos;
 -      vector panelSize;
 -
 -      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)
 -              {
 -                      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)
 -              {
 -                      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)
 -              {
 -                      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)
 -              {
 -                      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)
 -              {
 -                      return 2;
 -              }
 -      }
 -      return 0;
 -}
 -
 -// move a panel to the beginning of the panel order array (which means it gets drawn last, on top of everything else)
 -void HUD_Panel_FirstInDrawQ(float id)
 -{
 -      float i;
 -      var float place = -1;
 -      // find out where in the array our current id is, save into place
 -      for(i = 0; i < HUD_PANEL_NUM; ++i)
 -      {
 -              if(panel_order[i] == id)
 -              {
 -                      place = i;
 -                      break;
 -              }
 -      }
 -      // place last if we didn't find a place for it yet (probably new panel, or screwed up cvar)
 -      if(place == -1)
 -              place = HUD_PANEL_NUM - 1;
 -
 -      // move all ids up by one step in the array until "place"
 -      for(i = place; i > 0; --i)
 -      {
 -              panel_order[i] = panel_order[i-1];
 -      }
 -      // now save the new top id
 -      panel_order[0] = id;
 -      
 -      // let's save them into the cvar by some strcat trickery
 -      string s;
 -      for(i = 0; i < HUD_PANEL_NUM; ++i)
 -      {
 -              s = strcat(s, ftos(panel_order[i]), " ");
 -      }
 -      cvar_set("_hud_panelorder", s);
 -      if(hud_panelorder_prev)
 -              strunzone(hud_panelorder_prev);
 -      hud_panelorder_prev = strzone(autocvar__hud_panelorder); // prevent HUD_Main from doing useless update, we already updated here
 -}
 -
 -void HUD_Panel_Highlight()
 -{
 -      float i, j, border;
 -      vector panelPos;
 -      vector panelSize;
 -
 -      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)
 -              {
 -                      highlightedPanel = i;
 -                      HUD_Panel_FirstInDrawQ(i);
 -                      highlightedAction = 1;
 -                      panel_click_distance = mousepos - panelPos;
 -                      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)
 -              {
 -                      highlightedPanel = i;
 -                      HUD_Panel_FirstInDrawQ(i);
 -                      highlightedAction = 2;
 -                      resizeCorner = 1;
 -                      panel_click_distance = mousepos - panelPos;
 -                      panel_click_resizeorigin = panelPos + panelSize;
 -                      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)
 -              {
 -                      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;
 -                      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)
 -              {
 -                      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;
 -                      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)
 -              {
 -                      highlightedPanel = i;
 -                      HUD_Panel_FirstInDrawQ(i);
 -                      highlightedAction = 2;
 -                      resizeCorner = 4;
 -                      panel_click_distance = panelSize - mousepos + panelPos;
 -                      panel_click_resizeorigin = panelPos;
 -                      return;
 +                      // 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
                {
 -                      highlightedPanel_prev = -1;
 +                      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);
                }
        }
  }
  
 -float highlightcheck;
 -vector prev_pos, prev_size;
 -void HUD_Panel_Mouse()
 +void HUD_Panel_DrawHighlight(vector pos, vector mySize, vector color, float alpha, float drawflag)
  {
 -      // 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 (autocvar__menu_alpha == 0 && time - menu_enabled_time > 0.5)
 -              menu_enabled = 0;
 -
 -      /*
 -      print("menu_enabled: ", ftos(menu_enabled), "\n");
 -      print("Highlighted: ", ftos(highlightedPanel), "\n");
 -      print("Menu alpha: ", ftos(autocvar__menu_alpha), "\n");
 -      */
 -
 -      // instantly hide the editor cursor if we open the HUDExit dialog
 -      // as hud_fade_alpha doesn't decrease to 0 in this case
 -      // TODO: find a way to fade the cursor out even in this case
 -      if(menu_enabled == 1 || (menu_enabled == 2 && !hud_fade_alpha))
 +      if(!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);
 -      mousepos_y = bound(0, mousepos_y, vid_conheight);
 -
 -      if(mouseClicked)
 -      {
 -              if(prevMouseClicked == 0)
 -              {
 -                      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;
 -              }
 -              else
 -                      HUD_Panel_UpdatePosSizeForId(highlightedPanel);
 -
 -              if (prev_pos != panel_pos || prev_size != panel_size)
 -              {
 -                      hud_configure_checkcollisions = (!(hudShiftState & S_CTRL) && autocvar_hud_configure_checkcollisions);
 -                      // backup!
 -                      panel_pos_backup = prev_pos;
 -                      panel_size_backup = prev_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;
 -
 -              if(highlightedAction == 1)
 -                      HUD_Panel_SetPos(mousepos - panel_click_distance);
 -              else if(highlightedAction == 2)
 -              {
 -                      vector mySize;
 -                      if(resizeCorner == 1) {
 -                              mySize_x = panel_click_resizeorigin_x - (mousepos_x - panel_click_distance_x);
 -                              mySize_y = panel_click_resizeorigin_y - (mousepos_y - panel_click_distance_y);
 -                      } else if(resizeCorner == 2) {
 -                              mySize_x = mousepos_x + panel_click_distance_x - panel_click_resizeorigin_x;
 -                              mySize_y = panel_click_distance_y + panel_click_resizeorigin_y - mousepos_y;
 -                      } else if(resizeCorner == 3) {
 -                              mySize_x = panel_click_resizeorigin_x + panel_click_distance_x - mousepos_x;
 -                              mySize_y = mousepos_y + panel_click_distance_y - panel_click_resizeorigin_y;
 -                      } else { // resizeCorner == 4
 -                              mySize_x = mousepos_x - (panel_click_resizeorigin_x - panel_click_distance_x);
 -                              mySize_y = mousepos_y - (panel_click_resizeorigin_y - panel_click_distance_y);
 -                      }
 -                      HUD_Panel_SetPosSize(mySize);
 -              }
 -
 -              // doubleclick check
 -              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");
 -                      return;
 -              }
 -              if(prevMouseClicked == 0)
 -              {
 -                      prevMouseClickedTime = time;
 -                      prevMouseClickedPos = mousepos;
 -              }
 -      }
 -      else
 -      {
 -              highlightcheck = HUD_Panel_HighlightCheck();
 +      string pic;
 +      pic = strcat(hud_skin_path, "/num_leading");
 +      if(precache_pic(pic) == "") {
 +              pic = "gfx/hud/default/num_leading";
        }
 -      // draw cursor after performing move/resize to have the panel pos/size updated before highlightcheck
 -      vector cursorsize;
 -      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);
 -      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);
 -      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);
 -      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);
 -
 -      prevMouseClicked = mouseClicked;
 +      drawsubpic(pos, eX * min(mySize_x * 0.5, mySize_y) + eY * mySize_y, pic, '0 0 0', '0.25 1 0', color, alpha, drawflag);
 +      if(mySize_x/mySize_y > 2)
 +              drawsubpic(pos + eX * mySize_y, eX * (mySize_x - 2 * mySize_y) + eY * mySize_y, pic, '0.25 0 0', '0.5 1 0', color, alpha, drawflag);
 +      drawsubpic(pos + eX * mySize_x - eX * min(mySize_x * 0.5, mySize_y), eX * min(mySize_x * 0.5, mySize_y) + eY * mySize_y, pic, '0.75 0 0', '0.25 1 0', color, alpha, drawflag);
  }
  
  // Weapon icons (#0)
  //
 -float weaponspace[10];
 -#define HUD_Weapons_Clear()\
 -      float idx;\
 -      for(idx = 0; idx < 10; ++idx)\
 -              weaponspace[idx] = 0
 -
  entity weaponorder[WEP_MAXCOUNT];
  void weaponorder_swap(float i, float j, entity pass)
  {
@@@ -615,13 -1532,8 +615,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)
        {
                f = (time - (weapontime + timeout)) / timeout_effect_length;
 -              if (autocvar_hud_panel_weapons_timeout_effect)
 +              if (autocvar_hud_panel_weapons_timeout_effect == 1 || autocvar_hud_panel_weapons_timeout_effect == 3)
                {
                        panel_bg_alpha *= (1 - f);
                        panel_fg_alpha *= (1 - f);
                }
 -              if (autocvar_hud_panel_weapons_timeout_effect == 1)
 +              if (autocvar_hud_panel_weapons_timeout_effect == 2 || autocvar_hud_panel_weapons_timeout_effect == 3)
                {
                        f *= f; // for a cooler movement
                        center_x = panel_pos_x + panel_size_x/2;
        else if (timeout && time < weaponprevtime + timein_effect_length && !autocvar__hud_configure)
        {
                f = (time - weaponprevtime) / timein_effect_length;
 -              if (autocvar_hud_panel_weapons_timeout_effect)
 +              if (autocvar_hud_panel_weapons_timeout_effect == 1 || autocvar_hud_panel_weapons_timeout_effect == 3)
                {
                        panel_bg_alpha *= (f);
                        panel_fg_alpha *= (f);
                }
 -              if (autocvar_hud_panel_weapons_timeout_effect == 1)
 +              if (autocvar_hud_panel_weapons_timeout_effect == 2 || autocvar_hud_panel_weapons_timeout_effect == 3)
                {
                        f *= f; // for a cooler movement
                        f = 1 - f;
        }
  
        float i, weapid, wpnalpha, weapon_cnt;
 -      weapon_cnt = 0;
 -      for(i = WEP_FIRST; i <= WEP_LAST; ++i)
 -      {
 -              self = get_weaponinfo(i);
 -              if(self.impulse >= 0)
 -                      ++weapon_cnt;
 -      }
  
        // TODO make this configurable
        if(weaponorder_bypriority != autocvar_cl_weaponpriority || !weaponorder[0])
                                ++weapon_cnt;
                        }
                }
 +              for(i = weapon_cnt; i < WEP_MAXCOUNT; ++i)
 +                      weaponorder[i] = NULL;
                heapsort(weapon_cnt, weaponorder_swap, weaponorder_cmp, world);
  
                weaponorder_cmp_str = string_null;
        else
                wpnalpha = panel_fg_alpha;
  
 -      HUD_Weapons_Clear();
 -
        float rows, columns;
        float aspect = autocvar_hud_panel_weapons_aspect;
        rows = panel_size_y/panel_size_x;
        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;
  
        }
  
        float weapons_st = getstati(STAT_WEAPONS);
 -      float label = autocvar_hud_panel_weapons_label;
  
 -      for(i = 0; i < weapon_cnt; ++i)
 +      for(i = 0; i <= WEP_LAST-WEP_FIRST; ++i)
        {
 +              self = weaponorder[i];
 +              if (!self || self.impulse < 0)
 +                      continue;
                wpnpos = panel_pos + eX * column * wpnsize_x + eY * row * wpnsize_y;
  
 -              self = weaponorder[i];
                weapid = self.impulse;
  
                // draw background behind currently selected weapon
                }
  
                // draw the weapon icon
 -              if((weapid >= 0) && (weapons_st & self.weapons))
 +              if(weapons_st & self.weapons)
                {
                        drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '1 1 1', wpnalpha, DRAWFLAG_NORMAL);
  
 -                      if(label == 1) // weapon number
 +                      if(autocvar_hud_panel_weapons_label == 1) // weapon number
                                drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * wpnsize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                      else if(label == 2) // bind
 +                      else if(autocvar_hud_panel_weapons_label == 2) // bind
                                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 && self.weapon != WEP_TUBA && self.weapon != WEP_LASER && self.weapon != WEP_PORTO)
 +                      if(autocvar_hud_panel_weapons_ammo && self.weapon != WEP_TUBA && self.weapon != WEP_LASER && self.weapon != WEP_PORTO)
                        {
                                a = 0;
                                type = GetAmmoTypeForWep(self.weapon);
                                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;
                                        }
  
@@@ -969,7 -1895,7 +969,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, a/autocvar_hud_panel_ammo_maxammo, 0, 0, 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;
                        column = column + 1;
                }
        }
 -}
 +}
 +
 +void DrawNumIcon(vector myPos, vector mySize, float x, string icon, float vertical, float icon_right_align, vector color, float alpha)
 +{
 +      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;
 +      }
  
 -void DrawNumIcon(float iconalign, vector myPos, vector mySize, float x, string icon, float left, vector color, float alpha)
 -{
 -      vector newPos;
 -      float newSize_x, newSize_y;
        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;
        }
  
 -      drawstring_aspect(numpos, ftos(x), eX * (2/3) * newSize_x + eY * newSize_y, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
 +      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 picpos;
 -      vector numpos;
 -
 -      string leftname, rightname;
 -    string leftprogressname, rightprogressname;
 -      float leftcnt, rightcnt;
 -      float leftexact, rightexact;
 -      float flip = autocvar_hud_panel_powerups_flip;
 -      if (flip) {
 -              leftname = "strength";
 -        leftprogressname = autocvar_hud_panel_powerups_progressbar_strength;
 -              leftcnt = ceil(strength_time);
 -              leftexact = strength_time;
 -
 -              rightname = "shield";
 -        rightprogressname = autocvar_hud_panel_powerups_progressbar_shield;
 -              rightcnt = ceil(shield_time);
 -              rightexact = shield_time;
 -      } else {
 -              leftname = "shield";
 -        leftprogressname = autocvar_hud_panel_powerups_progressbar_shield;
 -              leftcnt = ceil(shield_time);
 -              leftexact = shield_time;
 +      float panel_ar = mySize_x/mySize_y;
 +      float is_vertical = (panel_ar < 1);
 +      vector shield_offset, strength_offset;
 +      if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
 +      {
 +              mySize_x *= 0.5;
 +              if (autocvar_hud_panel_powerups_flip)
 +                      shield_offset_x = mySize_x;
 +              else
 +                      strength_offset_x = mySize_x;
 +      }
 +      else
 +      {
 +              mySize_y *= 0.5;
 +              if (autocvar_hud_panel_powerups_flip)
 +                      shield_offset_y = mySize_y;
 +              else
 +                      strength_offset_y = mySize_y;
 +      }
  
 -              rightname = "strength";
 -        rightprogressname = autocvar_hud_panel_powerups_progressbar_strength;
 -              rightcnt = ceil(strength_time);
 -              rightexact = strength_time;
 +      float shield_baralign, strength_baralign;
 +      float shield_iconalign, strength_iconalign;
 +      if (autocvar_hud_panel_powerups_flip)
 +      {
 +              strength_baralign = (autocvar_hud_panel_powerups_baralign == 2 || autocvar_hud_panel_powerups_baralign == 1);
 +              shield_baralign = (autocvar_hud_panel_powerups_baralign == 3 || autocvar_hud_panel_powerups_baralign == 1);
 +              strength_iconalign = (autocvar_hud_panel_powerups_iconalign == 2 || autocvar_hud_panel_powerups_iconalign == 1);
 +              shield_iconalign = (autocvar_hud_panel_powerups_iconalign == 3 || autocvar_hud_panel_powerups_iconalign == 1);
 +      }
 +      else
 +      {
 +              shield_baralign = (autocvar_hud_panel_powerups_baralign == 2 || autocvar_hud_panel_powerups_baralign == 1);
 +              strength_baralign = (autocvar_hud_panel_powerups_baralign == 3 || autocvar_hud_panel_powerups_baralign == 1);
 +              shield_iconalign = (autocvar_hud_panel_powerups_iconalign == 2 || autocvar_hud_panel_powerups_iconalign == 1);
 +              strength_iconalign = (autocvar_hud_panel_powerups_iconalign == 3 || autocvar_hud_panel_powerups_iconalign == 1);
        }
  
 -      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)
 +      if(shield_time)
        {
 -        barsize = eX * 0.5 * mySize_x + eY * mySize_y;
 -              if(leftcnt)
 +              const float maxshield = 30;
 +              float shield = ceil(shield_time);
 +              if(autocvar_hud_panel_powerups_progressbar)
                {
 -                      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)
 -                      {
 -                              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 * 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));
 -            }
 +                      HUD_Panel_GetProgressBarColor(shield);
 +                      HUD_Panel_DrawProgressBar(pos + shield_offset, mySize, autocvar_hud_panel_powerups_progressbar_shield, shield/maxshield, is_vertical, shield_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                }
 -
 -              if(rightcnt)
 +              if(autocvar_hud_panel_powerups_text)
                {
 -                      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(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));
 -            }
 +                      if(shield > 1)
 +                              DrawNumIcon(pos + shield_offset, mySize, shield, "shield", is_vertical, shield_iconalign, '1 1 1', 1);
 +                      if(shield <= 5)
 +                              DrawNumIcon_expanding(pos + shield_offset, mySize, shield, "shield", is_vertical, shield_iconalign, '1 1 1', bound(0, (shield - shield_time) / 0.5, 1));
                }
        }
 -      else if (mySize_x/mySize_y > 1.5)
 +
 +      if(strength_time)
        {
 -        barsize = eX * mySize_x + eY * 0.5 * mySize_y;
 -              if(leftcnt)
 +              const float maxstrength = 30;
 +              float strength = ceil(strength_time);
 +              if(autocvar_hud_panel_powerups_progressbar)
                {
 -            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));
 -            }
 +                      HUD_Panel_GetProgressBarColor(strength);
 +                      HUD_Panel_DrawProgressBar(pos + strength_offset, mySize, autocvar_hud_panel_powerups_progressbar_strength, strength/maxstrength, is_vertical, strength_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                }
 -
 -              if(rightcnt)
 +              if(autocvar_hud_panel_powerups_text)
                {
 -            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/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(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(strength > 1)
 +                              DrawNumIcon(pos + strength_offset, mySize, strength, "strength", is_vertical, strength_iconalign, '1 1 1', 1);
 +                      if(strength <= 5)
 +                              DrawNumIcon_expanding(pos + strength_offset, mySize, strength, "strength", is_vertical, strength_iconalign, '1 1 1', bound(0, (strength - strength_time) / 0.5, 1));
                }
        }
 -      else
 -      {
 -        barsize = eX * 0.5 * mySize_x + eY * 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;
 -                      }
 +// Health/armor (#3)
 +//
  
 -                      if(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);
 -                      }
 -            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);
 -            }
 -              }
 +// prev_* vars contain the health/armor at the previous FRAME
 +// set to -1 when player is dead or was not playing
 +float prev_health, prev_armor;
 +float health_damagetime, armor_damagetime;
 +float health_beforedamage, armor_beforedamage;
 +// old_p_* vars keep track of previous values when smoothing value changes of the progressbar
 +float old_p_health, old_p_armor;
 +float old_p_healthtime, old_p_armortime;
 +// prev_p_* vars contain the health/armor progressbar value at the previous FRAME
 +// set to -1 to forcedly stop effects when we switch spectated player (e.g. from playerX: 70h to playerY: 50h)
 +float prev_p_health, prev_p_armor;
 +
 +void HUD_HealthArmor(void)
 +{
 +      float armor, health, fuel;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_healtharmor) return;
 +              if(spectatee_status == -1) return;
  
 -              if(rightcnt)
 +              health = getstati(STAT_HEALTH);
 +              if(health <= 0)
                {
 -            barpos = pos + eX * 0.5 * mySize_x;
 -                      if(baralign == 0 || baralign == 3) { // down align
 -                barflip = 1;
 -                      } else { // up align
 -                barflip = 0;
 -                      }
 +                      prev_health = -1;
 +                      return;
 +              }
 +              armor = getstati(STAT_ARMOR);
  
 -                      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;
 -                      }
 +              // code to check for spectatee_status changes is in Ent_ClientData()
 +              // prev_p_health and prev_health can be set to -1 there
  
 -                      if(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);
 -                      }
 -            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 (prev_p_health == -1)
 +              {
 +                      // no effect
 +                      health_beforedamage = 0;
 +                      armor_beforedamage = 0;
 +                      health_damagetime = 0;
 +                      armor_damagetime = 0;
 +                      prev_health = health;
 +                      prev_armor = armor;
 +                      old_p_health = health;
 +                      old_p_armor = armor;
 +                      prev_p_health = health;
 +                      prev_p_armor = armor;
 +              }
 +              else if (prev_health == -1)
 +              {
 +                      //start the load effect
 +                      health_damagetime = 0;
 +                      armor_damagetime = 0;
 +                      prev_health = 0;
 +                      prev_armor = 0;
                }
 +              fuel = getstati(STAT_FUEL);
        }
 -}
 +      else
 +      {
 +              hud_configure_active_panel = HUD_PANEL_HEALTHARMOR;
  
 -// Health/armor (#3)
 -//
 -void HUD_HealthArmor(void)
 -{
 -      if(!autocvar_hud_panel_healtharmor && !autocvar__hud_configure)
 -              return;
 +              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;
 -
        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
        {
 -              string leftname, rightname;
 -        string leftprogressname, rightprogressname;
 -              float leftcnt, rightcnt;
 -              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
 -                      leftname = "armor";
 -            leftprogressname = autocvar_hud_panel_healtharmor_progressbar_armor;
 -                      leftcnt = armor;
 -                      if(leftcnt)
 -                              leftactive = 1;
 -                      leftalpha = min((armor+10)/55, 1);
 -            leftmax = maxarmor;
 -
 -                      rightname = "health";
 -            rightprogressname = autocvar_hud_panel_healtharmor_progressbar_health;
 -                      rightcnt = health;
 -                      rightactive = 1;
 -                      rightalpha = 1;
 -            rightmax = maxhealth;
 -              } else {
 -                      leftname = "health";
 -            leftprogressname = autocvar_hud_panel_healtharmor_progressbar_health;
 -                      leftcnt = health;
 -                      leftactive = 1;
 -                      leftalpha = 1;
 -            leftmax = maxhealth;
 -
 -                      rightname = "armor";
 -            rightprogressname = autocvar_hud_panel_healtharmor_progressbar_armor;
 -                      rightcnt = armor;
 -                      if(rightcnt)
 -                              rightactive = 1;
 -                      rightalpha = min((armor+10)/55, 1);
 -            rightmax = maxarmor;
 -              }
 -
 -              if (mySize_x/mySize_y > 4)
 +              float panel_ar = mySize_x/mySize_y;
 +              float is_vertical = (panel_ar < 1);
 +              vector health_offset, armor_offset;
 +              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)
 -                              {
 -                                      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 * 0.5 * mySize_x + eY * mySize_y, leftcnt, leftname, 1, 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)
 -                              {
 -                                      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 + eX * 0.5 * mySize_x, eX * 0.5 * mySize_x + eY * 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);
 -                      }
 +                      mySize_x *= 0.5;
 +                      if (autocvar_hud_panel_healtharmor_flip)
 +                              health_offset_x = mySize_x;
 +                      else
 +                              armor_offset_x = mySize_x;
                }
 -              else if (mySize_x/mySize_y > 1.5)
 +              else
                {
 -            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);
 -                      }
 +                      mySize_y *= 0.5;
 +                      if (autocvar_hud_panel_healtharmor_flip)
 +                              health_offset_y = mySize_y;
 +                      else
 +                              armor_offset_y = mySize_y;
 +              }
  
 -                      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);
 -                      }
 +              float health_baralign, armor_baralign, fuel_baralign;
 +              float health_iconalign, armor_iconalign;
 +              if (autocvar_hud_panel_healtharmor_flip)
 +              {
 +                      armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
 +                      health_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
 +                      fuel_baralign = health_baralign;
 +                      armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
 +                      health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
                }
                else
                {
 -            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(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;
 -                              }
 +                      health_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
 +                      armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
 +                      fuel_baralign = armor_baralign;
 +                      health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
 +                      armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
 +              }
  
 -                              if(progressbar)
 +              //if(health)
 +              {
 +                      if(autocvar_hud_panel_healtharmor_progressbar)
 +                      {
 +                              HUD_Panel_GetProgressBarColor(health);
 +                              float p_health, pain_health_alpha;
 +                              p_health = health;
 +                              pain_health_alpha = 1;
 +                              if (autocvar_hud_panel_healtharmor_progressbar_gfx)
                                {
 -                                      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);
 +                                      if (autocvar_hud_panel_healtharmor_progressbar_gfx_smooth > 0)
 +                                      {
 +                                              if (fabs(prev_health - health) >= autocvar_hud_panel_healtharmor_progressbar_gfx_smooth)
 +                                              {
 +                                                      if (time - old_p_healthtime < 1)
 +                                                              old_p_health = prev_p_health;
 +                                                      else
 +                                                              old_p_health = prev_health;
 +                                                      old_p_healthtime = time;
 +                                              }
 +                                              if (time - old_p_healthtime < 1)
 +                                              {
 +                                                      p_health += (old_p_health - health) * (1 - (time - old_p_healthtime));
 +                                                      prev_p_health = p_health;
 +                                              }
 +                                      }
 +                                      if (autocvar_hud_panel_healtharmor_progressbar_gfx_damage > 0)
 +                                      {
 +                                              if (prev_health - health >= autocvar_hud_panel_healtharmor_progressbar_gfx_damage)
 +                                              {
 +                                                      if (time - health_damagetime >= 1)
 +                                                              health_beforedamage = prev_health;
 +                                                      health_damagetime = time;
 +                                              }
 +                                              if (time - health_damagetime < 1)
 +                                              {
 +                                                      float health_damagealpha = 1 - (time - health_damagetime)*(time - health_damagetime);
 +                                                      HUD_Panel_DrawProgressBar(pos + health_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_health, health_beforedamage/maxhealth, is_vertical, health_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * health_damagealpha, DRAWFLAG_NORMAL);
 +                                              }
 +                                      }
 +                                      prev_health = health;
 +
 +                                      if (health <= autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth)
 +                                      {
 +                                              float BLINK_FACTOR = 0.15;
 +                                              float BLINK_BASE = 0.85;
 +                                              float BLINK_FREQ = 9; 
 +                                              pain_health_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
 +                                      }
                                }
 -                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);
 -                }
 +                              HUD_Panel_DrawProgressBar(pos + health_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_health, p_health/maxhealth, is_vertical, health_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * pain_health_alpha, DRAWFLAG_NORMAL);
                        }
 +                      if(autocvar_hud_panel_healtharmor_text)
 +                              DrawNumIcon(pos + health_offset, mySize, health, "health", is_vertical, health_iconalign, HUD_Get_Num_Color(health, maxhealth), 1);
 +              }
  
 -                      if(rightactive)
 +              if(armor)
 +              {
 +                      if(autocvar_hud_panel_healtharmor_progressbar)
                        {
 -                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)
 +                              HUD_Panel_GetProgressBarColor(armor);
 +                              float p_armor;
 +                              p_armor = armor;
 +                              if (autocvar_hud_panel_healtharmor_progressbar_gfx)
                                {
 -                                      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);
 +                                      if (autocvar_hud_panel_healtharmor_progressbar_gfx_smooth > 0)
 +                                      {
 +                                              if (fabs(prev_armor - armor) >= autocvar_hud_panel_healtharmor_progressbar_gfx_smooth)
 +                                              {
 +                                                      if (time - old_p_armortime < 1)
 +                                                              old_p_armor = prev_p_armor;
 +                                                      else
 +                                                              old_p_armor = prev_armor;
 +                                                      old_p_armortime = time;
 +                                              }
 +                                              if (time - old_p_armortime < 1)
 +                                              {
 +                                                      p_armor += (old_p_armor - armor) * (1 - (time - old_p_armortime));
 +                                                      prev_p_armor = p_armor;
 +                                              }
 +                                      }
 +                                      if (autocvar_hud_panel_healtharmor_progressbar_gfx_damage > 0)
 +                                      {
 +                                              if (prev_armor - armor >= autocvar_hud_panel_healtharmor_progressbar_gfx_damage)
 +                                              {
 +                                                      if (time - armor_damagetime >= 1)
 +                                                              armor_beforedamage = prev_armor;
 +                                                      armor_damagetime = time;
 +                                              }
 +                                              if (time - armor_damagetime < 1)
 +                                              {
 +                                                      float armor_damagealpha = 1 - (time - armor_damagetime)*(time - armor_damagetime);
 +                                                      HUD_Panel_DrawProgressBar(pos + armor_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_armor, armor_beforedamage/maxarmor, is_vertical, armor_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * armor_damagealpha, DRAWFLAG_NORMAL);
 +                                              }
 +                                      }
 +                                      prev_armor = armor;
                                }
 -                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);
 -                }
 +                              HUD_Panel_DrawProgressBar(pos + armor_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_armor, p_armor/maxarmor, is_vertical, armor_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                        }
 +                      if(autocvar_hud_panel_healtharmor_text)
 +                              DrawNumIcon(pos + armor_offset, mySize, armor, "armor", is_vertical, armor_iconalign, HUD_Get_Num_Color(armor, maxarmor), 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);
 -                      }
 +              if(fuel)
 +              {
 +                      if (is_vertical)
 +                              mySize_x *= 0.2 / 2; //if vertical always halve x to not cover too much numbers with 3 digits
 +                      else
 +                              mySize_y *= 0.2;
 +                      if (panel_ar >= 4)
 +                              mySize_x *= 2; //restore full panel size
 +                      else if (panel_ar < 1/4)
 +                              mySize_y *= 2; //restore full panel size
 +                      HUD_Panel_GetProgressBarColor(fuel);
 +                      HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, fuel_baralign, progressbar_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
                }
        }
  }
@@@ -1850,7 -2899,7 +1850,7 @@@ void HUD_KillNotify(string s1, string s
                                print (sprintf(_("%s^7 is a ^1BERSERKER!\n"), s1));
                } else if(type == KILL_SPREE_25) {
                        if(gentle)
-                               print (sprintf(_("%s^7 made ^1TWENTY FIFE SCORES IN A ROW!\n"), s1));
+                               print (sprintf(_("%s^7 made ^1TWENTY FIVE SCORES IN A ROW!\n"), s1));
                        else
                                print (sprintf(_("%s^7 inflicts ^1CARNAGE!\n"), s1));
                } else if(type == KILL_SPREE_30) {
@@@ -2083,13 -3132,10 +2083,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;
@@@ -2396,13 -3442,10 +2396,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;
                  f * mi_center
                + (1 - f) * view_origin);
  
 -      color1 = GetPlayerColor(player_localentnum-1);
 -      rgb = GetTeamRGB(color1);
 -
        drawsetcliparea(
                pos_x,
                pos_y,
                mySize_y
        );
  
 -      draw_teamradar_background(hud_panel_radar_foreground_alpha);
 +      draw_teamradar_background(hud_panel_radar_foreground_alpha);
 +
 +      for(tm = world; (tm = find(tm, classname, "radarlink")); )
 +              draw_teamradar_link(tm.origin, tm.velocity, tm.team);
 +      for(tm = world; (tm = findflags(tm, teamradar_icon, 0xFFFFFF)); )
 +              draw_teamradar_icon(tm.origin, tm.teamradar_icon, tm, tm.teamradar_color, panel_fg_alpha);
 +      for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
 +      {
 +              color2 = GetPlayerColor(tm.sv_entnum);
 +              //if(color == COLOR_SPECTATOR || color == color2)
 +                      draw_teamradar_player(tm.origin, tm.angles, GetTeamRGB(color2));
 +      }
 +      draw_teamradar_player(view_origin, view_angles, '1 1 1');
 +
 +      drawresetcliparea();
 +};
 +
 +// Score (#7)
 +//
 +void HUD_UpdatePlayerTeams();
 +void HUD_Score_Rankings(vector pos, vector mySize, entity me, float team_count)
 +{
 +      float score;
 +      entity tm, pl;
 +#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, score_color;
 +      rgb = '1 1 1';
 +      score_color = '1 1 1';
 +
 +      const float name_size = mySize_x*0.75;
 +      const float spacing_size = mySize_x*0.04;
 +      const float highlight_alpha = 0.2;
 +      float i, me_printed, first_pl;
 +      string s;
 +      i, first_pl = 0;
 +      if (autocvar__hud_configure)
 +      {
 +              if (team_count)
 +              {
 +                      // show team scores in the first line
 +                      float score_size = mySize_x / team_count;
 +                      for(tm = teams.sort_next; tm; tm = tm.sort_next) {
 +                              if(tm.team == COLOR_SPECTATOR)
 +                                      continue;
 +                              if (tm.team == myteam)
 +                                      HUD_Panel_DrawHighlight(pos - eY * (height * (1 - 0.9) / 2) + eX * score_size * i, eX * score_size + eY * height, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring_aspect(pos + eX * score_size * i, ftos(123), eX * score_size + eY * fontsize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              ++i;
 +                      }
 +                      first_pl = 1;
 +                      pos_y += height;
 +              }
 +              score = 10 + SCOREPANEL_MAX_ENTRIES * 3;
 +              for (i=first_pl; 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 = sprintf(_("Player %d"), i + 1 - first_pl);
 +                              score -= 3;
 +                      }
 +
 +                      if (team_count)
 +                              score_color = GetTeamRGB(ColorByTeam(mod(i + 2, team_count))) * 0.8;
 +                      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 * (name_size + spacing_size), ftos(score), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      pos_y += height;
 +              }
 +              return;
 +      }
 +
 +      if (!scoreboard_fade_alpha) // the scoreboard too calls HUD_UpdatePlayerTeams
 +              HUD_UpdatePlayerTeams();
 +      if (team_count)
 +      {
 +              // show team scores in the first line
 +              float score_size = mySize_x / team_count;
 +              for(tm = teams.sort_next; tm; tm = tm.sort_next) {
 +                      if(tm.team == COLOR_SPECTATOR)
 +                              continue;
 +                      if (tm.team == myteam)
 +                              drawfill(pos - eY * (height * (1 - 0.9) / 2) + eX * score_size * i, eX * score_size + eY * height, '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores[ts_primary])), eX * score_size + eY * fontsize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      ++i;
 +              }
 +              first_pl = 1;
 +              pos_y += height;
 +      }
 +      i = first_pl;
 +      for (pl = players.sort_next; 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;
 +              }
  
 -      for(tm = world; (tm = find(tm, classname, "radarlink")); )
 -              draw_teamradar_link(tm.origin, tm.velocity, tm.team);
 -      for(tm = world; (tm = findflags(tm, teamradar_icon, 0xFFFFFF)); )
 -              draw_teamradar_icon(tm.origin, tm.teamradar_icon, tm, tm.teamradar_color, panel_fg_alpha);
 -      for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
 -      {
 -              color2 = GetPlayerColor(tm.sv_entnum);
 -              //if(color == COLOR_SPECTATOR || color == color2)
 -                      draw_teamradar_player(tm.origin, tm.angles, GetTeamRGB(color2));
 +              if (pl == me)
 +              {
 +                      if (i == first_pl)
 +                              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);
 +              }
 +              if (team_count)
 +                      score_color = GetTeamRGB(pl.team) * 0.8;
 +              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 * (name_size + spacing_size), ftos(pl.(scores[ps_primary])), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              pos_y += height;
        }
 -      draw_teamradar_player(view_origin, view_angles, '1 1 1');
 -
 -      drawresetcliparea();
 -};
 +}
  
 -// Score (#7)
 -//
  void HUD_Score(void)
  {
 -      if(!autocvar_hud_panel_score && !autocvar__hud_configure)
 -              return;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_score) return;
 +              if(spectatee_status == -1 && (gametype == GAME_RACE || gametype == GAME_CTS)) 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;
                        HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                drawstring_aspect(pos, timer, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
        } else if (!teamplay) { // non-teamgames
 +              if ((spectatee_status == -1 && !autocvar__hud_configure) || autocvar_hud_panel_score_rankings)
 +              {
 +                      HUD_Score_Rankings(pos, mySize, me, 0);
 +                      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);
 +              }
                drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              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 scores_count, row, column, rows, columns;
 +              vector offset;
 +              vector score_pos, score_size; //for scores other than myteam
 +              if (spectatee_status == -1 || autocvar_hud_panel_score_rankings)
 +              {
 +                      for(tm = teams.sort_next; tm, tm.team != COLOR_SPECTATOR; tm = tm.sort_next)
 +                              ++scores_count;
 +                      if (autocvar_hud_panel_score_rankings)
 +                      {
 +                              HUD_Score_Rankings(pos, mySize, me, scores_count);
 +                              return;
 +                      }
 +                      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);
 +
                float max_fragcount;
                max_fragcount = -99;
 -
 -              float teamnum;
                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);
 +                              drawstring_aspect(score_pos, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              ++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);
                                drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                        } 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;
@@@ -3038,24 -3896,19 +3038,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;
 +              if (autocvar__hud_configure)
 +              {
 +                      vote_yescount = 0;
 +                      vote_nocount = 0;
 +                      print(_("^1You must 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;
 +              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)
@@@ -3576,11 -4429,17 +3576,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, "progressbar", 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, "progressbar", p, 1, 0, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
        }
  
        if (stat_items & IT_KEY1)
@@@ -3732,117 -4591,19 +3732,117 @@@ void HUD_Mod_Race(vector pos, vector my
        }
  }
  
 +void DrawDomItem(vector myPos, vector mySize, float aspect_ratio, float layout, float i)
 +{
 +      float stat, pps_ratio;
 +      string pic;
 +      vector color;
 +      switch(i)
 +      {
 +              case 0:
 +                      stat = getstatf(STAT_DOM_PPS_RED);
 +                      pic = "dom_icon_red";
 +                      color = '1 0 0';
 +                      break;
 +              case 1:
 +                      stat = getstatf(STAT_DOM_PPS_BLUE);
 +                      pic = "dom_icon_blue";
 +                      color = '0 0 1';
 +                      break;
 +              case 2:
 +                      stat = getstatf(STAT_DOM_PPS_YELLOW);
 +                      pic = "dom_icon_yellow";
 +                      color = '1 1 0';
 +                      break;
 +              case 3:
 +                      stat = getstatf(STAT_DOM_PPS_PINK);
 +                      pic = "dom_icon_pink";
 +                      color = '1 0 1';
 +      }
 +      pps_ratio = stat / getstatf(STAT_DOM_TOTAL_PPS);
 +
 +      if(mySize_x/mySize_y > aspect_ratio)
 +      {
 +              i = aspect_ratio * mySize_y;
 +              myPos_x = myPos_x + (mySize_x - i) / 2;
 +              mySize_x = i;
 +      }
 +      else
 +      {
 +              i = 1/aspect_ratio * mySize_x;
 +              myPos_y = myPos_y + (mySize_y - i) / 2;
 +              mySize_y = i;
 +      }
 +
 +      if (layout) // show text too
 +      {
 +              //draw the text
 +              color *= 0.5 + pps_ratio * (1 - 0.5); // half saturated color at min, full saturated at max
 +              if (layout == 2) // average pps
 +                      drawstring_aspect(myPos + eX * mySize_y, ftos_decimals(stat, 2), eX * (2/3) * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
 +              else // percentage of average pps
 +                      drawstring_aspect(myPos + eX * mySize_y, strcat( ftos(floor(pps_ratio*100 + 0.5)), "%" ), eX * (2/3) * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
 +      }
 +
 +      //draw the icon
 +      drawpic_aspect_skin(myPos, pic, '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +      if (stat > 0)
 +      {
 +              drawsetcliparea(myPos_x, myPos_y + mySize_y * (1 - pps_ratio), mySize_y, mySize_y * pps_ratio);
 +              drawpic_aspect_skin(myPos, strcat(pic, "-highlighted"), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 +              drawresetcliparea();
 +      }
 +}
 +
 +void HUD_Mod_Dom(vector myPos, vector mySize)
 +{
 +      mod_active = 1; // required in each mod function that always shows something
 +      entity tm;
 +      float teams_count;
 +      for(tm = teams.sort_next; tm; tm = tm.sort_next)
 +              if(tm.team != COLOR_SPECTATOR)
 +                      ++teams_count;
 +
 +      float layout = autocvar_hud_panel_modicons_dom_layout;
 +      float rows, columns, aspect_ratio;
 +      rows = mySize_y/mySize_x;
 +      aspect_ratio = (layout) ? 3 : 1;
 +      rows = bound(1, floor((sqrt((4 * aspect_ratio * teams_count + rows) * rows) + rows + 0.5) / 2), teams_count);
 +      columns = ceil(teams_count/rows);
 +
 +      int i;
 +      float row, column;
 +      for(i=0; i<teams_count; ++i)
 +      {
 +              vector pos, itemSize;
 +              pos = myPos + eX * column * mySize_x*(1/columns) + eY * row * mySize_y*(1/rows);
 +              itemSize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
 +
 +              DrawDomItem(pos, itemSize, aspect_ratio, layout, i);
 +
 +              ++row;
 +              if(row >= rows)
 +              {
 +                      row = 0;
 +                      ++column;
 +              }
 +      }
 +}
 +
  float mod_prev; // previous state of mod_active to check for a change
  float mod_alpha;
  float mod_change; // "time" when mod_active changed
  
  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 && gametype != GAME_DOMINATION) return;
 +      }
 +      else
 +              hud_configure_active_panel = HUD_PANEL_MODICONS;
  
 -      active_panel = HUD_PANEL_MODICONS;
        HUD_Panel_UpdateCvars(modicons);
        vector pos, mySize;
        pos = panel_pos;
                HUD_Mod_Race(pos, mySize);
        else if(gametype == GAME_CA || gametype == GAME_FREEZETAG)
                HUD_Mod_CA(pos, mySize);
 +      else if(gametype == GAME_DOMINATION)
 +              HUD_Mod_Dom(pos, mySize);
        else if(gametype == GAME_KEEPAWAY)
                HUD_Mod_Keepaway(pos, mySize);
  }
  //
  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;
                }
        }
  }
@@@ -4029,13 -4778,10 +4029,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
 -==================
 -*/
 -
 -void HUD_ShowSpeed(void)
 +// Physics panel (#15)
 +//
 +vector acc_prevspeed;
 +float acc_prevtime, acc_avg, top_speed, top_speed_time;
 +void HUD_Physics(void)
  {
 -      vector numsize;
 -      float pos, conversion_factor;
 -      string speed, zspeed, unit;
 +      if(!autocvar__hud_configure)
 +      {
 +              if(!autocvar_hud_panel_physics) return;
 +              if(spectatee_status == -1 && autocvar_hud_panel_physics < 2) 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)
 +      switch(autocvar_hud_panel_physics_speed_unit)
        {
                default:
 -              case 0:
 -                      unit = "";
 -                      conversion_factor = 1.0;
 -                      break;
                case 1:
                        unit = _(" qu/s");
                        conversion_factor = 1.0;
                        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_vertical)
 +              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
 +      {
 +              // 1 m/s = 0.0254 qu/s; 1 g = 9.80665 m/s^2
 +              f = time - acc_prevtime;
 +              if(autocvar_hud_panel_physics_acceleration_vertical)
 +                      acceleration = (vlen(pmove_vel) - vlen(acc_prevspeed)) * (1 / f) * (0.0254 / 9.80665);
 +              else
 +                      acceleration = (vlen(pmove_vel - '0 0 1' * pmove_vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z)) * (1 / f) * (0.0254 / 9.80665);
 +              acc_prevspeed = pmove_vel;
 +              acc_prevtime = time;
  
 -      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;
 +      }
  
 -      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
 +      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_baralign == 4)
 +              acceleration_baralign = speed_baralign = 2;
 +      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);
 +      }
 +      if (autocvar_hud_panel_physics_acceleration_progressbar_mode == 0)
 +              acceleration_baralign = 3; //override hud_panel_physics_baralign value for acceleration
  
 -vector acc_prevspeed;
 -float acc_prevtime;
 -float acc_avg;
 +      //draw speed
 +      if(speed)
 +      if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
 +      {
 +              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 tmp_offset, tmp_size;
 +      if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
 +      {
 +              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);
 -      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;
 +              //draw speed unit
 +              if (speed_baralign)
 +                      tmp_offset_x = 0;
 +              else
 +                      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_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 2)
 +      {
 +              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)
 +                      {
 +                              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 );
 +                      }
 +            else //hide top speed 0, it would be stupid
 +                              f = 0;
 +              }
 +              if (f > 0)
 +              {
 +                      //top speed progressbar peak
 +                      if(speed < top_speed)
 +                      if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 2)
 +                      {
 +                              float peak_offset_x;
 +                              vector peak_size;
 +                              if (speed_baralign == 0)
 +                                      peak_offset_x = min(top_speed, max_speed)/max_speed * panel_size_x;
 +                else if (speed_baralign == 1)
 +                                      peak_offset_x = (1 - min(top_speed, max_speed)/max_speed) * panel_size_x;
 +                else if (speed_baralign == 2)
 +                    peak_offset_x = min(top_speed, max_speed)/max_speed * panel_size_x * 0.5;
 +                              //if speed is not 0 the speed progressbar already fetched the color
 +                              if (speed == 0)
 +                                      HUD_Panel_GetProgressBarColor(speed);
 +                              peak_size_x = floor(panel_size_x * 0.01 + 1.5);
 +                peak_size_y = panel_size_y;
 +                if (speed_baralign == 2) // draw two peaks, on both sides
 +                {
 +                    drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size_x + peak_offset_x - peak_size_x), peak_size, progressbar_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                    drawfill(panel_pos + speed_offset + eX * (0.5 * panel_size_x - peak_offset_x + peak_size_x), peak_size, progressbar_color, f * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +                }
 +                else
 +                    drawfill(panel_pos + speed_offset + eX * (peak_offset_x - peak_size_x), peak_size, 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, "accelbar", 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, "accelbar", 0, 1, -acceleration * scale, rgb, alpha * autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +      //draw acceleration
 +      if(acceleration)
 +      if(autocvar_hud_panel_physics_progressbar == 1 || autocvar_hud_panel_physics_progressbar == 3)
 +      {
 +              if (acceleration < 0)
 +                      HUD_Panel_GetProgressBarColor(acceleration_neg);
 +              else
 +                      HUD_Panel_GetProgressBarColor(acceleration);
 +              HUD_Panel_DrawProgressBar(panel_pos + acceleration_offset, panel_size, "accelbar", acceleration/autocvar_hud_panel_physics_acceleration_max, 0, acceleration_baralign, progressbar_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 +      }
 +      if (autocvar_hud_panel_physics_text == 1 || autocvar_hud_panel_physics_text == 3)
 +              drawstring_aspect(panel_pos + acceleration_offset, strcat(ftos_decimals(acceleration, 2), "g"), panel_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
  }
  
 +/*
 +==================
 +Main HUD system
 +==================
 +*/
 +
  void HUD_Reset (void)
  {
        // reset gametype specific icons
@@@ -4543,8 -5154,6 +4543,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);
        }
  
      current_player = (spectatee_status > 0) ? spectatee_status : player_localentnum;
  
        // 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 6df74d3ff72a7ce5b17bebd4d83fe30b9ce38869,9e0069a7f0155a51fb1428f90a86e5c8498aa7a3..8e024ead5b0c7fdeb36865a802c9378bf55ba7bf
@@@ -365,7 -365,7 +365,7 @@@ void Cmd_HUD_SetFields(float argc
  
                strunzone(hud_title[hud_num_fields]);
                hud_title[hud_num_fields] = strzone(TranslateScoresLabel(str));
-               hud_size[hud_num_fields] = stringwidth(str, FALSE, hud_fontsize);
+               hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], FALSE, hud_fontsize);
                str = strtolower(str);
  
                if(str == "ping") {
@@@ -923,7 -923,9 +923,7 @@@ float HUD_WouldDrawScoreboard() 
                return 1;
        else if (intermission == 2)
                return 0;
 -      else if (getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != GAME_CTS)
 -              return 1;
 -      else if (spectatee_status == -1)
 +      else if (spectatee_status != -1 && getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != GAME_CTS)
                return 1;
        else if (scoreboard_showscores_force)
                return 1;
@@@ -1250,12 -1252,12 +1250,12 @@@ void HUD_DrawScoreboard(
        if(gametype == GAME_LMS)
        {
                if(tl > 0)
-                       str = strcat(str, sprintf(_(" for up to ^1%.1f minutes^7"), tl));
+                       str = strcat(str, sprintf(_(" for up to ^1%1.0f minutes^7"), tl));
        }
        else
        {
                if(tl > 0)
-                       str = strcat(str, sprintf(_(" for up to ^1%.1f minutes^7"), tl));
+                       str = strcat(str, sprintf(_(" for up to ^1%1.0f minutes^7"), tl));
                if(fl > 0)
                {
                        if(tl > 0)
index 587cc2799a604b1d380a5bf4bb3fb354f763bad0,64dcaa44e1fb25f1fdb12c3c08767d1286632aad..53eb9eed355449cf322fbea12ec43ee937e43afb
@@@ -113,7 -113,7 +113,8 @@@ const float ENT_CLIENT_HOOK = 27
  const float ENT_CLIENT_LGBEAM = 28;
  const float ENT_CLIENT_GAUNTLET = 29;
  const float ENT_CLIENT_ACCURACY = 30;
 -const float ENT_CLIENT_WARPZONE_TELEPORTED = 31;
 +const float ENT_CLIENT_SHOWNAMES = 31;
++const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
  
  const float ENT_CLIENT_TURRET = 40;
  
@@@ -355,12 -355,6 +356,12 @@@ const float STAT_PINKALIVE = 103
  const float STAT_FROZEN = 104;
  const float STAT_REVIVE_PROGRESS = 105;
  
 +const float STAT_DOM_TOTAL_PPS = 100;
 +const float STAT_DOM_PPS_RED = 101;
 +const float STAT_DOM_PPS_BLUE = 102;
 +const float STAT_DOM_PPS_PINK = 103;
 +const float STAT_DOM_PPS_YELLOW = 104;
 +
  //const float STAT_SPIDERBOT_AIM     53 // compressShotOrigin
  //const float STAT_SPIDERBOT_TARGET  54 // compressShotOrigin
  
@@@ -634,6 -628,7 +635,6 @@@ float WR_RESETPLAYER    = 10; // (SVQC
  float WR_IMPACTEFFECT = 11; // (CSQC) impact effect
  float WR_SWITCHABLE   = 12; // (CSQC) impact effect
  
 -
  float HUD_PANEL_WEAPONS               = 0;
  float HUD_PANEL_AMMO          = 1;
  float HUD_PANEL_POWERUPS      = 2;
@@@ -649,8 -644,7 +650,8 @@@ float HUD_PANEL_PRESSEDKEYS        = 11
  float HUD_PANEL_CHAT          = 12;
  float HUD_PANEL_ENGINEINFO    = 13;
  float HUD_PANEL_INFOMESSAGES  = 14;
 -float HUD_PANEL_NUM           = 15; // always last panel id + 1, please increment when adding a new panel
 +float HUD_PANEL_PHYSICS       = 15;
 +float HUD_PANEL_NUM           = 16; // always last panel id + 1, please increment when adding a new panel
  
  string HUD_PANELNAME_WEAPONS          = "weapons";
  string HUD_PANELNAME_AMMO             = "ammo";
@@@ -667,7 -661,6 +668,7 @@@ string HUD_PANELNAME_PRESSEDKEYS   = "pr
  string HUD_PANELNAME_CHAT             = "chat";
  string HUD_PANELNAME_ENGINEINFO               = "engineinfo";
  string HUD_PANELNAME_INFOMESSAGES     = "infomessages";
 +string HUD_PANELNAME_PHYSICS  = "physics";
  
  float HUD_MENU_ENABLE         = 0;
  
index c8f7e565aa91650bbf2267fbf9e86a5809890994,4a9255a47cbfb10162c57ddaf31c75f9ff3db250..121f8ac2370f00ab410508a88052fe5207914eac
@@@ -364,7 -364,7 +364,7 @@@ void postMenuDraw(
        if(autocvar_menu_watermark != "")
        {
                vector fs = '48 48 0';
-               draw_CenterText('0.5 0.1 0', autocvar_menu_watermark, globalToBoxSize('32 32 0', draw_scale), '1 1 1', 0.05, 1);
+               draw_CenterText('0.5 0.1 0', sprintf(_("^1%s TEST BUILD"), autocvar_menu_watermark), globalToBoxSize('32 32 0', draw_scale), '1 1 1', 0.05, 1);
        }
  }
  void preMenuDraw()
@@@ -464,6 -464,14 +464,6 @@@ string resolvemod(string m
                return m;
  }
  
 -string HUD_Panel_GetSettingName(float theSetting)
 -{
 -      switch(theSetting) {
 -              case HUD_MENU_ENABLE: return ""; break;
 -              default: return "";
 -      }
 -}
 -
  float updateCompression()
  {
        float fh;
index 485d2b10305e96eacd4418444c524cf66ce1af54,2a99f50323fe01ea43ae1b837d6a56956ecbf4dc..f048862ab85c4160c30f7b89e1299b83b4a95884
@@@ -54,6 -54,9 +54,9 @@@ float autocvar_bot_sound_monopoly
  #define autocvar_bot_suffix cvar_string("bot_suffix")
  float autocvar_bot_usemodelnames;
  float autocvar_bot_vs_human;
+ float autocvar_bot_debug_tracewalk;
+ float autocvar_bot_debug_goalstack;
+ float autocvar_bot_wander_enable;
  float autocvar_captureleadlimit_override;
  #define autocvar_capturelimit_override cvar("capturelimit_override")
  float autocvar_deathmatch_force_teamplay;
@@@ -93,6 -96,7 +96,7 @@@ float autocvar_g_balance_sniperrifle_pr
  float autocvar_g_balance_sniperrifle_primary_headshotaddeddamage;
  float autocvar_g_balance_sniperrifle_primary_lifetime;
  float autocvar_g_balance_sniperrifle_primary_refire;
+ float autocvar_g_balance_sniperrifle_primary_shots;
  float autocvar_g_balance_sniperrifle_primary_speed;
  float autocvar_g_balance_sniperrifle_primary_spread;
  float autocvar_g_balance_sniperrifle_primary_tracer;
@@@ -108,6 -112,7 +112,7 @@@ float autocvar_g_balance_sniperrifle_se
  float autocvar_g_balance_sniperrifle_secondary_lifetime;
  float autocvar_g_balance_sniperrifle_secondary_reload;
  float autocvar_g_balance_sniperrifle_secondary_refire;
+ float autocvar_g_balance_sniperrifle_secondary_shots;
  float autocvar_g_balance_sniperrifle_secondary_speed;
  float autocvar_g_balance_sniperrifle_secondary_spread;
  float autocvar_g_balance_sniperrifle_secondary_tracer;
@@@ -1232,4 -1237,3 +1237,4 @@@ float autocvar_waypoint_benchmark
  float autocvar_welcome_message_time;
  float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
  float autocvar_g_trueaim_minrange;
 +float autocvar_sv_shownames_cull_distance;
index 483f3bfbd59b6b071ce940a1e8c2813b28dc0f3f,b3d326264e0a2a702843ae0b874714d6eb11f0cf..d73772b72bf012339133614e9df4b55035081f07
@@@ -328,13 -328,28 +328,28 @@@ entity SelectSpawnPoint (float anypoint
        if(anypoint)
                teamcheck = -1;
        else if(have_team_spawns > 0)
-               teamcheck = self.team; // MUST be team
-       else if(have_team_spawns == 0 && have_noteam_spawns)
+       {
+               if(have_team_spawns_forteam[self.team] == 0)
+               {
+                       // we request a spawn for a team, and we have team
+                       // spawns, but that team has no spawns?
+                       if(have_team_spawns[0])
+                               // try noteam spawns
+                               teamcheck = 0;
+                       else
+                               // if not, any spawn has to do
+                               teamcheck = -1;
+               }
+               else
+                       teamcheck = self.team; // MUST be team
+       }
+       else if(have_team_spawns == 0 && have_team_spawns[0])
                teamcheck = 0; // MUST be noteam
        else
                teamcheck = -1;
                // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then
  
        // get the list of players
        playerlist = findchain(classname, "player");
        // get the entire list of spots
@@@ -1508,7 -1523,6 +1523,7 @@@ Called when a client connects to the se
  string ColoredTeamName(float t);
  void DecodeLevelParms (void);
  //void dom_player_join_team(entity pl);
 +void set_dom_state(entity e);
  void ClientConnect (void)
  {
        float t;
        DecodeLevelParms();
  
  #ifdef WATERMARK
-       sprint(self, strcat("^4SVQC Build information: ", WATERMARK(), "\n"));
+       sprint(self, strcat("^4SVQC Build information: ^1", WATERMARK(), "\n"));
  #endif
  
        self.classname = "player_joining";
        else if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca
                send_CSQC_teamnagger();
  
 +      if (g_domination)
 +              set_dom_state(self);
 +
        CheatInitClient();
  
        PlayerStats_AddPlayer(self);
 +
 +    self.shownames = spawn();
 +    self.shownames.owner = self;
 +    self.shownames.think = shownames_think;
 +    self.shownames.nextthink = time;
 +      self.shownames.customizeentityforclient = shownames_customize;
 +    Net_LinkEntity(self.shownames, FALSE, 0, SendEntity_ShowNames);
  }
  
  /*
@@@ -1862,8 -1866,6 +1877,8 @@@ void ClientDisconnect (void
        self.playerid = 0;
        ReadyCount();
  
 +    remove(self.shownames);
 +
        // free cvars
        GetCvars(-1);
  }
@@@ -2627,6 -2629,8 +2642,8 @@@ void() nexball_setstatus
  .float items_added;
  void PlayerPreThink (void)
  {
+       WarpZone_PlayerPhysics_FixVAngle();
        self.stat_game_starttime = game_starttime;
        self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
        self.stat_leadlimit = autocvar_leadlimit;
                        return;                                 // the think tics
                }
  
-               if(self.teleport_time)
-               if(time > self.teleport_time)
-               {
-                       self.teleport_time = 0;
-                       self.effects = self.effects - (self.effects & EF_NODRAW);
-               }
 -              if(frametime > 0) // don't do this in cl_movement frames, just in server ticks
 -                      UpdateSelectedPlayer();
--
                //don't allow the player to turn around while game is paused!
                if(timeoutStatus == 2) {
                        self.v_angle = self.lastV_angle;
diff --combined qcsrc/server/defs.qh
index 6cca99ab201c9b55b730ed17d2726b31e93e02b8,cf13fee2c67cc944407e4921e3ee79af2f225cc8..3482a0628c9a54c59840954c7180ae4f880d802d
@@@ -310,6 -310,7 +310,6 @@@ float default_weapon_alpha
  .float cvar_cl_handicap;
  .float cvar_cl_playerdetailreduction;
  .float cvar_scr_centertime;
 -.float cvar_cl_shownames;
  .string cvar_g_xonoticversion;
  .string cvar_cl_weaponpriority;
  .string cvar_cl_weaponpriorities[10];
@@@ -361,6 -362,15 +361,6 @@@ float W_AmmoItemCode(float wpn)
  float W_WeaponBit(float wpn);
  string W_Name(float weaponid);
  
 -void UpdateSelectedPlayer();
 -void ClearSelectedPlayer();
 -.entity selected_player;
 -.entity last_selected_player;
 -.float selected_player_time; // when this player has been selected
 -.float selected_player_count; // how long this player has been directly pointed to
 -.float selected_player_display_needs_update; // are regular updates necessary? (health)
 -.float selected_player_display_timeout; // when the selection will time out
 -
  void FixIntermissionClient(entity e);
  void FixClientCvars(entity e);
  
@@@ -400,7 -410,7 +400,7 @@@ float TemporaryDB
  
  float some_spawn_has_been_used;
  float have_team_spawns; // 0 = no team spawns requested, -1 = team spawns requested but none found, 1 = team spawns requested and found
- float have_noteam_spawns; // 0 = no no-team spawns, 1 = no-team spawns exist
+ float have_team_spawns_forteam[17]; // 0 = this team has no spawns, 1 = this team has spawns; team 0 is the "no-team"
  
  // set when showing a kill countdown
  .entity killindicator;
@@@ -659,6 -669,3 +659,6 @@@ float serverflags
  
  .entity muzzle_flash;
  .float misc_bulletcounter;    // replaces uzi & hlac bullet counter.
 +
 +.entity shownames;
 +void shownames_think();
index d4be16ee17a1d4eb51b7c5267910ce8688484e90,de18bfdd5c0a2e97b8ec5b1ea9c88e97ae4eca76..281a0b4a4548df2f5583c43266be37cd6c619e36
@@@ -21,29 -21,6 +21,29 @@@ Note: The only teams who can use dom co
  .entity sprite;
  .float captime;
  
 +// pps: points per second
 +.float dom_total_pps;
 +.float dom_pps_red;
 +.float dom_pps_blue;
 +.float dom_pps_yellow;
 +.float dom_pps_pink;
 +float total_pps;
 +float pps_red;
 +float pps_blue;
 +float pps_yellow;
 +float pps_pink;
 +void set_dom_state(entity e)
 +{
 +      // BIG ugly hack to make stat sending work
 +      e.dom_total_pps = total_pps;
 +      e.dom_pps_red = pps_red;
 +      e.dom_pps_blue = pps_blue;
 +      if(c3 >= 0)
 +              e.dom_pps_yellow = pps_yellow;
 +      if(c4 >= 0)
 +              e.dom_pps_pink = pps_pink;
 +}
 +
  void() dom_controlpoint_setup;
  
  void LogDom(string mode, float team_before, entity actor)
@@@ -130,57 -107,25 +130,57 @@@ void dompoint_captured (
        self.delay = old_delay;
        self.team = old_team;
  
 +      switch(self.team)
 +      {
 +              // "fix" pps when slightly under 0 because of approximation errors
 +              case COLOR_TEAM1:
 +                      pps_red -= (points/wait_time);
 +                      if (pps_red < 0) pps_red = 0;
 +                      break;
 +              case COLOR_TEAM2:
 +                      pps_blue -= (points/wait_time);
 +                      if (pps_blue < 0) pps_blue = 0;
 +                      break;
 +              case COLOR_TEAM3:
 +                      pps_yellow -= (points/wait_time);
 +                      if (pps_yellow < 0) pps_yellow = 0;
 +                      break;
 +              case COLOR_TEAM4:
 +                      pps_pink -= (points/wait_time);
 +                      if (pps_pink < 0) pps_pink = 0;
 +      }
 +
        switch(self.goalentity.team)
        {
 +              // "fix" pps when slightly over total_pps because of approximation errors
                case COLOR_TEAM1:
 +                      pps_red += (points/wait_time);
 +                      if (pps_red > total_pps) pps_red = total_pps;
                        WaypointSprite_UpdateSprites(self.sprite, "dom-red", "", "");
                        break;
                case COLOR_TEAM2:
 +                      pps_blue += (points/wait_time);
 +                      if (pps_blue > total_pps) pps_blue = total_pps;
                        WaypointSprite_UpdateSprites(self.sprite, "dom-blue", "", "");
                        break;
                case COLOR_TEAM3:
 +                      pps_yellow += (points/wait_time);
 +                      if (pps_yellow > total_pps) pps_yellow = total_pps;
                        WaypointSprite_UpdateSprites(self.sprite, "dom-yellow", "", "");
                        break;
                case COLOR_TEAM4:
 +                      pps_pink += (points/wait_time);
 +                      if (pps_pink > total_pps) pps_pink = total_pps;
                        WaypointSprite_UpdateSprites(self.sprite, "dom-pink", "", "");
 -                      break;
        }
 +
        WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, colormapPaletteColor(self.goalentity.team - 1, 0));
        WaypointSprite_Ping(self.sprite);
  
        self.captime = time;
 +
 +      FOR_EACH_PLAYER(head)
 +              set_dom_state(head);
  };
  
  void AnimateDomPoint()
@@@ -360,23 -305,11 +360,23 @@@ void dom_controlpoint_setup(
        if(!self.message)
                self.message = " has captured a control point";
  
 -      if(!self.DOMPOINTFRAGS)
 +      if(self.DOMPOINTFRAGS <= 0)
                self.DOMPOINTFRAGS = 1;
 -      if(!self.wait)
 +      if(self.wait <= 0)
                self.wait = 5;
  
 +      float points, waittime;
 +      if (autocvar_g_domination_point_rate)
 +              points = autocvar_g_domination_point_rate;
 +      else
 +              points = self.frags;
 +      if (autocvar_g_domination_point_amt)
 +              waittime = autocvar_g_domination_point_amt;
 +      else
 +              waittime = self.wait;
 +
 +      total_pps += points/waittime;
 +
        if(!self.t_width)
                self.t_width = 0.02; // frame animation rate
        if(!self.t_length)
@@@ -681,22 -614,15 +681,15 @@@ void dom_delayedinit(
        // if no control points are found, spawn defaults
        if (find(world, classname, "dom_controlpoint") == world)
        {
-               // here follow default domination points for each map
-               /*
-               if (world.model == "maps/e1m1.bsp")
-               {
-                       dom_spawnpoint('0 0 0');
-               }
-               else
-               */
+               // TODO in a few months (maybe 2011/08): change this into error() and remove this very poor dom point selection
+               backtrace("This map contains no dom_controlpoint entities. A very poor dom point placement will be chosen. Please fix the map.");
+               // if no supported map was found, make every deathmatch spawn a point
+               head = find(world, classname, "info_player_deathmatch");
+               while (head)
                {
-                       // if no supported map was found, make every deathmatch spawn a point
-                       head = find(world, classname, "info_player_deathmatch");
-                       while (head)
-                       {
-                               dom_spawnpoint(head.origin);
-                               head = find(head, classname, "info_player_deathmatch");
-                       }
+                       dom_spawnpoint(head.origin);
+                       head = find(head, classname, "info_player_deathmatch");
                }
        }
  
@@@ -715,11 -641,5 +708,11 @@@ void dom_init(
        precache_model("models/domination/dom_unclaimed.md3");
        precache_sound("domination/claim.wav");
        InitializeEntity(world, dom_delayedinit, INITPRIO_GAMETYPE);
 +
 +      addstat(STAT_DOM_TOTAL_PPS, AS_FLOAT, dom_total_pps);
 +      addstat(STAT_DOM_PPS_RED, AS_FLOAT, dom_pps_red);
 +      addstat(STAT_DOM_PPS_BLUE, AS_FLOAT, dom_pps_blue);
 +      if(c3 >= 0) addstat(STAT_DOM_PPS_YELLOW, AS_FLOAT, dom_pps_yellow);
 +      if(c4 >= 0) addstat(STAT_DOM_PPS_PINK, AS_FLOAT, dom_pps_pink);
  };
  
index 251bc5f3b682e5a2f0a50f7ec76b06fdbc030eb3,0c8162b54464275c9df9537dd1aad11d4f9af682..9ee54dd343fdf95ab04d41784be0f7c5400918cf
@@@ -236,8 -236,7 +236,7 @@@ void relocate_spawnpoint(
      if (have_team_spawns != 0)
          if (self.team)
              have_team_spawns = 1;
-     if (!self.team)
-         have_noteam_spawns = 1;
+     have_team_spawns_forteam[self.team] = 1;
  
      if (autocvar_r_showbboxes)
      {
@@@ -461,6 -460,11 +460,6 @@@ string formatmessage(string msg
                        replacement = cursor_ent.netname;
                        if (!replacement || !cursor_ent)
                                replacement = "nothing";
 -              } else if (escape == "p") {
 -                      if (self.last_selected_player)
 -                              replacement = self.last_selected_player.netname;
 -                      else
 -                              replacement = "(nobody)";
                } else if (escape == "s")
                        replacement = ftos(vlen(self.velocity - self.velocity_z * '0 0 1'));
                else if (escape == "S")
@@@ -581,6 -585,7 +580,6 @@@ void GetCvars(float f
        GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
        GetCvars_handleFloat(s, f, cvar_cl_playerdetailreduction, "cl_playerdetailreduction");
        GetCvars_handleFloat(s, f, cvar_scr_centertime, "scr_centertime");
 -      GetCvars_handleFloat(s, f, cvar_cl_shownames, "cl_shownames");
        GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
        GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap");
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);