]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move scoreboard files to hud/panel/
authorterencehill <piuntn@gmail.com>
Sat, 30 Jul 2016 14:56:45 +0000 (16:56 +0200)
committerterencehill <piuntn@gmail.com>
Sat, 30 Jul 2016 16:08:18 +0000 (18:08 +0200)
15 files changed:
qcsrc/client/_mod.inc
qcsrc/client/_mod.qh
qcsrc/client/hud/all.inc
qcsrc/client/hud/hud.qc
qcsrc/client/hud/panel/_mod.inc
qcsrc/client/hud/panel/_mod.qh
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/score.qc
qcsrc/client/hud/panel/scoreboard.qc [new file with mode: 0644]
qcsrc/client/hud/panel/scoreboard.qh [new file with mode: 0644]
qcsrc/client/main.qc
qcsrc/client/mapvoting.qc
qcsrc/client/scoreboard.qc [deleted file]
qcsrc/client/scoreboard.qh [deleted file]
qcsrc/client/view.qc

index 186be97400aaa76e6253d2786d525c31c234f28d..0920265d630bec596040cd55735ce790510adc76 100644 (file)
@@ -6,7 +6,6 @@
 #include <client/mapvoting.qc>
 #include <client/miscfunctions.qc>
 #include <client/player_skeleton.qc>
-#include <client/scoreboard.qc>
 #include <client/shownames.qc>
 #include <client/teamradar.qc>
 #include <client/view.qc>
index 1c66ff781e07ceb95562c9cd57ec7238311a772f..75266dfa2d0aaec18e189dcc84ee21f9e00abcee 100644 (file)
@@ -6,7 +6,6 @@
 #include <client/mapvoting.qh>
 #include <client/miscfunctions.qh>
 #include <client/player_skeleton.qh>
-#include <client/scoreboard.qh>
 #include <client/shownames.qh>
 #include <client/teamradar.qh>
 #include <client/view.qh>
index aa36eec409ba36a501407b4de4e3e0d43498ec46..8305304fe9ae8f65a32bad1cc66426d62f4d3970 100644 (file)
@@ -19,3 +19,4 @@
 // #include "panel/mapvote.qc"
 // #include "panel/itemstime.qc"
 #include "panel/quickmenu.qc"
+#include "panel/scoreboard.qc"
index 62f5dcb6d82a66a115b478c81bf6bb7235ef0f45..2c1a7e1b0d24554afa68112a4ffa2b5d83a6d6f1 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "hud_config.qh"
 #include "../mapvoting.qh"
-#include "../scoreboard.qh"
 #include "../teamradar.qh"
 #include <common/t_items.qh>
 #include <common/deathtypes/all.qh>
index 5681474b84e75ea22e1894ddfd1aced1948f03b0..d495fdee7670c8874ee45388484abd996092624c 100644 (file)
@@ -18,3 +18,4 @@
 #include <client/hud/panel/timer.qc>
 #include <client/hud/panel/vote.qc>
 #include <client/hud/panel/weapons.qc>
+#include <client/hud/panel/scoreboard.qc>
index 930a3fe02ba8ccc73879bf98039e5b3845e53a3e..fa9b755309da1b4e2b90810e32179230189bd5b9 100644 (file)
@@ -18,3 +18,4 @@
 #include <client/hud/panel/timer.qh>
 #include <client/hud/panel/vote.qh>
 #include <client/hud/panel/weapons.qh>
+#include <client/hud/panel/scoreboard.qh>
index 7dfaa909e3ae7760ec9af933852354222adf437e..cbba0faf3f08288e3eb6d39467207bafb87762d4 100644 (file)
@@ -1,6 +1,6 @@
 #include "centerprint.qh"
 
-#include <client/scoreboard.qh>
+#include "scoreboard.qh"
 
 // CenterPrint (#16)
 
index b07b84ed33f8001c34779cea4a7bddd9d4db5813..c7128b1eb4feb531530f6e4b0315cb24d38df656 100644 (file)
@@ -1,6 +1,6 @@
 #include "score.qh"
 
-#include <client/scoreboard.qh>
+#include "scoreboard.qh"
 #include <common/ent_cs.qh>
 #include <common/mapinfo.qh>
 
diff --git a/qcsrc/client/hud/panel/scoreboard.qc b/qcsrc/client/hud/panel/scoreboard.qc
new file mode 100644 (file)
index 0000000..72a058d
--- /dev/null
@@ -0,0 +1,1541 @@
+#include "scoreboard.qh"
+
+#include "quickmenu.qh"
+#include <common/ent_cs.qh>
+#include <common/constants.qh>
+#include <common/mapinfo.qh>
+#include <common/minigames/cl_minigames.qh>
+#include <common/stats.qh>
+#include <common/teams.qh>
+
+float scoreboard_alpha_bg;
+float scoreboard_alpha_fg;
+float scoreboard_highlight;
+float scoreboard_highlight_alpha;
+float scoreboard_highlight_alpha_self;
+float scoreboard_alpha_name;
+float scoreboard_alpha_name_self;
+
+void drawstringright(vector, string, vector, vector, float, float);
+void drawstringcenter(vector, string, vector, vector, float, float);
+
+const float SCOREBOARD_OFFSET = 50;
+
+// wrapper to put all possible scores titles through gettext
+string TranslateScoresLabel(string l)
+{
+       switch(l)
+       {
+               case "bckills": return CTX(_("SCO^bckills"));
+               case "bctime": return CTX(_("SCO^bctime"));
+               case "caps": return CTX(_("SCO^caps"));
+               case "captime": return CTX(_("SCO^captime"));
+               case "deaths": return CTX(_("SCO^deaths"));
+               case "destroyed": return CTX(_("SCO^destroyed"));
+               case "dmg": return CTX(_("SCO^dmg"));
+               case "dmgtaken": return CTX(_("SCO^dmgtaken"));
+               case "drops": return CTX(_("SCO^drops"));
+               case "faults": return CTX(_("SCO^faults"));
+               case "fckills": return CTX(_("SCO^fckills"));
+               case "goals": return CTX(_("SCO^goals"));
+               case "kckills": return CTX(_("SCO^kckills"));
+               case "kdratio": return CTX(_("SCO^kdratio"));
+               case "k/d": return CTX(_("SCO^k/d"));
+               case "kd": return CTX(_("SCO^kd"));
+               case "kdr": return CTX(_("SCO^kdr"));
+               case "kills": return CTX(_("SCO^kills"));
+               case "laps": return CTX(_("SCO^laps"));
+               case "lives": return CTX(_("SCO^lives"));
+               case "losses": return CTX(_("SCO^losses"));
+               case "name": return CTX(_("SCO^name"));
+               case "sum": return CTX(_("SCO^sum"));
+               case "nick": return CTX(_("SCO^nick"));
+               case "objectives": return CTX(_("SCO^objectives"));
+               case "pickups": return CTX(_("SCO^pickups"));
+               case "ping": return CTX(_("SCO^ping"));
+               case "pl": return CTX(_("SCO^pl"));
+               case "pushes": return CTX(_("SCO^pushes"));
+               case "rank": return CTX(_("SCO^rank"));
+               case "returns": return CTX(_("SCO^returns"));
+               case "revivals": return CTX(_("SCO^revivals"));
+               case "score": return CTX(_("SCO^score"));
+               case "suicides": return CTX(_("SCO^suicides"));
+               case "takes": return CTX(_("SCO^takes"));
+               case "ticks": return CTX(_("SCO^ticks"));
+               default: return l;
+       }
+}
+
+void HUD_InitScores()
+{
+       int i, f;
+
+       ps_primary = ps_secondary = ts_primary = ts_secondary = -1;
+       for(i = 0; i < MAX_SCORE; ++i)
+       {
+               f = (scores_flags[i] & SFL_SORT_PRIO_MASK);
+               if(f == SFL_SORT_PRIO_PRIMARY)
+                       ps_primary = i;
+               if(f == SFL_SORT_PRIO_SECONDARY)
+                       ps_secondary = i;
+       }
+       if(ps_secondary == -1)
+               ps_secondary = ps_primary;
+
+       for(i = 0; i < MAX_TEAMSCORE; ++i)
+       {
+               f = (teamscores_flags[i] & SFL_SORT_PRIO_MASK);
+               if(f == SFL_SORT_PRIO_PRIMARY)
+                       ts_primary = i;
+               if(f == SFL_SORT_PRIO_SECONDARY)
+                       ts_secondary = i;
+       }
+       if(ts_secondary == -1)
+               ts_secondary = ts_primary;
+
+       Cmd_HUD_SetFields(0);
+}
+
+float SetTeam(entity pl, float Team);
+//float lastpnum;
+void HUD_UpdatePlayerTeams()
+{
+       float Team;
+       entity pl, tmp;
+       float num;
+
+       num = 0;
+       for(pl = players.sort_next; pl; pl = pl.sort_next)
+       {
+               num += 1;
+               Team = entcs_GetScoreTeam(pl.sv_entnum);
+               if(SetTeam(pl, Team))
+               {
+                       tmp = pl.sort_prev;
+                       HUD_UpdatePlayerPos(pl);
+                       if(tmp)
+                               pl = tmp;
+                       else
+                               pl = players.sort_next;
+               }
+       }
+       /*
+       if(num != lastpnum)
+               print(strcat("PNUM: ", ftos(num), "\n"));
+       lastpnum = num;
+       */
+}
+
+int HUD_CompareScore(int vl, int vr, int f)
+{
+    TC(int, vl); TC(int, vr); TC(int, f);
+       if(f & SFL_ZERO_IS_WORST)
+       {
+               if(vl == 0 && vr != 0)
+                       return 1;
+               if(vl != 0 && vr == 0)
+                       return 0;
+       }
+       if(vl > vr)
+               return IS_INCREASING(f);
+       if(vl < vr)
+               return IS_DECREASING(f);
+       return -1;
+}
+
+float HUD_ComparePlayerScores(entity left, entity right)
+{
+       float vl, vr, r;
+       vl = entcs_GetTeam(left.sv_entnum);
+       vr = entcs_GetTeam(right.sv_entnum);
+
+       if(!left.gotscores)
+               vl = NUM_SPECTATOR;
+       if(!right.gotscores)
+               vr = NUM_SPECTATOR;
+
+       if(vl > vr)
+               return true;
+       if(vl < vr)
+               return false;
+
+       if(vl == NUM_SPECTATOR)
+       {
+               // FIRST the one with scores (spectators), THEN the ones without (downloaders)
+               // no other sorting
+               if(!left.gotscores && right.gotscores)
+                       return true;
+               return false;
+       }
+
+       r = HUD_CompareScore(left.scores[ps_primary], right.scores[ps_primary], scores_flags[ps_primary]);
+       if (r >= 0)
+               return r;
+
+       r = HUD_CompareScore(left.scores[ps_secondary], right.scores[ps_secondary], scores_flags[ps_secondary]);
+       if (r >= 0)
+               return r;
+
+       int i;
+       for(i = 0; i < MAX_SCORE; ++i)
+       {
+               r = HUD_CompareScore(left.scores[i], right.scores[i], scores_flags[i]);
+               if (r >= 0)
+                       return r;
+       }
+
+       if (left.sv_entnum < right.sv_entnum)
+               return true;
+
+       return false;
+}
+
+void HUD_UpdatePlayerPos(entity player)
+{
+       entity ent;
+       for(ent = player.sort_next; ent && HUD_ComparePlayerScores(player, ent); ent = player.sort_next)
+       {
+               SORT_SWAP(player, ent);
+       }
+       for(ent = player.sort_prev; ent != players && HUD_ComparePlayerScores(ent, player); ent = player.sort_prev)
+       {
+               SORT_SWAP(ent, player);
+       }
+}
+
+float HUD_CompareTeamScores(entity left, entity right)
+{
+       int i, r;
+
+       if(left.team == NUM_SPECTATOR)
+               return 1;
+       if(right.team == NUM_SPECTATOR)
+               return 0;
+
+       r = HUD_CompareScore(left.teamscores[ts_primary], right.teamscores[ts_primary], teamscores_flags[ts_primary]);
+       if (r >= 0)
+               return r;
+
+       r = HUD_CompareScore(left.teamscores[ts_secondary], right.teamscores[ts_secondary], teamscores_flags[ts_secondary]);
+       if (r >= 0)
+               return r;
+
+       for(i = 0; i < MAX_SCORE; ++i)
+       {
+               r = HUD_CompareScore(left.teamscores[i], right.teamscores[i], teamscores_flags[i]);
+               if (r >= 0)
+                       return r;
+       }
+
+       if (left.team < right.team)
+               return true;
+
+       return false;
+}
+
+void HUD_UpdateTeamPos(entity Team)
+{
+       entity ent;
+       for(ent = Team.sort_next; ent && HUD_CompareTeamScores(Team, ent); ent = Team.sort_next)
+       {
+               SORT_SWAP(Team, ent);
+       }
+       for(ent = Team.sort_prev; ent != teams && HUD_CompareTeamScores(ent, Team); ent = Team.sort_prev)
+       {
+               SORT_SWAP(ent, Team);
+       }
+}
+
+void Cmd_HUD_Help()
+{
+       LOG_INFO(_("You can modify the scoreboard using the ^2scoreboard_columns_set command.\n"));
+       LOG_INFO(_("^3|---------------------------------------------------------------|\n"));
+       LOG_INFO(_("Usage:\n"));
+       LOG_INFO(_("^2scoreboard_columns_set default\n"));
+       LOG_INFO(_("^2scoreboard_columns_set ^7field1 field2 ...\n"));
+       LOG_INFO(_("The following field names are recognized (case insensitive):\n"));
+       LOG_INFO(_("You can use a ^3|^7 to start the right-aligned fields.\n\n"));
+
+       LOG_INFO(_("^3name^7 or ^3nick^7             Name of a player\n"));
+       LOG_INFO(_("^3ping^7                     Ping time\n"));
+       LOG_INFO(_("^3pl^7                       Packet loss\n"));
+       LOG_INFO(_("^3kills^7                    Number of kills\n"));
+       LOG_INFO(_("^3deaths^7                   Number of deaths\n"));
+       LOG_INFO(_("^3suicides^7                 Number of suicides\n"));
+       LOG_INFO(_("^3frags^7                    kills - suicides\n"));
+       LOG_INFO(_("^3kd^7                       The kill-death ratio\n"));
+       LOG_INFO(_("^3dmg^7                      The total damage done\n"));
+       LOG_INFO(_("^3dmgtaken^7                 The total damage taken\n"));
+       LOG_INFO(_("^3sum^7                      frags - deaths\n"));
+       LOG_INFO(_("^3caps^7                     How often a flag (CTF) or a key (KeyHunt) was captured\n"));
+       LOG_INFO(_("^3pickups^7                  How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up\n"));
+       LOG_INFO(_("^3captime^7                  Time of fastest cap (CTF)\n"));
+       LOG_INFO(_("^3fckills^7                  Number of flag carrier kills\n"));
+       LOG_INFO(_("^3returns^7                  Number of flag returns\n"));
+       LOG_INFO(_("^3drops^7                    Number of flag drops\n"));
+       LOG_INFO(_("^3lives^7                    Number of lives (LMS)\n"));
+       LOG_INFO(_("^3rank^7                     Player rank\n"));
+       LOG_INFO(_("^3pushes^7                   Number of players pushed into void\n"));
+       LOG_INFO(_("^3destroyed^7                Number of keys destroyed by pushing them into void\n"));
+       LOG_INFO(_("^3kckills^7                  Number of keys carrier kills\n"));
+       LOG_INFO(_("^3losses^7                   Number of times a key was lost\n"));
+       LOG_INFO(_("^3laps^7                     Number of laps finished (race/cts)\n"));
+       LOG_INFO(_("^3time^7                     Total time raced (race/cts)\n"));
+       LOG_INFO(_("^3fastest^7                  Time of fastest lap (race/cts)\n"));
+       LOG_INFO(_("^3ticks^7                    Number of ticks (DOM)\n"));
+       LOG_INFO(_("^3takes^7                    Number of domination points taken (DOM)\n"));
+       LOG_INFO(_("^3bckills^7                  Number of ball carrier kills\n"));
+       LOG_INFO(_("^3bctime^7                   Total amount of time holding the ball in Keepaway\n"));
+       LOG_INFO(_("^3score^7                    Total score\n\n"));
+
+       LOG_INFO(_("Before a field you can put a + or - sign, then a comma separated list\n"
+               "of game types, then a slash, to make the field show up only in these\n"
+               "or in all but these game types. You can also specify 'all' as a\n"
+               "field to show all fields available for the current game mode.\n\n"));
+
+       LOG_INFO(_("The special game type names 'teams' and 'noteams' can be used to\n"
+               "include/exclude ALL teams/noteams game modes.\n\n"));
+
+       LOG_INFO(_("Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4\n"));
+       LOG_INFO(_("will display name, ping and pl aligned to the left, and the fields\n"
+               "right of the vertical bar aligned to the right.\n"));
+       LOG_INFO(_("'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
+               "other gamemodes except DM.\n"));
+}
+
+// NOTE: adding a gametype with ? to not warn for an optional field
+// make sure it's excluded in a previous exclusive rule, if any
+// otherwise the previous exclusive rule warns anyway
+// e.g. -teams,rc,cts,lms/kills ?+rc/kills
+#define SCOREBOARD_DEFAULT_COLUMNS \
+"ping pl name |" \
+" -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
+" -teams,lms/deaths +ft,tdm/deaths" \
+" -teams,lms,rc,cts,inv,ka/suicides +ft,tdm/suicides ?+rc,inv/suicides" \
+" -cts,dm,tdm,ka,ft/frags" /* tdm already has this in "score" */ \
+" -rc,cts,nb/dmg -rc,cts,nb/dmgtaken" \
+" +ctf/caps +ctf/pickups +ctf/fckills +ctf/returns +ons/caps +ons/takes" \
+" +lms/lives +lms/rank" \
+" +kh/caps +kh/pushes +kh/destroyed" \
+" ?+rc/laps ?+rc/time +rc,cts/fastest" \
+" +as/objectives +nb/faults +nb/goals" \
+" +ka/pickups +ka/bckills +ka/bctime +ft/revivals" \
+" -lms,rc,cts,inv,nb/score"
+
+void Cmd_HUD_SetFields(int argc)
+{
+    TC(int, argc);
+       int i, j, slash;
+       string str, pattern;
+       float have_name = 0, have_primary = 0, have_secondary = 0, have_separator = 0;
+       float missing;
+
+       if(!gametype)
+       {
+               // set up a temporary scoreboard layout
+               // no layout can be properly set up until score_info data haven't been received
+               argc = tokenizebyseparator("0 1 ping pl name | score", " ");
+               ps_primary = 0;
+               scores_label[ps_primary] = strzone("score");
+               scores_flags[ps_primary] = SFL_ALLOW_HIDE;
+       }
+
+       // TODO: re enable with gametype dependant cvars?
+       if(argc < 3) // no arguments provided
+               argc = tokenizebyseparator(strcat("0 1 ", autocvar_scoreboard_columns), " ");
+
+       if(argc < 3)
+               argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " ");
+
+       if(argc == 3)
+       {
+               if(argv(2) == "default")
+                       argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " ");
+               else if(argv(2) == "all")
+               {
+                       string s;
+                       s = "ping pl name |";
+                       for(i = 0; i < MAX_SCORE; ++i)
+                       {
+                               if(i != ps_primary)
+                               if(i != ps_secondary)
+                               if(scores_label[i] != "")
+                                       s = strcat(s, " ", scores_label[i]);
+                       }
+                       if(ps_secondary != ps_primary)
+                               s = strcat(s, " ", scores_label[ps_secondary]);
+                       s = strcat(s, " ", scores_label[ps_primary]);
+                       argc = tokenizebyseparator(strcat("0 1 ", s), " ");
+               }
+       }
+
+
+       hud_num_fields = 0;
+
+       hud_fontsize = HUD_GetFontsize("hud_fontsize");
+
+       for(i = 1; i < argc - 1; ++i)
+       {
+               float nocomplain;
+               str = argv(i+1);
+
+               nocomplain = false;
+               if(substring(str, 0, 1) == "?")
+               {
+                       nocomplain = true;
+                       str = substring(str, 1, strlen(str) - 1);
+               }
+
+               slash = strstrofs(str, "/", 0);
+               if(slash >= 0)
+               {
+                       pattern = substring(str, 0, slash);
+                       str = substring(str, slash + 1, strlen(str) - (slash + 1));
+
+                       if (!isGametypeInFilter(gametype, teamplay, false, pattern))
+                               continue;
+               }
+
+               strunzone(hud_title[hud_num_fields]);
+               hud_title[hud_num_fields] = strzone(TranslateScoresLabel(str));
+               hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], false, hud_fontsize);
+               str = strtolower(str);
+
+               switch(str)
+               {
+                       case "ping": hud_field[hud_num_fields] = SP_PING; break;
+                       case "pl": hud_field[hud_num_fields] = SP_PL; break;
+                       case "kd": case "kdr": case "kdratio": case "k/d": hud_field[hud_num_fields] = SP_KDRATIO; break;
+                       case "sum": case "diff": case "k-d": hud_field[hud_num_fields] = SP_SUM; break;
+                       case "name": case "nick": hud_field[hud_num_fields] = SP_NAME; have_name = true; break;
+                       case "|": hud_field[hud_num_fields] = SP_SEPARATOR; have_separator = true; break;
+                       case "dmg": hud_field[hud_num_fields] = SP_DMG; break;
+                       case "dmgtaken": hud_field[hud_num_fields] = SP_DMGTAKEN; break;
+                       default:
+                       {
+                               for(j = 0; j < MAX_SCORE; ++j)
+                                       if(str == strtolower(scores_label[j]))
+                                               goto found; // sorry, but otherwise fteqcc -O3 miscompiles this and warns about "unreachable code"
+
+LABEL(notfound)
+                               if(str == "frags")
+                                       j = SP_FRAGS;
+                               else
+                               {
+                                       if(!nocomplain)
+                                               LOG_INFOF("^1Error:^7 Unknown score field: '%s'\n", str);
+                                       continue;
+                               }
+LABEL(found)
+                               hud_field[hud_num_fields] = j;
+                               if(j == ps_primary)
+                                       have_primary = 1;
+                               if(j == ps_secondary)
+                                       have_secondary = 1;
+
+                       }
+               }
+               ++hud_num_fields;
+               if(hud_num_fields >= MAX_HUD_FIELDS)
+                       break;
+       }
+
+       if(scores_flags[ps_primary] & SFL_ALLOW_HIDE)
+               have_primary = 1;
+       if(scores_flags[ps_secondary] & SFL_ALLOW_HIDE)
+               have_secondary = 1;
+       if(ps_primary == ps_secondary)
+               have_secondary = 1;
+       missing = (!have_primary) + (!have_secondary) + (!have_separator) + (!have_name);
+
+       if(hud_num_fields+missing < MAX_HUD_FIELDS)
+       {
+               if(!have_name)
+               {
+                       strunzone(hud_title[hud_num_fields]);
+                       for(i = hud_num_fields; i > 0; --i)
+                       {
+                               hud_title[i] = hud_title[i-1];
+                               hud_size[i] = hud_size[i-1];
+                               hud_field[i] = hud_field[i-1];
+                       }
+                       hud_title[0] = strzone(TranslateScoresLabel("name"));
+                       hud_field[0] = SP_NAME;
+                       ++hud_num_fields;
+                       LOG_INFO("fixed missing field 'name'\n");
+
+                       if(!have_separator)
+                       {
+                               strunzone(hud_title[hud_num_fields]);
+                               for(i = hud_num_fields; i > 1; --i)
+                               {
+                                       hud_title[i] = hud_title[i-1];
+                                       hud_size[i] = hud_size[i-1];
+                                       hud_field[i] = hud_field[i-1];
+                               }
+                               hud_title[1] = strzone("|");
+                               hud_field[1] = SP_SEPARATOR;
+                               hud_size[1] = stringwidth("|", false, hud_fontsize);
+                               ++hud_num_fields;
+                               LOG_INFO("fixed missing field '|'\n");
+                       }
+               }
+               else if(!have_separator)
+               {
+                       strunzone(hud_title[hud_num_fields]);
+                       hud_title[hud_num_fields] = strzone("|");
+                       hud_size[hud_num_fields] = stringwidth("|", false, hud_fontsize);
+                       hud_field[hud_num_fields] = SP_SEPARATOR;
+                       ++hud_num_fields;
+                       LOG_INFO("fixed missing field '|'\n");
+               }
+               if(!have_secondary)
+               {
+                       strunzone(hud_title[hud_num_fields]);
+                       hud_title[hud_num_fields] = strzone(TranslateScoresLabel(scores_label[ps_secondary]));
+                       hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], false, hud_fontsize);
+                       hud_field[hud_num_fields] = ps_secondary;
+                       ++hud_num_fields;
+                       LOG_INFOF("fixed missing field '%s'\n", scores_label[ps_secondary]);
+               }
+               if(!have_primary)
+               {
+                       strunzone(hud_title[hud_num_fields]);
+                       hud_title[hud_num_fields] = strzone(TranslateScoresLabel(scores_label[ps_primary]));
+                       hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], false, hud_fontsize);
+                       hud_field[hud_num_fields] = ps_primary;
+                       ++hud_num_fields;
+                       LOG_INFOF("fixed missing field '%s'\n", scores_label[ps_primary]);
+               }
+       }
+
+       hud_field[hud_num_fields] = SP_END;
+}
+
+// MOVEUP::
+vector hud_field_rgb;
+string hud_field_icon0;
+string hud_field_icon1;
+string hud_field_icon2;
+vector hud_field_icon0_rgb;
+vector hud_field_icon1_rgb;
+vector hud_field_icon2_rgb;
+float hud_field_icon0_alpha;
+float hud_field_icon1_alpha;
+float hud_field_icon2_alpha;
+string HUD_GetField(entity pl, int field)
+{
+    TC(int, field);
+       float tmp, num, denom;
+       int f;
+       string str;
+       hud_field_rgb = '1 1 1';
+       hud_field_icon0 = "";
+       hud_field_icon1 = "";
+       hud_field_icon2 = "";
+       hud_field_icon0_rgb = '1 1 1';
+       hud_field_icon1_rgb = '1 1 1';
+       hud_field_icon2_rgb = '1 1 1';
+       hud_field_icon0_alpha = 1;
+       hud_field_icon1_alpha = 1;
+       hud_field_icon2_alpha = 1;
+       switch(field)
+       {
+               case SP_PING:
+                       if (!pl.gotscores)
+                               return "\xE2\x96\xB6\xE2\x96\xB6\xE2\x96\xB6"; // >>> sign using U+25B6
+                       //str = getplayerkeyvalue(pl.sv_entnum, "ping");
+                       f = pl.ping;
+                       if(f == 0)
+                               return _("N/A");
+                       tmp = max(0, min(220, f-80)) / 220;
+                       hud_field_rgb = '1 1 1' - '0 1 1'*tmp;
+                       return ftos(f);
+
+               case SP_PL:
+                       if (!pl.gotscores)
+                               return _("N/A");
+                       f = pl.ping_packetloss;
+                       tmp = pl.ping_movementloss;
+                       if(f == 0 && tmp == 0)
+                               return "";
+                       str = ftos(ceil(f * 100));
+                       if(tmp != 0)
+                               str = strcat(str, "~", ftos(ceil(tmp * 100)));
+                       tmp = bound(0, f / 0.2 + tmp / 0.04, 1); // 20% is REALLY BAD pl
+                       hud_field_rgb = '1 0.5 0.5' - '0 0.5 0.5'*tmp;
+                       return str;
+
+               case SP_NAME:
+                       if(ready_waiting && pl.ready)
+                       {
+                               hud_field_icon0 = "gfx/scoreboard/player_ready";
+                       }
+                       else if(!teamplay)
+                       {
+                               f = stof(getplayerkeyvalue(pl.sv_entnum, "colors"));
+                               {
+                                       hud_field_icon0 = "gfx/scoreboard/playercolor_base";
+                                       hud_field_icon1 = "gfx/scoreboard/playercolor_shirt";
+                                       hud_field_icon1_rgb = colormapPaletteColor(floor(f / 16), 0);
+                                       hud_field_icon2 = "gfx/scoreboard/playercolor_pants";
+                                       hud_field_icon2_rgb = colormapPaletteColor(f % 16, 1);
+                               }
+                       }
+                       return entcs_GetName(pl.sv_entnum);
+
+               case SP_FRAGS:
+                       f = pl.(scores[SP_KILLS]);
+                       f -= pl.(scores[SP_SUICIDES]);
+                       return ftos(f);
+
+               case SP_KDRATIO:
+                       num = pl.(scores[SP_KILLS]);
+                       denom = pl.(scores[SP_DEATHS]);
+
+                       if(denom == 0) {
+                               hud_field_rgb = '0 1 0';
+                               str = sprintf("%d", num);
+                       } else if(num <= 0) {
+                               hud_field_rgb = '1 0 0';
+                               str = sprintf("%.1f", num/denom);
+                       } else
+                               str = sprintf("%.1f", num/denom);
+                       return str;
+
+               case SP_SUM:
+                       f = pl.(scores[SP_KILLS]);
+                       f -= pl.(scores[SP_DEATHS]);
+
+                       if(f > 0) {
+                               hud_field_rgb = '0 1 0';
+                       } else if(f == 0) {
+                               hud_field_rgb = '1 1 1';
+                       } else {
+                               hud_field_rgb = '1 0 0';
+                       }
+                       return ftos(f);
+
+               case SP_DMG:
+                       num = pl.(scores[SP_DMG]);
+                       denom = 1000;
+
+                       str = sprintf("%.1f k", num/denom);
+                       return str;
+
+               case SP_DMGTAKEN:
+                       num = pl.(scores[SP_DMGTAKEN]);
+                       denom = 1000;
+
+                       str = sprintf("%.1f k", num/denom);
+                       return str;
+
+               default:
+                       tmp = pl.(scores[field]);
+                       f = scores_flags[field];
+                       if(field == ps_primary)
+                               hud_field_rgb = '1 1 0';
+                       else if(field == ps_secondary)
+                               hud_field_rgb = '0 1 1';
+                       else
+                               hud_field_rgb = '1 1 1';
+                       return ScoreString(f, tmp);
+       }
+       //return "error";
+}
+
+float hud_fixscoreboardcolumnwidth_len;
+float hud_fixscoreboardcolumnwidth_iconlen;
+float hud_fixscoreboardcolumnwidth_marginlen;
+
+string HUD_FixScoreboardColumnWidth(int i, string str)
+{
+    TC(int, i);
+       float field, f;
+       vector sz;
+       field = hud_field[i];
+
+       hud_fixscoreboardcolumnwidth_iconlen = 0;
+
+       if(hud_field_icon0 != "")
+       {
+               sz = draw_getimagesize(hud_field_icon0);
+               f = sz.x / sz.y;
+               if(hud_fixscoreboardcolumnwidth_iconlen < f)
+                       hud_fixscoreboardcolumnwidth_iconlen = f;
+       }
+
+       if(hud_field_icon1 != "")
+       {
+               sz = draw_getimagesize(hud_field_icon1);
+               f = sz.x / sz.y;
+               if(hud_fixscoreboardcolumnwidth_iconlen < f)
+                       hud_fixscoreboardcolumnwidth_iconlen = f;
+       }
+
+       if(hud_field_icon2 != "")
+       {
+               sz = draw_getimagesize(hud_field_icon2);
+               f = sz.x / sz.y;
+               if(hud_fixscoreboardcolumnwidth_iconlen < f)
+                       hud_fixscoreboardcolumnwidth_iconlen = f;
+       }
+
+       hud_fixscoreboardcolumnwidth_iconlen *= hud_fontsize.y / hud_fontsize.x; // fix icon aspect
+
+       if(hud_fixscoreboardcolumnwidth_iconlen != 0)
+               hud_fixscoreboardcolumnwidth_marginlen = stringwidth(" ", false, hud_fontsize);
+       else
+               hud_fixscoreboardcolumnwidth_marginlen = 0;
+
+       if(field == SP_NAME) // name gets all remaining space
+       {
+               int j;
+               float namesize;
+               namesize = sbwidth;// / hud_fontsize_x;
+               for(j = 0; j < hud_num_fields; ++j)
+                       if(j != i)
+                               if (hud_field[i] != SP_SEPARATOR)
+                                       namesize -= hud_size[j] + hud_fontsize.x;
+               namesize += hud_fontsize.x;
+               hud_size[i] = namesize;
+
+               if (hud_fixscoreboardcolumnwidth_iconlen != 0)
+                       namesize -= hud_fixscoreboardcolumnwidth_marginlen + hud_fixscoreboardcolumnwidth_iconlen;
+               str = textShortenToWidth(str, namesize, hud_fontsize, stringwidth_colors);
+               hud_fixscoreboardcolumnwidth_len = stringwidth(str, true, hud_fontsize);
+       }
+       else
+               hud_fixscoreboardcolumnwidth_len = stringwidth(str, false, hud_fontsize);
+
+       f = hud_fixscoreboardcolumnwidth_len + hud_fixscoreboardcolumnwidth_marginlen + hud_fixscoreboardcolumnwidth_iconlen;
+       if(hud_size[i] < f)
+               hud_size[i] = f;
+
+       return str;
+}
+
+void HUD_PrintScoreboardItem(vector pos, vector item_size, entity pl, bool is_self, int pl_number)
+{
+    TC(bool, is_self); TC(int, pl_number);
+       vector tmp, rgb;
+       rgb = Team_ColorRGB(pl.team);
+       string str;
+       int field;
+       float is_spec;
+       is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
+
+       if((rgb == '1 1 1') && (!is_spec)) {
+               rgb.x = autocvar_scoreboard_color_bg_r + 0.5;
+               rgb.y = autocvar_scoreboard_color_bg_g + 0.5;
+               rgb.z = autocvar_scoreboard_color_bg_b + 0.5; }
+
+       vector h_pos = pos - '1 1 0';
+       vector h_size = item_size + '2 0 0';
+       // alternated rows highlighting
+       if(is_self)
+               drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
+       else if((scoreboard_highlight) && (!(pl_number % 2)))
+               drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+
+       tmp.x = item_size.x;
+       tmp.y = 0;
+       tmp.z = 0;
+       int i;
+       for(i = 0; i < hud_num_fields; ++i)
+       {
+               field = hud_field[i];
+               if(field == SP_SEPARATOR)
+                       break;
+
+               if(is_spec && field != SP_NAME && field != SP_PING) {
+                       pos.x += hud_size[i] + hud_fontsize.x;
+                       continue;
+               }
+               str = HUD_GetField(pl, field);
+               str = HUD_FixScoreboardColumnWidth(i, str);
+
+               pos.x += hud_size[i] + hud_fontsize.x;
+
+               if(field == SP_NAME) {
+                       tmp.x = hud_size[i] - hud_fontsize.x*hud_fixscoreboardcolumnwidth_iconlen - hud_fixscoreboardcolumnwidth_marginlen + hud_fontsize.x;
+                       if (is_self)
+                               drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                       else
+                               drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name, DRAWFLAG_NORMAL);
+               } else {
+                       tmp.x = hud_fixscoreboardcolumnwidth_len + hud_fontsize.x;
+                       if (is_self)
+                               drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                       else
+                               drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name, DRAWFLAG_NORMAL);
+               }
+
+               tmp.x = hud_size[i] + hud_fontsize.x;
+               if(hud_field_icon0 != "")
+                       if (is_self)
+                               drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                       else
+                               drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
+               if(hud_field_icon1 != "")
+                       if (is_self)
+                               drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                       else
+                               drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
+               if(hud_field_icon2 != "")
+                       if (is_self)
+                               drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                       else
+                               drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
+       }
+
+       if(hud_field[i] == SP_SEPARATOR)
+       {
+               pos.x = xmax;
+               for(i = hud_num_fields-1; i > 0; --i)
+               {
+                       field = hud_field[i];
+                       if(field == SP_SEPARATOR)
+                               break;
+
+                       if(is_spec && field != SP_NAME && field != SP_PING) {
+                               pos.x -= hud_size[i] + hud_fontsize.x;
+                               continue;
+                       }
+
+                       str = HUD_GetField(pl, field);
+                       str = HUD_FixScoreboardColumnWidth(i, str);
+
+                       if(field == SP_NAME) {
+                               tmp.x = hud_fixscoreboardcolumnwidth_len; // left or right aligned? let's put it right...
+                               if(is_self)
+                                       drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                               else
+                                       drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name, DRAWFLAG_NORMAL);
+                       } else {
+                               tmp.x = hud_fixscoreboardcolumnwidth_len;
+                               if(is_self)
+                                       drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                               else
+                                       drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name, DRAWFLAG_NORMAL);
+                       }
+
+                       tmp.x = hud_size[i];
+                       if(hud_field_icon0 != "")
+                               if (is_self)
+                                       drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                               else
+                                       drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
+                       if(hud_field_icon1 != "")
+                               if (is_self)
+                                       drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                               else
+                                       drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
+                       if(hud_field_icon2 != "")
+                               if (is_self)
+                                       drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
+                               else
+                                       drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
+                       pos.x -= hud_size[i] + hud_fontsize.x;
+               }
+       }
+
+       if(pl.eliminated)
+               drawfill(h_pos, h_size, '0 0 0', 0.5, DRAWFLAG_NORMAL);
+}
+
+/*
+ * HUD_Scoreboard_MakeTable
+ *
+ * Makes a table for a team (for all playing players in DM) and fills it
+ */
+
+vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
+{
+       float body_table_height;
+       vector tmp = '0 0 0', column_dim = '0 0 0';
+       entity pl;
+
+       body_table_height = 1.25 * hud_fontsize.y * max(1, tm.team_size); // no player? show 1 empty line
+
+       pos.y += autocvar_scoreboard_border_thickness;
+       pos -= '1 1 0';
+
+       tmp.x = sbwidth + 2;
+       tmp.y = 1.25 * hud_fontsize.y;
+
+       // rounded header
+       if (teamplay)
+               drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, (rgb * autocvar_scoreboard_color_bg_team) + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       else
+               drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, rgb + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+
+       // table border
+       tmp.y += autocvar_scoreboard_border_thickness;
+       tmp.y += body_table_height;
+       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL); // more transparency for the scoreboard
+
+       // separator header/table
+       pos.y += 1.25 * hud_fontsize.y;
+       tmp.y = autocvar_scoreboard_border_thickness;
+       drawfill(pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+
+       pos.y += autocvar_scoreboard_border_thickness;
+
+       // table background
+       tmp.y = body_table_height;
+       if (teamplay)
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       else
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+
+       // anyway, apply some color
+       //drawfill(pos, tmp + '2 0 0', rgb, 0.1, DRAWFLAG_NORMAL);
+
+       // go back to the top to make alternated columns highlighting and to print the strings
+       pos.y -= 1.25 * hud_fontsize.y;
+       pos.y -= autocvar_scoreboard_border_thickness;
+
+       pos += '1 1 0';
+
+       if (scoreboard_highlight)
+       {
+               column_dim.y = 1.25 * hud_fontsize.y; // header
+               column_dim.y += autocvar_scoreboard_border_thickness;
+               column_dim.y += body_table_height;
+       }
+
+       // print the strings of the columns headers and draw the columns
+       int i;
+       for(i = 0; i < hud_num_fields; ++i)
+       {
+               if(hud_field[i] == SP_SEPARATOR)
+                       break;
+               column_dim.x = hud_size[i] + hud_fontsize.x;
+               if (scoreboard_highlight)
+               {
+                       if (i % 2)
+                               drawfill(pos - '0 1 0' - hud_fontsize.x / 2 * '1 0 0', column_dim, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
+               }
+               drawstring(pos, hud_title[i], hud_fontsize, rgb * 1.5, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               pos.x += column_dim.x;
+       }
+       if(hud_field[i] == SP_SEPARATOR)
+       {
+               pos.x = xmax;
+               tmp.y = 0;
+               for(i = hud_num_fields-1; i > 0; --i)
+               {
+                       if(hud_field[i] == SP_SEPARATOR)
+                               break;
+
+                       pos.x -= hud_size[i];
+
+                       if (scoreboard_highlight)
+                       {
+                               if (!(i % 2))
+                               {
+                                       if (i == hud_num_fields-1)
+                                               column_dim.x = hud_size[i] + hud_fontsize.x / 2 + 1;
+                                       else
+                                               column_dim.x = hud_size[i] + hud_fontsize.x;
+                                       drawfill(pos - '0 1 0' - hud_fontsize.x / 2 * '1 0 0', column_dim, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
+                               }
+                       }
+
+                       tmp.x = stringwidth(hud_title[i], false, hud_fontsize);
+                       tmp.x = (hud_size[i] - tmp.x);
+                       drawstring(pos + tmp, hud_title[i], hud_fontsize, rgb * 1.5, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       pos.x -= hud_fontsize.x;
+               }
+       }
+
+       pos.x = xmin;
+       pos.y += 1.25 * hud_fontsize.y; // skip the header
+       pos.y += autocvar_scoreboard_border_thickness;
+
+       // item size
+       tmp.x = sbwidth;
+       tmp.y = hud_fontsize.y * 1.25;
+
+       // fill the table and draw the rows
+       i = 0;
+       if (teamplay)
+               for(pl = players.sort_next; pl; pl = pl.sort_next)
+               {
+                       if(pl.team != tm.team)
+                               continue;
+                       HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
+                       pos.y += 1.25 * hud_fontsize.y;
+                       ++i;
+               }
+       else
+               for(pl = players.sort_next; pl; pl = pl.sort_next)
+               {
+                       if(pl.team == NUM_SPECTATOR)
+                               continue;
+                       HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
+                       pos.y += 1.25 * hud_fontsize.y;
+                       ++i;
+               }
+
+       if (i == 0)
+               pos.y += 1.25 * hud_fontsize.y; // move to the end of the table
+       pos.y += 1.25 * hud_fontsize.y; // move empty row (out of the table)
+
+       return pos;
+}
+
+float HUD_WouldDrawScoreboard() {
+       if (QuickMenu_IsOpened())
+               return 0;
+       else if (HUD_Radar_Clickable())
+               return 0;
+       else if (scoreboard_showscores)
+               return 1;
+       else if (intermission == 1)
+               return 1;
+       else if (intermission == 2)
+               return 0;
+       else if (spectatee_status != -1 && STAT(HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != MAPINFO_TYPE_CTS && !active_minigame)
+               return 1;
+       else if (scoreboard_showscores_force)
+               return 1;
+       return 0;
+}
+
+float average_accuracy;
+vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
+{
+       WepSet weapons_stat = WepSet_GetFromStat();
+       WepSet weapons_inmap = WepSet_GetFromStat_InMap();
+       float initial_posx = pos.x;
+       int disownedcnt = 0;
+       FOREACH(Weapons, it != WEP_Null, {
+               int weapon_stats = weapon_accuracy[i - WEP_FIRST];
+
+               WepSet set = it.m_wepset;
+               if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
+                       ++disownedcnt;
+       });
+
+       int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt;
+       if (weapon_cnt <= 0) return pos;
+
+       int rows = 1;
+       if (autocvar_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
+               rows = 2;
+       int columnns = ceil(weapon_cnt / rows);
+
+       float height = 40;
+       float fontsize = height * 1/3;
+       float weapon_height = height * 2/3;
+       float weapon_width = sbwidth / columnns / rows;
+
+       drawstring(pos, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       pos.y += 1.25 * hud_fontsize.y + autocvar_scoreboard_border_thickness;
+       vector tmp = '0 0 0';
+       tmp.x = sbwidth;
+       tmp.y = height * rows;
+
+       if (teamplay)
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       else
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
+
+       // column highlighting
+       for (int i = 0; i < columnns; ++i)
+       {
+               if ((i % 2) == 0)
+                       drawfill(pos + '1 0 0' * weapon_width * rows * i, '0 1 0' * height * rows + '1 0 0' * weapon_width * rows, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
+       }
+
+       // row highlighting
+       for (int i = 0; i < rows; ++i)
+       {
+               drawfill(pos + '0 1 0' * weapon_height + '0 1 0' * height * i, '1 0 0' * sbwidth + '0 1 0' * fontsize, '1 1 1', scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+       }
+
+       average_accuracy = 0;
+       int weapons_with_stats = 0;
+       if (rows == 2)
+               pos.x += weapon_width / 2;
+
+       if (autocvar_scoreboard_accuracy_nocolors)
+               rgb = '1 1 1';
+       else
+               Accuracy_LoadColors();
+
+       float oldposx = pos.x;
+       vector tmpos = pos;
+
+       int column = 0;
+       FOREACH(Weapons, it != WEP_Null, {
+               int weapon_stats = weapon_accuracy[i - WEP_FIRST];
+
+               WepSet set = it.m_wepset;
+               if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
+                       continue;
+
+               float weapon_alpha;
+               if (weapon_stats >= 0)
+                       weapon_alpha = scoreboard_alpha_fg;
+               else
+                       weapon_alpha = 0.2 * scoreboard_alpha_fg;
+
+               // weapon icon
+               drawpic_aspect_skin(tmpos, it.model2, '1 0 0' * weapon_width + '0 1 0' * weapon_height, '1 1 1', weapon_alpha, DRAWFLAG_NORMAL);
+               // the accuracy
+               if (weapon_stats >= 0) {
+                       weapons_with_stats += 1;
+                       average_accuracy += weapon_stats; // store sum of all accuracies in average_accuracy
+
+                       string s;
+                       s = sprintf("%d%%", weapon_stats*100);
+
+                       float padding;
+                       padding = (weapon_width - stringwidth(s, false, '1 0 0' * fontsize)) / 2; // center the accuracy value
+
+                       if(!autocvar_scoreboard_accuracy_nocolors)
+                               rgb = Accuracy_GetColor(weapon_stats);
+
+                       drawstring(tmpos + '1 0 0' * padding + '0 1 0' * weapon_height, s, '1 1 0' * fontsize, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               }
+               tmpos.x += weapon_width * rows;
+               pos.x += weapon_width * rows;
+               if (rows == 2 && column == columnns - 1) {
+                       tmpos.x = oldposx;
+                       tmpos.y += height;
+                       pos.y += height;
+               }
+               ++column;
+       });
+
+       if (weapons_with_stats)
+               average_accuracy = floor((average_accuracy * 100 / weapons_with_stats) + 0.5);
+
+       pos.y += height;
+       pos.y += 1.25 * hud_fontsize.y;
+       pos.x = initial_posx;
+       return pos;
+}
+
+vector HUD_DrawKeyValue(vector pos, string key, string value) {
+       float px = pos.x;
+       pos.x += hud_fontsize.x * 0.25;
+       drawstring(pos, key, hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       pos.x = xmax - stringwidth(value, false, hud_fontsize) - hud_fontsize.x * 0.25;
+       drawstring(pos, value, hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       pos.x = px;
+       pos.y+= hud_fontsize.y;
+
+       return pos;
+}
+
+vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
+       float stat_secrets_found, stat_secrets_total;
+       float stat_monsters_killed, stat_monsters_total;
+       float rows = 0;
+       string val;
+
+       // get monster stats
+       stat_monsters_killed = STAT(MONSTERS_KILLED);
+       stat_monsters_total = STAT(MONSTERS_TOTAL);
+
+       // get secrets stats
+       stat_secrets_found = STAT(SECRETS_FOUND);
+       stat_secrets_total = STAT(SECRETS_TOTAL);
+
+       // get number of rows
+       if(stat_secrets_total)
+               rows += 1;
+       if(stat_monsters_total)
+               rows += 1;
+
+       // if no rows, return
+       if (!rows)
+               return pos;
+
+       //  draw table header
+       drawstring(pos, _("Map stats:"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       pos.y += 1.25 * hud_fontsize.y + autocvar_scoreboard_border_thickness;
+
+       // draw table
+       vector tmp = '0 0 0';
+       tmp.x = sbwidth;
+       tmp.y = hud_fontsize.y * rows;
+
+       if (teamplay)
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       else
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
+
+       // draw monsters
+       if(stat_monsters_total)
+       {
+               val = sprintf("%d/%d", stat_monsters_killed, stat_monsters_total);
+               pos = HUD_DrawKeyValue(pos, _("Monsters killed:"), val);
+       }
+
+       // draw secrets
+       if(stat_secrets_total)
+       {
+               val = sprintf("%d/%d", stat_secrets_found, stat_secrets_total);
+               pos = HUD_DrawKeyValue(pos, _("Secrets found:"), val);
+       }
+
+       // update position
+       pos.y += 1.25 * hud_fontsize.y;
+       return pos;
+}
+
+
+vector HUD_DrawScoreboardRankings(vector pos, entity pl,  vector rgb, vector bg_size)
+{
+       int i;
+       RANKINGS_RECEIVED_CNT = 0;
+       for (i=RANKINGS_CNT-1; i>=0; --i)
+               if (grecordtime[i])
+                       ++RANKINGS_RECEIVED_CNT;
+
+       if (RANKINGS_RECEIVED_CNT == 0)
+               return pos;
+
+       float is_spec;
+       is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
+       vector hl_rgb;
+       hl_rgb.x = autocvar_scoreboard_color_bg_r + 0.5;
+       hl_rgb.y = autocvar_scoreboard_color_bg_g + 0.5;
+       hl_rgb.z = autocvar_scoreboard_color_bg_b + 0.5;
+
+       pos.y += hud_fontsize.y;
+       drawstring(pos, _("Rankings"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       pos.y += hud_fontsize.y + autocvar_scoreboard_border_thickness;
+       vector tmp = '0 0 0';
+       tmp.x = sbwidth;
+       tmp.y = 1.25 * hud_fontsize.y * RANKINGS_RECEIVED_CNT;
+
+       if (teamplay)
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       else
+               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
+       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
+
+       // row highlighting
+       for(i = 0; i<RANKINGS_RECEIVED_CNT; ++i)
+       {
+               string n, p;
+               float t;
+               t = grecordtime[i];
+               if (t == 0)
+                       continue;
+               n = grecordholder[i];
+               p = count_ordinal(i+1);
+               if(grecordholder[i] == entcs_GetName(player_localnum))
+                       drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize.y, hl_rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
+               else if(!(i % 2) && scoreboard_highlight)
+                       drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize.y, hl_rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+               drawstring(pos, p, '1 1 0' * hud_fontsize.y, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               drawstring(pos + '3 0 0' * hud_fontsize.y, TIME_ENCODED_TOSTRING(t), '1 1 0' * hud_fontsize.y, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               drawcolorcodedstring(pos + '8 0 0' * hud_fontsize.y, n, '1 1 0' * hud_fontsize.y, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               pos.y += 1.25 * hud_fontsize.y;
+       }
+       pos.y += autocvar_scoreboard_border_thickness;
+
+       return pos;
+}
+
+float hud_woulddrawscoreboard_prev;
+float hud_woulddrawscoreboard_change; // "time" at which HUD_WouldDrawScoreboard() changed
+void HUD_DrawScoreboard()
+{
+       if(!autocvar__hud_configure)
+       {
+               float hud_woulddrawscoreboard;
+               hud_woulddrawscoreboard = scoreboard_active;
+               if(hud_woulddrawscoreboard != hud_woulddrawscoreboard_prev) {
+                       hud_woulddrawscoreboard_change = time;
+                       hud_woulddrawscoreboard_prev = hud_woulddrawscoreboard;
+               }
+       
+               if(hud_woulddrawscoreboard) {
+                       if(menu_enabled == 1)
+                               scoreboard_fade_alpha = 1;
+                       float scoreboard_fadeinspeed = autocvar_scoreboard_fadeinspeed;
+                       if (scoreboard_fadeinspeed)
+                               scoreboard_fade_alpha = bound (0, (time - hud_woulddrawscoreboard_change) * scoreboard_fadeinspeed, 1);
+                       else
+                               scoreboard_fade_alpha = 1;
+               }
+               else {
+                       float scoreboard_fadeoutspeed = autocvar_scoreboard_fadeoutspeed;
+                       if (scoreboard_fadeoutspeed)
+                               scoreboard_fade_alpha = bound (0, (1/scoreboard_fadeoutspeed - (time - hud_woulddrawscoreboard_change)) * scoreboard_fadeoutspeed, 1);
+                       else
+                               scoreboard_fade_alpha = 0;
+               }
+
+               if (!scoreboard_fade_alpha)
+                       return;
+       }
+       else
+               scoreboard_fade_alpha = 0;
+
+       if (autocvar_scoreboard_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
+
+       float hud_fade_alpha_save = hud_fade_alpha;
+       if(menu_enabled == 1)
+               hud_fade_alpha = 1;
+       else
+               hud_fade_alpha = scoreboard_fade_alpha * (1 - autocvar__menu_alpha);
+       HUD_Panel_UpdateCvars();
+
+       scoreboard_alpha_bg = autocvar_scoreboard_alpha_bg * panel_fg_alpha;
+       scoreboard_alpha_fg = autocvar_scoreboard_alpha_fg * panel_fg_alpha;
+       scoreboard_highlight = autocvar_scoreboard_highlight;
+       scoreboard_highlight_alpha = autocvar_scoreboard_highlight_alpha * panel_fg_alpha;
+       scoreboard_highlight_alpha_self = autocvar_scoreboard_highlight_alpha_self * panel_fg_alpha;
+       scoreboard_alpha_name = autocvar_scoreboard_alpha_name * panel_fg_alpha;
+       scoreboard_alpha_name_self = autocvar_scoreboard_alpha_name_self * panel_fg_alpha;
+
+       hud_fade_alpha = hud_fade_alpha_save;
+
+       // don't overlap with con_notify
+       if(!autocvar__hud_configure)
+               panel_pos_y = max((autocvar_con_notify * autocvar_con_notifysize), panel_pos_y);
+
+       HUD_Panel_DrawBg(scoreboard_fade_alpha);
+
+       if(panel_bg_padding)
+       {
+               panel_pos += '1 1 0' * panel_bg_padding;
+               panel_size -= '2 2 0' * panel_bg_padding;
+       }
+
+       HUD_UpdatePlayerTeams();
+
+       vector rgb, pos, tmp;
+       entity pl, tm;
+       string str;
+
+       xmin = panel_pos_x;
+       ymin = panel_pos_y;
+
+       xmax = panel_pos_x + panel_size_x;
+       ymax = panel_pos_y + panel_size_y;
+
+       sbwidth = panel_size_x;
+
+       // Initializes position
+       pos.x = xmin;
+       pos.y = ymin;
+       pos.z = 0;
+
+       // Heading
+       vector sb_heading_fontsize;
+       sb_heading_fontsize = hud_fontsize * 2;
+       draw_beginBoldFont();
+       drawstring(pos, _("Scoreboard"), sb_heading_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       draw_endBoldFont();
+
+       pos.y += sb_heading_fontsize.y + hud_fontsize.y * 0.25;
+
+       // Draw the scoreboard
+       vector bg_size = draw_getimagesize("gfx/scoreboard/scoreboard_bg") * ((autocvar_scoreboard_bg_scale > 0) ? autocvar_scoreboard_bg_scale : 0.25);
+
+       if(teamplay)
+       {
+               vector team_score_baseoffset;
+               team_score_baseoffset = eY * (2 * autocvar_scoreboard_border_thickness + hud_fontsize.y) - eX * (autocvar_scoreboard_border_thickness + hud_fontsize.x * 0.25);
+               for(tm = teams.sort_next; tm; tm = tm.sort_next)
+               {
+                       if(tm.team == NUM_SPECTATOR)
+                               continue;
+                       if(!tm.team && teamplay)
+                               continue;
+
+                       draw_beginBoldFont();
+                       rgb = Team_ColorRGB(tm.team);
+                       str = ftos(tm.(teamscores[ts_primary]));
+                       drawstring(pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize * 1.5), str, hud_fontsize * 1.5, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+
+                       if(ts_primary != ts_secondary)
+                       {
+                               str = ftos(tm.(teamscores[ts_secondary]));
+                               drawstring(pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize) + eY * hud_fontsize.y * 1.5, str, hud_fontsize, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       }
+                       draw_endBoldFont();
+
+                       pos = HUD_Scoreboard_MakeTable(pos, tm, rgb, bg_size);
+               }
+               rgb.x = autocvar_scoreboard_color_bg_r;
+               rgb.y = autocvar_scoreboard_color_bg_g;
+               rgb.z = autocvar_scoreboard_color_bg_b;
+       }
+       else
+       {
+               rgb.x = autocvar_scoreboard_color_bg_r;
+               rgb.y = autocvar_scoreboard_color_bg_g;
+               rgb.z = autocvar_scoreboard_color_bg_b;
+
+               for(tm = teams.sort_next; tm; tm = tm.sort_next)
+               {
+                       if(tm.team == NUM_SPECTATOR)
+                               continue;
+                       if(!tm.team && teamplay)
+                               continue;
+
+                       pos = HUD_Scoreboard_MakeTable(pos, tm, rgb, bg_size);
+               }
+       }
+
+       if(gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE) {
+               if(race_speedaward) {
+                       drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, race_speedaward_unit, race_speedaward_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       pos.y += 1.25 * hud_fontsize.y;
+               }
+               if(race_speedaward_alltimebest) {
+                       drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d%s ^7(%s^7)"), race_speedaward_alltimebest, race_speedaward_alltimebest_unit, race_speedaward_alltimebest_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       pos.y += 1.25 * hud_fontsize.y;
+               }
+               pos = HUD_DrawScoreboardRankings(pos, playerslots[player_localnum], rgb, bg_size);
+       }
+       else if (autocvar_scoreboard_accuracy && !warmup_stage && gametype != MAPINFO_TYPE_NEXBALL) {
+               if(teamplay)
+                       pos = HUD_DrawScoreboardAccuracyStats(pos, Team_ColorRGB(myteam), bg_size);
+               else
+                       pos = HUD_DrawScoreboardAccuracyStats(pos, rgb, bg_size);
+       }
+
+
+       if(teamplay)
+               pos = HUD_DrawMapStats(pos, Team_ColorRGB(myteam), bg_size);
+       else
+               pos = HUD_DrawMapStats(pos, rgb, bg_size);
+
+       // List spectators
+       float specs;
+       specs = 0;
+       tmp = pos;
+       vector item_size;
+       item_size.x = sbwidth;
+       item_size.y = hud_fontsize.y * 1.25;
+       item_size.z = 0;
+       for(pl = players.sort_next; pl; pl = pl.sort_next)
+       {
+               if(pl.team != NUM_SPECTATOR)
+                       continue;
+               pos.y += 1.25 * hud_fontsize.y;
+               HUD_PrintScoreboardItem(pos, item_size, pl, (pl.sv_entnum == player_localnum), specs);
+               ++specs;
+       }
+
+       if(specs)
+       {
+               draw_beginBoldFont();
+               drawstring(tmp, _("Spectators"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               draw_endBoldFont();
+               pos.y += 1.25 * hud_fontsize.y;
+       }
+
+       // Print info string
+       float tl, fl, ll;
+       str = sprintf(_("playing ^3%s^7 on ^2%s^7"), MapInfo_Type_ToText(gametype), shortmapname);
+       tl = STAT(TIMELIMIT);
+       fl = STAT(FRAGLIMIT);
+       ll = STAT(LEADLIMIT);
+       if(gametype == MAPINFO_TYPE_LMS)
+       {
+               if(tl > 0)
+                       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%1.0f minutes^7"), tl));
+               if(fl > 0)
+               {
+                       if(tl > 0)
+                               str = strcat(str, _(" or"));
+                       if(teamplay)
+                       {
+                               str = strcat(str, sprintf(_(" until ^3%s %s^7"), ScoreString(teamscores_flags[ts_primary], fl),
+                                       (teamscores_label[ts_primary] == "score")   ? CTX(_("SCO^points")) :
+                                       (teamscores_label[ts_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       TranslateScoresLabel(teamscores_label[ts_primary])));
+                       }
+                       else
+                       {
+                               str = strcat(str, sprintf(_(" until ^3%s %s^7"), ScoreString(scores_flags[ps_primary], fl),
+                                       (scores_label[ps_primary] == "score")   ? CTX(_("SCO^points")) :
+                                       (scores_label[ps_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       TranslateScoresLabel(scores_label[ps_primary])));
+                       }
+               }
+               if(ll > 0)
+               {
+                       if(tl > 0 || fl > 0)
+                               str = strcat(str, _(" or"));
+                       if(teamplay)
+                       {
+                               str = strcat(str, sprintf(_(" until a lead of ^3%s %s^7"), ScoreString(teamscores_flags[ts_primary], ll),
+                                       (teamscores_label[ts_primary] == "score")   ? CTX(_("SCO^points")) :
+                                       (teamscores_label[ts_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       TranslateScoresLabel(teamscores_label[ts_primary])));
+                       }
+                       else
+                       {
+                               str = strcat(str, sprintf(_(" until a lead of ^3%s %s^7"), ScoreString(scores_flags[ps_primary], ll),
+                                       (scores_label[ps_primary] == "score")   ? CTX(_("SCO^points")) :
+                                       (scores_label[ps_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       TranslateScoresLabel(scores_label[ps_primary])));
+                       }
+               }
+       }
+
+       pos.y += 1.2 * hud_fontsize.y;
+       drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+
+       // print information about respawn status
+       float respawn_time = STAT(RESPAWN_TIME);
+       if(!intermission)
+       if(respawn_time)
+       {
+               if(respawn_time < 0)
+               {
+                       // a negative number means we are awaiting respawn, time value is still the same
+                       respawn_time *= -1; // remove mark now that we checked it
+                       respawn_time = max(time, respawn_time); // don't show a negative value while the server is respawning the player (lag)
+
+                       str = sprintf(_("^1Respawning in ^3%s^1..."),
+                               (autocvar_scoreboard_respawntime_decimals ?
+                                       count_seconds_decs(respawn_time - time, autocvar_scoreboard_respawntime_decimals)
+                                       :
+                                       count_seconds(respawn_time - time)
+                               )
+                       );
+               }
+               else if(time < respawn_time)
+               {
+                       str = sprintf(_("You are dead, wait ^3%s^7 before respawning"),
+                               (autocvar_scoreboard_respawntime_decimals ?
+                                       count_seconds_decs(respawn_time - time, autocvar_scoreboard_respawntime_decimals)
+                                       :
+                                       count_seconds(respawn_time - time)
+                               )
+                       );
+               }
+               else if(time >= respawn_time)
+                       str = sprintf(_("You are dead, press ^2%s^7 to respawn"), getcommandkey("jump", "+jump"));
+
+               pos.y += 1.2 * hud_fontsize.y;
+               drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       }
+
+       scoreboard_bottom = pos.y + 2 * hud_fontsize.y;
+}
diff --git a/qcsrc/client/hud/panel/scoreboard.qh b/qcsrc/client/hud/panel/scoreboard.qh
new file mode 100644 (file)
index 0000000..227e5a9
--- /dev/null
@@ -0,0 +1,14 @@
+#pragma once
+#include "../panel.qh"
+
+float xmin, xmax, ymin, ymax, sbwidth;
+
+float scoreboard_active;
+float scoreboard_fade_alpha;
+
+void Cmd_HUD_SetFields(float argc);
+void HUD_DrawScoreboard();
+void HUD_InitScores();
+void HUD_UpdatePlayerPos(entity pl);
+void HUD_UpdateTeamPos(entity Team);
+float HUD_WouldDrawScoreboard();
index bd9e82ed21dac1c9af805b844ba63767bd2878cc..9274613cbc1d90b418d0ab8bf9cca77ce80fd629 100644 (file)
@@ -4,8 +4,8 @@
 #include "hud/all.qh"
 #include "mapvoting.qh"
 #include "mutators/events.qh"
+#include "hud/panel/scoreboard.qh"
 #include "hud/panel/quickmenu.qh"
-#include "scoreboard.qh"
 #include "shownames.qh"
 #include <common/t_items.qh>
 #include "wall.qh"
index bfc25e99c134116524b39fe0934773484e1627f7..b7751ed06ef75cf730252aaca51946e70c0721bf 100644 (file)
@@ -1,7 +1,7 @@
 #include "mapvoting.qh"
 
 #include "hud/all.qh"
-#include "scoreboard.qh"
+#include "hud/panel/scoreboard.qh"
 
 #include <common/mapinfo.qh>
 
diff --git a/qcsrc/client/scoreboard.qc b/qcsrc/client/scoreboard.qc
deleted file mode 100644 (file)
index cc605d6..0000000
+++ /dev/null
@@ -1,1543 +0,0 @@
-#include "scoreboard.qh"
-
-#include "hud/panel/quickmenu.qh"
-#include "hud/all.qh"
-
-#include <common/ent_cs.qh>
-#include <common/constants.qh>
-#include <common/mapinfo.qh>
-#include <common/minigames/cl_minigames.qh>
-#include <common/stats.qh>
-#include <common/teams.qh>
-
-float scoreboard_alpha_bg;
-float scoreboard_alpha_fg;
-float scoreboard_highlight;
-float scoreboard_highlight_alpha;
-float scoreboard_highlight_alpha_self;
-float scoreboard_alpha_name;
-float scoreboard_alpha_name_self;
-
-void drawstringright(vector, string, vector, vector, float, float);
-void drawstringcenter(vector, string, vector, vector, float, float);
-
-const float SCOREBOARD_OFFSET = 50;
-
-// wrapper to put all possible scores titles through gettext
-string TranslateScoresLabel(string l)
-{
-       switch(l)
-       {
-               case "bckills": return CTX(_("SCO^bckills"));
-               case "bctime": return CTX(_("SCO^bctime"));
-               case "caps": return CTX(_("SCO^caps"));
-               case "captime": return CTX(_("SCO^captime"));
-               case "deaths": return CTX(_("SCO^deaths"));
-               case "destroyed": return CTX(_("SCO^destroyed"));
-               case "dmg": return CTX(_("SCO^dmg"));
-               case "dmgtaken": return CTX(_("SCO^dmgtaken"));
-               case "drops": return CTX(_("SCO^drops"));
-               case "faults": return CTX(_("SCO^faults"));
-               case "fckills": return CTX(_("SCO^fckills"));
-               case "goals": return CTX(_("SCO^goals"));
-               case "kckills": return CTX(_("SCO^kckills"));
-               case "kdratio": return CTX(_("SCO^kdratio"));
-               case "k/d": return CTX(_("SCO^k/d"));
-               case "kd": return CTX(_("SCO^kd"));
-               case "kdr": return CTX(_("SCO^kdr"));
-               case "kills": return CTX(_("SCO^kills"));
-               case "laps": return CTX(_("SCO^laps"));
-               case "lives": return CTX(_("SCO^lives"));
-               case "losses": return CTX(_("SCO^losses"));
-               case "name": return CTX(_("SCO^name"));
-               case "sum": return CTX(_("SCO^sum"));
-               case "nick": return CTX(_("SCO^nick"));
-               case "objectives": return CTX(_("SCO^objectives"));
-               case "pickups": return CTX(_("SCO^pickups"));
-               case "ping": return CTX(_("SCO^ping"));
-               case "pl": return CTX(_("SCO^pl"));
-               case "pushes": return CTX(_("SCO^pushes"));
-               case "rank": return CTX(_("SCO^rank"));
-               case "returns": return CTX(_("SCO^returns"));
-               case "revivals": return CTX(_("SCO^revivals"));
-               case "score": return CTX(_("SCO^score"));
-               case "suicides": return CTX(_("SCO^suicides"));
-               case "takes": return CTX(_("SCO^takes"));
-               case "ticks": return CTX(_("SCO^ticks"));
-               default: return l;
-       }
-}
-
-void HUD_InitScores()
-{
-       int i, f;
-
-       ps_primary = ps_secondary = ts_primary = ts_secondary = -1;
-       for(i = 0; i < MAX_SCORE; ++i)
-       {
-               f = (scores_flags[i] & SFL_SORT_PRIO_MASK);
-               if(f == SFL_SORT_PRIO_PRIMARY)
-                       ps_primary = i;
-               if(f == SFL_SORT_PRIO_SECONDARY)
-                       ps_secondary = i;
-       }
-       if(ps_secondary == -1)
-               ps_secondary = ps_primary;
-
-       for(i = 0; i < MAX_TEAMSCORE; ++i)
-       {
-               f = (teamscores_flags[i] & SFL_SORT_PRIO_MASK);
-               if(f == SFL_SORT_PRIO_PRIMARY)
-                       ts_primary = i;
-               if(f == SFL_SORT_PRIO_SECONDARY)
-                       ts_secondary = i;
-       }
-       if(ts_secondary == -1)
-               ts_secondary = ts_primary;
-
-       Cmd_HUD_SetFields(0);
-}
-
-float SetTeam(entity pl, float Team);
-//float lastpnum;
-void HUD_UpdatePlayerTeams()
-{
-       float Team;
-       entity pl, tmp;
-       float num;
-
-       num = 0;
-       for(pl = players.sort_next; pl; pl = pl.sort_next)
-       {
-               num += 1;
-               Team = entcs_GetScoreTeam(pl.sv_entnum);
-               if(SetTeam(pl, Team))
-               {
-                       tmp = pl.sort_prev;
-                       HUD_UpdatePlayerPos(pl);
-                       if(tmp)
-                               pl = tmp;
-                       else
-                               pl = players.sort_next;
-               }
-       }
-       /*
-       if(num != lastpnum)
-               print(strcat("PNUM: ", ftos(num), "\n"));
-       lastpnum = num;
-       */
-}
-
-int HUD_CompareScore(int vl, int vr, int f)
-{
-    TC(int, vl); TC(int, vr); TC(int, f);
-       if(f & SFL_ZERO_IS_WORST)
-       {
-               if(vl == 0 && vr != 0)
-                       return 1;
-               if(vl != 0 && vr == 0)
-                       return 0;
-       }
-       if(vl > vr)
-               return IS_INCREASING(f);
-       if(vl < vr)
-               return IS_DECREASING(f);
-       return -1;
-}
-
-float HUD_ComparePlayerScores(entity left, entity right)
-{
-       float vl, vr, r;
-       vl = entcs_GetTeam(left.sv_entnum);
-       vr = entcs_GetTeam(right.sv_entnum);
-
-       if(!left.gotscores)
-               vl = NUM_SPECTATOR;
-       if(!right.gotscores)
-               vr = NUM_SPECTATOR;
-
-       if(vl > vr)
-               return true;
-       if(vl < vr)
-               return false;
-
-       if(vl == NUM_SPECTATOR)
-       {
-               // FIRST the one with scores (spectators), THEN the ones without (downloaders)
-               // no other sorting
-               if(!left.gotscores && right.gotscores)
-                       return true;
-               return false;
-       }
-
-       r = HUD_CompareScore(left.scores[ps_primary], right.scores[ps_primary], scores_flags[ps_primary]);
-       if (r >= 0)
-               return r;
-
-       r = HUD_CompareScore(left.scores[ps_secondary], right.scores[ps_secondary], scores_flags[ps_secondary]);
-       if (r >= 0)
-               return r;
-
-       int i;
-       for(i = 0; i < MAX_SCORE; ++i)
-       {
-               r = HUD_CompareScore(left.scores[i], right.scores[i], scores_flags[i]);
-               if (r >= 0)
-                       return r;
-       }
-
-       if (left.sv_entnum < right.sv_entnum)
-               return true;
-
-       return false;
-}
-
-void HUD_UpdatePlayerPos(entity player)
-{
-       entity ent;
-       for(ent = player.sort_next; ent && HUD_ComparePlayerScores(player, ent); ent = player.sort_next)
-       {
-               SORT_SWAP(player, ent);
-       }
-       for(ent = player.sort_prev; ent != players && HUD_ComparePlayerScores(ent, player); ent = player.sort_prev)
-       {
-               SORT_SWAP(ent, player);
-       }
-}
-
-float HUD_CompareTeamScores(entity left, entity right)
-{
-       int i, r;
-
-       if(left.team == NUM_SPECTATOR)
-               return 1;
-       if(right.team == NUM_SPECTATOR)
-               return 0;
-
-       r = HUD_CompareScore(left.teamscores[ts_primary], right.teamscores[ts_primary], teamscores_flags[ts_primary]);
-       if (r >= 0)
-               return r;
-
-       r = HUD_CompareScore(left.teamscores[ts_secondary], right.teamscores[ts_secondary], teamscores_flags[ts_secondary]);
-       if (r >= 0)
-               return r;
-
-       for(i = 0; i < MAX_SCORE; ++i)
-       {
-               r = HUD_CompareScore(left.teamscores[i], right.teamscores[i], teamscores_flags[i]);
-               if (r >= 0)
-                       return r;
-       }
-
-       if (left.team < right.team)
-               return true;
-
-       return false;
-}
-
-void HUD_UpdateTeamPos(entity Team)
-{
-       entity ent;
-       for(ent = Team.sort_next; ent && HUD_CompareTeamScores(Team, ent); ent = Team.sort_next)
-       {
-               SORT_SWAP(Team, ent);
-       }
-       for(ent = Team.sort_prev; ent != teams && HUD_CompareTeamScores(ent, Team); ent = Team.sort_prev)
-       {
-               SORT_SWAP(ent, Team);
-       }
-}
-
-void Cmd_HUD_Help()
-{
-       LOG_INFO(_("You can modify the scoreboard using the ^2scoreboard_columns_set command.\n"));
-       LOG_INFO(_("^3|---------------------------------------------------------------|\n"));
-       LOG_INFO(_("Usage:\n"));
-       LOG_INFO(_("^2scoreboard_columns_set default\n"));
-       LOG_INFO(_("^2scoreboard_columns_set ^7field1 field2 ...\n"));
-       LOG_INFO(_("The following field names are recognized (case insensitive):\n"));
-       LOG_INFO(_("You can use a ^3|^7 to start the right-aligned fields.\n\n"));
-
-       LOG_INFO(_("^3name^7 or ^3nick^7             Name of a player\n"));
-       LOG_INFO(_("^3ping^7                     Ping time\n"));
-       LOG_INFO(_("^3pl^7                       Packet loss\n"));
-       LOG_INFO(_("^3kills^7                    Number of kills\n"));
-       LOG_INFO(_("^3deaths^7                   Number of deaths\n"));
-       LOG_INFO(_("^3suicides^7                 Number of suicides\n"));
-       LOG_INFO(_("^3frags^7                    kills - suicides\n"));
-       LOG_INFO(_("^3kd^7                       The kill-death ratio\n"));
-       LOG_INFO(_("^3dmg^7                      The total damage done\n"));
-       LOG_INFO(_("^3dmgtaken^7                 The total damage taken\n"));
-       LOG_INFO(_("^3sum^7                      frags - deaths\n"));
-       LOG_INFO(_("^3caps^7                     How often a flag (CTF) or a key (KeyHunt) was captured\n"));
-       LOG_INFO(_("^3pickups^7                  How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up\n"));
-       LOG_INFO(_("^3captime^7                  Time of fastest cap (CTF)\n"));
-       LOG_INFO(_("^3fckills^7                  Number of flag carrier kills\n"));
-       LOG_INFO(_("^3returns^7                  Number of flag returns\n"));
-       LOG_INFO(_("^3drops^7                    Number of flag drops\n"));
-       LOG_INFO(_("^3lives^7                    Number of lives (LMS)\n"));
-       LOG_INFO(_("^3rank^7                     Player rank\n"));
-       LOG_INFO(_("^3pushes^7                   Number of players pushed into void\n"));
-       LOG_INFO(_("^3destroyed^7                Number of keys destroyed by pushing them into void\n"));
-       LOG_INFO(_("^3kckills^7                  Number of keys carrier kills\n"));
-       LOG_INFO(_("^3losses^7                   Number of times a key was lost\n"));
-       LOG_INFO(_("^3laps^7                     Number of laps finished (race/cts)\n"));
-       LOG_INFO(_("^3time^7                     Total time raced (race/cts)\n"));
-       LOG_INFO(_("^3fastest^7                  Time of fastest lap (race/cts)\n"));
-       LOG_INFO(_("^3ticks^7                    Number of ticks (DOM)\n"));
-       LOG_INFO(_("^3takes^7                    Number of domination points taken (DOM)\n"));
-       LOG_INFO(_("^3bckills^7                  Number of ball carrier kills\n"));
-       LOG_INFO(_("^3bctime^7                   Total amount of time holding the ball in Keepaway\n"));
-       LOG_INFO(_("^3score^7                    Total score\n\n"));
-
-       LOG_INFO(_("Before a field you can put a + or - sign, then a comma separated list\n"
-               "of game types, then a slash, to make the field show up only in these\n"
-               "or in all but these game types. You can also specify 'all' as a\n"
-               "field to show all fields available for the current game mode.\n\n"));
-
-       LOG_INFO(_("The special game type names 'teams' and 'noteams' can be used to\n"
-               "include/exclude ALL teams/noteams game modes.\n\n"));
-
-       LOG_INFO(_("Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4\n"));
-       LOG_INFO(_("will display name, ping and pl aligned to the left, and the fields\n"
-               "right of the vertical bar aligned to the right.\n"));
-       LOG_INFO(_("'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
-               "other gamemodes except DM.\n"));
-}
-
-// NOTE: adding a gametype with ? to not warn for an optional field
-// make sure it's excluded in a previous exclusive rule, if any
-// otherwise the previous exclusive rule warns anyway
-// e.g. -teams,rc,cts,lms/kills ?+rc/kills
-#define SCOREBOARD_DEFAULT_COLUMNS \
-"ping pl name |" \
-" -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
-" -teams,lms/deaths +ft,tdm/deaths" \
-" -teams,lms,rc,cts,inv,ka/suicides +ft,tdm/suicides ?+rc,inv/suicides" \
-" -cts,dm,tdm,ka,ft/frags" /* tdm already has this in "score" */ \
-" -rc,cts,nb/dmg -rc,cts,nb/dmgtaken" \
-" +ctf/caps +ctf/pickups +ctf/fckills +ctf/returns +ons/caps +ons/takes" \
-" +lms/lives +lms/rank" \
-" +kh/caps +kh/pushes +kh/destroyed" \
-" ?+rc/laps ?+rc/time +rc,cts/fastest" \
-" +as/objectives +nb/faults +nb/goals" \
-" +ka/pickups +ka/bckills +ka/bctime +ft/revivals" \
-" -lms,rc,cts,inv,nb/score"
-
-void Cmd_HUD_SetFields(int argc)
-{
-    TC(int, argc);
-       int i, j, slash;
-       string str, pattern;
-       float have_name = 0, have_primary = 0, have_secondary = 0, have_separator = 0;
-       float missing;
-
-       if(!gametype)
-       {
-               // set up a temporary scoreboard layout
-               // no layout can be properly set up until score_info data haven't been received
-               argc = tokenizebyseparator("0 1 ping pl name | score", " ");
-               ps_primary = 0;
-               scores_label[ps_primary] = strzone("score");
-               scores_flags[ps_primary] = SFL_ALLOW_HIDE;
-       }
-
-       // TODO: re enable with gametype dependant cvars?
-       if(argc < 3) // no arguments provided
-               argc = tokenizebyseparator(strcat("0 1 ", autocvar_scoreboard_columns), " ");
-
-       if(argc < 3)
-               argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " ");
-
-       if(argc == 3)
-       {
-               if(argv(2) == "default")
-                       argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " ");
-               else if(argv(2) == "all")
-               {
-                       string s;
-                       s = "ping pl name |";
-                       for(i = 0; i < MAX_SCORE; ++i)
-                       {
-                               if(i != ps_primary)
-                               if(i != ps_secondary)
-                               if(scores_label[i] != "")
-                                       s = strcat(s, " ", scores_label[i]);
-                       }
-                       if(ps_secondary != ps_primary)
-                               s = strcat(s, " ", scores_label[ps_secondary]);
-                       s = strcat(s, " ", scores_label[ps_primary]);
-                       argc = tokenizebyseparator(strcat("0 1 ", s), " ");
-               }
-       }
-
-
-       hud_num_fields = 0;
-
-       hud_fontsize = HUD_GetFontsize("hud_fontsize");
-
-       for(i = 1; i < argc - 1; ++i)
-       {
-               float nocomplain;
-               str = argv(i+1);
-
-               nocomplain = false;
-               if(substring(str, 0, 1) == "?")
-               {
-                       nocomplain = true;
-                       str = substring(str, 1, strlen(str) - 1);
-               }
-
-               slash = strstrofs(str, "/", 0);
-               if(slash >= 0)
-               {
-                       pattern = substring(str, 0, slash);
-                       str = substring(str, slash + 1, strlen(str) - (slash + 1));
-
-                       if (!isGametypeInFilter(gametype, teamplay, false, pattern))
-                               continue;
-               }
-
-               strunzone(hud_title[hud_num_fields]);
-               hud_title[hud_num_fields] = strzone(TranslateScoresLabel(str));
-               hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], false, hud_fontsize);
-               str = strtolower(str);
-
-               switch(str)
-               {
-                       case "ping": hud_field[hud_num_fields] = SP_PING; break;
-                       case "pl": hud_field[hud_num_fields] = SP_PL; break;
-                       case "kd": case "kdr": case "kdratio": case "k/d": hud_field[hud_num_fields] = SP_KDRATIO; break;
-                       case "sum": case "diff": case "k-d": hud_field[hud_num_fields] = SP_SUM; break;
-                       case "name": case "nick": hud_field[hud_num_fields] = SP_NAME; have_name = true; break;
-                       case "|": hud_field[hud_num_fields] = SP_SEPARATOR; have_separator = true; break;
-                       case "dmg": hud_field[hud_num_fields] = SP_DMG; break;
-                       case "dmgtaken": hud_field[hud_num_fields] = SP_DMGTAKEN; break;
-                       default:
-                       {
-                               for(j = 0; j < MAX_SCORE; ++j)
-                                       if(str == strtolower(scores_label[j]))
-                                               goto found; // sorry, but otherwise fteqcc -O3 miscompiles this and warns about "unreachable code"
-
-LABEL(notfound)
-                               if(str == "frags")
-                                       j = SP_FRAGS;
-                               else
-                               {
-                                       if(!nocomplain)
-                                               LOG_INFOF("^1Error:^7 Unknown score field: '%s'\n", str);
-                                       continue;
-                               }
-LABEL(found)
-                               hud_field[hud_num_fields] = j;
-                               if(j == ps_primary)
-                                       have_primary = 1;
-                               if(j == ps_secondary)
-                                       have_secondary = 1;
-
-                       }
-               }
-               ++hud_num_fields;
-               if(hud_num_fields >= MAX_HUD_FIELDS)
-                       break;
-       }
-
-       if(scores_flags[ps_primary] & SFL_ALLOW_HIDE)
-               have_primary = 1;
-       if(scores_flags[ps_secondary] & SFL_ALLOW_HIDE)
-               have_secondary = 1;
-       if(ps_primary == ps_secondary)
-               have_secondary = 1;
-       missing = (!have_primary) + (!have_secondary) + (!have_separator) + (!have_name);
-
-       if(hud_num_fields+missing < MAX_HUD_FIELDS)
-       {
-               if(!have_name)
-               {
-                       strunzone(hud_title[hud_num_fields]);
-                       for(i = hud_num_fields; i > 0; --i)
-                       {
-                               hud_title[i] = hud_title[i-1];
-                               hud_size[i] = hud_size[i-1];
-                               hud_field[i] = hud_field[i-1];
-                       }
-                       hud_title[0] = strzone(TranslateScoresLabel("name"));
-                       hud_field[0] = SP_NAME;
-                       ++hud_num_fields;
-                       LOG_INFO("fixed missing field 'name'\n");
-
-                       if(!have_separator)
-                       {
-                               strunzone(hud_title[hud_num_fields]);
-                               for(i = hud_num_fields; i > 1; --i)
-                               {
-                                       hud_title[i] = hud_title[i-1];
-                                       hud_size[i] = hud_size[i-1];
-                                       hud_field[i] = hud_field[i-1];
-                               }
-                               hud_title[1] = strzone("|");
-                               hud_field[1] = SP_SEPARATOR;
-                               hud_size[1] = stringwidth("|", false, hud_fontsize);
-                               ++hud_num_fields;
-                               LOG_INFO("fixed missing field '|'\n");
-                       }
-               }
-               else if(!have_separator)
-               {
-                       strunzone(hud_title[hud_num_fields]);
-                       hud_title[hud_num_fields] = strzone("|");
-                       hud_size[hud_num_fields] = stringwidth("|", false, hud_fontsize);
-                       hud_field[hud_num_fields] = SP_SEPARATOR;
-                       ++hud_num_fields;
-                       LOG_INFO("fixed missing field '|'\n");
-               }
-               if(!have_secondary)
-               {
-                       strunzone(hud_title[hud_num_fields]);
-                       hud_title[hud_num_fields] = strzone(TranslateScoresLabel(scores_label[ps_secondary]));
-                       hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], false, hud_fontsize);
-                       hud_field[hud_num_fields] = ps_secondary;
-                       ++hud_num_fields;
-                       LOG_INFOF("fixed missing field '%s'\n", scores_label[ps_secondary]);
-               }
-               if(!have_primary)
-               {
-                       strunzone(hud_title[hud_num_fields]);
-                       hud_title[hud_num_fields] = strzone(TranslateScoresLabel(scores_label[ps_primary]));
-                       hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], false, hud_fontsize);
-                       hud_field[hud_num_fields] = ps_primary;
-                       ++hud_num_fields;
-                       LOG_INFOF("fixed missing field '%s'\n", scores_label[ps_primary]);
-               }
-       }
-
-       hud_field[hud_num_fields] = SP_END;
-}
-
-// MOVEUP::
-vector hud_field_rgb;
-string hud_field_icon0;
-string hud_field_icon1;
-string hud_field_icon2;
-vector hud_field_icon0_rgb;
-vector hud_field_icon1_rgb;
-vector hud_field_icon2_rgb;
-float hud_field_icon0_alpha;
-float hud_field_icon1_alpha;
-float hud_field_icon2_alpha;
-string HUD_GetField(entity pl, int field)
-{
-    TC(int, field);
-       float tmp, num, denom;
-       int f;
-       string str;
-       hud_field_rgb = '1 1 1';
-       hud_field_icon0 = "";
-       hud_field_icon1 = "";
-       hud_field_icon2 = "";
-       hud_field_icon0_rgb = '1 1 1';
-       hud_field_icon1_rgb = '1 1 1';
-       hud_field_icon2_rgb = '1 1 1';
-       hud_field_icon0_alpha = 1;
-       hud_field_icon1_alpha = 1;
-       hud_field_icon2_alpha = 1;
-       switch(field)
-       {
-               case SP_PING:
-                       if (!pl.gotscores)
-                               return "\xE2\x96\xB6\xE2\x96\xB6\xE2\x96\xB6"; // >>> sign using U+25B6
-                       //str = getplayerkeyvalue(pl.sv_entnum, "ping");
-                       f = pl.ping;
-                       if(f == 0)
-                               return _("N/A");
-                       tmp = max(0, min(220, f-80)) / 220;
-                       hud_field_rgb = '1 1 1' - '0 1 1'*tmp;
-                       return ftos(f);
-
-               case SP_PL:
-                       if (!pl.gotscores)
-                               return _("N/A");
-                       f = pl.ping_packetloss;
-                       tmp = pl.ping_movementloss;
-                       if(f == 0 && tmp == 0)
-                               return "";
-                       str = ftos(ceil(f * 100));
-                       if(tmp != 0)
-                               str = strcat(str, "~", ftos(ceil(tmp * 100)));
-                       tmp = bound(0, f / 0.2 + tmp / 0.04, 1); // 20% is REALLY BAD pl
-                       hud_field_rgb = '1 0.5 0.5' - '0 0.5 0.5'*tmp;
-                       return str;
-
-               case SP_NAME:
-                       if(ready_waiting && pl.ready)
-                       {
-                               hud_field_icon0 = "gfx/scoreboard/player_ready";
-                       }
-                       else if(!teamplay)
-                       {
-                               f = stof(getplayerkeyvalue(pl.sv_entnum, "colors"));
-                               {
-                                       hud_field_icon0 = "gfx/scoreboard/playercolor_base";
-                                       hud_field_icon1 = "gfx/scoreboard/playercolor_shirt";
-                                       hud_field_icon1_rgb = colormapPaletteColor(floor(f / 16), 0);
-                                       hud_field_icon2 = "gfx/scoreboard/playercolor_pants";
-                                       hud_field_icon2_rgb = colormapPaletteColor(f % 16, 1);
-                               }
-                       }
-                       return entcs_GetName(pl.sv_entnum);
-
-               case SP_FRAGS:
-                       f = pl.(scores[SP_KILLS]);
-                       f -= pl.(scores[SP_SUICIDES]);
-                       return ftos(f);
-
-               case SP_KDRATIO:
-                       num = pl.(scores[SP_KILLS]);
-                       denom = pl.(scores[SP_DEATHS]);
-
-                       if(denom == 0) {
-                               hud_field_rgb = '0 1 0';
-                               str = sprintf("%d", num);
-                       } else if(num <= 0) {
-                               hud_field_rgb = '1 0 0';
-                               str = sprintf("%.1f", num/denom);
-                       } else
-                               str = sprintf("%.1f", num/denom);
-                       return str;
-
-               case SP_SUM:
-                       f = pl.(scores[SP_KILLS]);
-                       f -= pl.(scores[SP_DEATHS]);
-
-                       if(f > 0) {
-                               hud_field_rgb = '0 1 0';
-                       } else if(f == 0) {
-                               hud_field_rgb = '1 1 1';
-                       } else {
-                               hud_field_rgb = '1 0 0';
-                       }
-                       return ftos(f);
-
-               case SP_DMG:
-                       num = pl.(scores[SP_DMG]);
-                       denom = 1000;
-
-                       str = sprintf("%.1f k", num/denom);
-                       return str;
-
-               case SP_DMGTAKEN:
-                       num = pl.(scores[SP_DMGTAKEN]);
-                       denom = 1000;
-
-                       str = sprintf("%.1f k", num/denom);
-                       return str;
-
-               default:
-                       tmp = pl.(scores[field]);
-                       f = scores_flags[field];
-                       if(field == ps_primary)
-                               hud_field_rgb = '1 1 0';
-                       else if(field == ps_secondary)
-                               hud_field_rgb = '0 1 1';
-                       else
-                               hud_field_rgb = '1 1 1';
-                       return ScoreString(f, tmp);
-       }
-       //return "error";
-}
-
-float hud_fixscoreboardcolumnwidth_len;
-float hud_fixscoreboardcolumnwidth_iconlen;
-float hud_fixscoreboardcolumnwidth_marginlen;
-
-string HUD_FixScoreboardColumnWidth(int i, string str)
-{
-    TC(int, i);
-       float field, f;
-       vector sz;
-       field = hud_field[i];
-
-       hud_fixscoreboardcolumnwidth_iconlen = 0;
-
-       if(hud_field_icon0 != "")
-       {
-               sz = draw_getimagesize(hud_field_icon0);
-               f = sz.x / sz.y;
-               if(hud_fixscoreboardcolumnwidth_iconlen < f)
-                       hud_fixscoreboardcolumnwidth_iconlen = f;
-       }
-
-       if(hud_field_icon1 != "")
-       {
-               sz = draw_getimagesize(hud_field_icon1);
-               f = sz.x / sz.y;
-               if(hud_fixscoreboardcolumnwidth_iconlen < f)
-                       hud_fixscoreboardcolumnwidth_iconlen = f;
-       }
-
-       if(hud_field_icon2 != "")
-       {
-               sz = draw_getimagesize(hud_field_icon2);
-               f = sz.x / sz.y;
-               if(hud_fixscoreboardcolumnwidth_iconlen < f)
-                       hud_fixscoreboardcolumnwidth_iconlen = f;
-       }
-
-       hud_fixscoreboardcolumnwidth_iconlen *= hud_fontsize.y / hud_fontsize.x; // fix icon aspect
-
-       if(hud_fixscoreboardcolumnwidth_iconlen != 0)
-               hud_fixscoreboardcolumnwidth_marginlen = stringwidth(" ", false, hud_fontsize);
-       else
-               hud_fixscoreboardcolumnwidth_marginlen = 0;
-
-       if(field == SP_NAME) // name gets all remaining space
-       {
-               int j;
-               float namesize;
-               namesize = sbwidth;// / hud_fontsize_x;
-               for(j = 0; j < hud_num_fields; ++j)
-                       if(j != i)
-                               if (hud_field[i] != SP_SEPARATOR)
-                                       namesize -= hud_size[j] + hud_fontsize.x;
-               namesize += hud_fontsize.x;
-               hud_size[i] = namesize;
-
-               if (hud_fixscoreboardcolumnwidth_iconlen != 0)
-                       namesize -= hud_fixscoreboardcolumnwidth_marginlen + hud_fixscoreboardcolumnwidth_iconlen;
-               str = textShortenToWidth(str, namesize, hud_fontsize, stringwidth_colors);
-               hud_fixscoreboardcolumnwidth_len = stringwidth(str, true, hud_fontsize);
-       }
-       else
-               hud_fixscoreboardcolumnwidth_len = stringwidth(str, false, hud_fontsize);
-
-       f = hud_fixscoreboardcolumnwidth_len + hud_fixscoreboardcolumnwidth_marginlen + hud_fixscoreboardcolumnwidth_iconlen;
-       if(hud_size[i] < f)
-               hud_size[i] = f;
-
-       return str;
-}
-
-void HUD_PrintScoreboardItem(vector pos, vector item_size, entity pl, bool is_self, int pl_number)
-{
-    TC(bool, is_self); TC(int, pl_number);
-       vector tmp, rgb;
-       rgb = Team_ColorRGB(pl.team);
-       string str;
-       int field;
-       float is_spec;
-       is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
-
-       if((rgb == '1 1 1') && (!is_spec)) {
-               rgb.x = autocvar_scoreboard_color_bg_r + 0.5;
-               rgb.y = autocvar_scoreboard_color_bg_g + 0.5;
-               rgb.z = autocvar_scoreboard_color_bg_b + 0.5; }
-
-       vector h_pos = pos - '1 1 0';
-       vector h_size = item_size + '2 0 0';
-       // alternated rows highlighting
-       if(is_self)
-               drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
-       else if((scoreboard_highlight) && (!(pl_number % 2)))
-               drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
-
-       tmp.x = item_size.x;
-       tmp.y = 0;
-       tmp.z = 0;
-       int i;
-       for(i = 0; i < hud_num_fields; ++i)
-       {
-               field = hud_field[i];
-               if(field == SP_SEPARATOR)
-                       break;
-
-               if(is_spec && field != SP_NAME && field != SP_PING) {
-                       pos.x += hud_size[i] + hud_fontsize.x;
-                       continue;
-               }
-               str = HUD_GetField(pl, field);
-               str = HUD_FixScoreboardColumnWidth(i, str);
-
-               pos.x += hud_size[i] + hud_fontsize.x;
-
-               if(field == SP_NAME) {
-                       tmp.x = hud_size[i] - hud_fontsize.x*hud_fixscoreboardcolumnwidth_iconlen - hud_fixscoreboardcolumnwidth_marginlen + hud_fontsize.x;
-                       if (is_self)
-                               drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                       else
-                               drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name, DRAWFLAG_NORMAL);
-               } else {
-                       tmp.x = hud_fixscoreboardcolumnwidth_len + hud_fontsize.x;
-                       if (is_self)
-                               drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                       else
-                               drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name, DRAWFLAG_NORMAL);
-               }
-
-               tmp.x = hud_size[i] + hud_fontsize.x;
-               if(hud_field_icon0 != "")
-                       if (is_self)
-                               drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
-               if(hud_field_icon1 != "")
-                       if (is_self)
-                               drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
-               if(hud_field_icon2 != "")
-                       if (is_self)
-                               drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
-       }
-
-       if(hud_field[i] == SP_SEPARATOR)
-       {
-               pos.x = xmax;
-               for(i = hud_num_fields-1; i > 0; --i)
-               {
-                       field = hud_field[i];
-                       if(field == SP_SEPARATOR)
-                               break;
-
-                       if(is_spec && field != SP_NAME && field != SP_PING) {
-                               pos.x -= hud_size[i] + hud_fontsize.x;
-                               continue;
-                       }
-
-                       str = HUD_GetField(pl, field);
-                       str = HUD_FixScoreboardColumnWidth(i, str);
-
-                       if(field == SP_NAME) {
-                               tmp.x = hud_fixscoreboardcolumnwidth_len; // left or right aligned? let's put it right...
-                               if(is_self)
-                                       drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                               else
-                                       drawcolorcodedstring(pos - tmp, str, hud_fontsize, scoreboard_alpha_name, DRAWFLAG_NORMAL);
-                       } else {
-                               tmp.x = hud_fixscoreboardcolumnwidth_len;
-                               if(is_self)
-                                       drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                               else
-                                       drawstring(pos - tmp, str, hud_fontsize, hud_field_rgb, scoreboard_alpha_name, DRAWFLAG_NORMAL);
-                       }
-
-                       tmp.x = hud_size[i];
-                       if(hud_field_icon0 != "")
-                               if (is_self)
-                                       drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                               else
-                                       drawpic(pos - tmp, hud_field_icon0, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon0_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
-                       if(hud_field_icon1 != "")
-                               if (is_self)
-                                       drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                               else
-                                       drawpic(pos - tmp, hud_field_icon1, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon1_rgb, hud_field_icon1_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
-                       if(hud_field_icon2 != "")
-                               if (is_self)
-                                       drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name_self, DRAWFLAG_NORMAL);
-                               else
-                                       drawpic(pos - tmp, hud_field_icon2, '0 1 0' * hud_fontsize.y + '1 0 0' * hud_fontsize.x * hud_fixscoreboardcolumnwidth_iconlen, hud_field_icon2_rgb, hud_field_icon2_alpha * scoreboard_alpha_name, DRAWFLAG_NORMAL);
-                       pos.x -= hud_size[i] + hud_fontsize.x;
-               }
-       }
-
-       if(pl.eliminated)
-               drawfill(h_pos, h_size, '0 0 0', 0.5, DRAWFLAG_NORMAL);
-}
-
-/*
- * HUD_Scoreboard_MakeTable
- *
- * Makes a table for a team (for all playing players in DM) and fills it
- */
-
-vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
-{
-       float body_table_height;
-       vector tmp = '0 0 0', column_dim = '0 0 0';
-       entity pl;
-
-       body_table_height = 1.25 * hud_fontsize.y * max(1, tm.team_size); // no player? show 1 empty line
-
-       pos.y += autocvar_scoreboard_border_thickness;
-       pos -= '1 1 0';
-
-       tmp.x = sbwidth + 2;
-       tmp.y = 1.25 * hud_fontsize.y;
-
-       // rounded header
-       if (teamplay)
-               drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, (rgb * autocvar_scoreboard_color_bg_team) + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       else
-               drawpic(pos, "gfx/scoreboard/scoreboard_tableheader", tmp, rgb + '0.5 0.5 0.5', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-
-       // table border
-       tmp.y += autocvar_scoreboard_border_thickness;
-       tmp.y += body_table_height;
-       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL); // more transparency for the scoreboard
-
-       // separator header/table
-       pos.y += 1.25 * hud_fontsize.y;
-       tmp.y = autocvar_scoreboard_border_thickness;
-       drawfill(pos, tmp, '0 0 0', scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-
-       pos.y += autocvar_scoreboard_border_thickness;
-
-       // table background
-       tmp.y = body_table_height;
-       if (teamplay)
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       else
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-
-       // anyway, apply some color
-       //drawfill(pos, tmp + '2 0 0', rgb, 0.1, DRAWFLAG_NORMAL);
-
-       // go back to the top to make alternated columns highlighting and to print the strings
-       pos.y -= 1.25 * hud_fontsize.y;
-       pos.y -= autocvar_scoreboard_border_thickness;
-
-       pos += '1 1 0';
-
-       if (scoreboard_highlight)
-       {
-               column_dim.y = 1.25 * hud_fontsize.y; // header
-               column_dim.y += autocvar_scoreboard_border_thickness;
-               column_dim.y += body_table_height;
-       }
-
-       // print the strings of the columns headers and draw the columns
-       int i;
-       for(i = 0; i < hud_num_fields; ++i)
-       {
-               if(hud_field[i] == SP_SEPARATOR)
-                       break;
-               column_dim.x = hud_size[i] + hud_fontsize.x;
-               if (scoreboard_highlight)
-               {
-                       if (i % 2)
-                               drawfill(pos - '0 1 0' - hud_fontsize.x / 2 * '1 0 0', column_dim, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
-               }
-               drawstring(pos, hud_title[i], hud_fontsize, rgb * 1.5, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               pos.x += column_dim.x;
-       }
-       if(hud_field[i] == SP_SEPARATOR)
-       {
-               pos.x = xmax;
-               tmp.y = 0;
-               for(i = hud_num_fields-1; i > 0; --i)
-               {
-                       if(hud_field[i] == SP_SEPARATOR)
-                               break;
-
-                       pos.x -= hud_size[i];
-
-                       if (scoreboard_highlight)
-                       {
-                               if (!(i % 2))
-                               {
-                                       if (i == hud_num_fields-1)
-                                               column_dim.x = hud_size[i] + hud_fontsize.x / 2 + 1;
-                                       else
-                                               column_dim.x = hud_size[i] + hud_fontsize.x;
-                                       drawfill(pos - '0 1 0' - hud_fontsize.x / 2 * '1 0 0', column_dim, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
-                               }
-                       }
-
-                       tmp.x = stringwidth(hud_title[i], false, hud_fontsize);
-                       tmp.x = (hud_size[i] - tmp.x);
-                       drawstring(pos + tmp, hud_title[i], hud_fontsize, rgb * 1.5, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-                       pos.x -= hud_fontsize.x;
-               }
-       }
-
-       pos.x = xmin;
-       pos.y += 1.25 * hud_fontsize.y; // skip the header
-       pos.y += autocvar_scoreboard_border_thickness;
-
-       // item size
-       tmp.x = sbwidth;
-       tmp.y = hud_fontsize.y * 1.25;
-
-       // fill the table and draw the rows
-       i = 0;
-       if (teamplay)
-               for(pl = players.sort_next; pl; pl = pl.sort_next)
-               {
-                       if(pl.team != tm.team)
-                               continue;
-                       HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
-                       pos.y += 1.25 * hud_fontsize.y;
-                       ++i;
-               }
-       else
-               for(pl = players.sort_next; pl; pl = pl.sort_next)
-               {
-                       if(pl.team == NUM_SPECTATOR)
-                               continue;
-                       HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
-                       pos.y += 1.25 * hud_fontsize.y;
-                       ++i;
-               }
-
-       if (i == 0)
-               pos.y += 1.25 * hud_fontsize.y; // move to the end of the table
-       pos.y += 1.25 * hud_fontsize.y; // move empty row (out of the table)
-
-       return pos;
-}
-
-float HUD_WouldDrawScoreboard() {
-       if (QuickMenu_IsOpened())
-               return 0;
-       else if (HUD_Radar_Clickable())
-               return 0;
-       else if (scoreboard_showscores)
-               return 1;
-       else if (intermission == 1)
-               return 1;
-       else if (intermission == 2)
-               return 0;
-       else if (spectatee_status != -1 && STAT(HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != MAPINFO_TYPE_CTS && !active_minigame)
-               return 1;
-       else if (scoreboard_showscores_force)
-               return 1;
-       return 0;
-}
-
-float average_accuracy;
-vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
-{
-       WepSet weapons_stat = WepSet_GetFromStat();
-       WepSet weapons_inmap = WepSet_GetFromStat_InMap();
-       float initial_posx = pos.x;
-       int disownedcnt = 0;
-       FOREACH(Weapons, it != WEP_Null, {
-               int weapon_stats = weapon_accuracy[i - WEP_FIRST];
-
-               WepSet set = it.m_wepset;
-               if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
-                       ++disownedcnt;
-       });
-
-       int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt;
-       if (weapon_cnt <= 0) return pos;
-
-       int rows = 1;
-       if (autocvar_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
-               rows = 2;
-       int columnns = ceil(weapon_cnt / rows);
-
-       float height = 40;
-       float fontsize = height * 1/3;
-       float weapon_height = height * 2/3;
-       float weapon_width = sbwidth / columnns / rows;
-
-       drawstring(pos, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       pos.y += 1.25 * hud_fontsize.y + autocvar_scoreboard_border_thickness;
-       vector tmp = '0 0 0';
-       tmp.x = sbwidth;
-       tmp.y = height * rows;
-
-       if (teamplay)
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       else
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
-
-       // column highlighting
-       for (int i = 0; i < columnns; ++i)
-       {
-               if ((i % 2) == 0)
-                       drawfill(pos + '1 0 0' * weapon_width * rows * i, '0 1 0' * height * rows + '1 0 0' * weapon_width * rows, '0 0 0', scoreboard_alpha_bg * 0.2, DRAWFLAG_NORMAL);
-       }
-
-       // row highlighting
-       for (int i = 0; i < rows; ++i)
-       {
-               drawfill(pos + '0 1 0' * weapon_height + '0 1 0' * height * i, '1 0 0' * sbwidth + '0 1 0' * fontsize, '1 1 1', scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
-       }
-
-       average_accuracy = 0;
-       int weapons_with_stats = 0;
-       if (rows == 2)
-               pos.x += weapon_width / 2;
-
-       if (autocvar_scoreboard_accuracy_nocolors)
-               rgb = '1 1 1';
-       else
-               Accuracy_LoadColors();
-
-       float oldposx = pos.x;
-       vector tmpos = pos;
-
-       int column = 0;
-       FOREACH(Weapons, it != WEP_Null, {
-               int weapon_stats = weapon_accuracy[i - WEP_FIRST];
-
-               WepSet set = it.m_wepset;
-               if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
-                       continue;
-
-               float weapon_alpha;
-               if (weapon_stats >= 0)
-                       weapon_alpha = scoreboard_alpha_fg;
-               else
-                       weapon_alpha = 0.2 * scoreboard_alpha_fg;
-
-               // weapon icon
-               drawpic_aspect_skin(tmpos, it.model2, '1 0 0' * weapon_width + '0 1 0' * weapon_height, '1 1 1', weapon_alpha, DRAWFLAG_NORMAL);
-               // the accuracy
-               if (weapon_stats >= 0) {
-                       weapons_with_stats += 1;
-                       average_accuracy += weapon_stats; // store sum of all accuracies in average_accuracy
-
-                       string s;
-                       s = sprintf("%d%%", weapon_stats*100);
-
-                       float padding;
-                       padding = (weapon_width - stringwidth(s, false, '1 0 0' * fontsize)) / 2; // center the accuracy value
-
-                       if(!autocvar_scoreboard_accuracy_nocolors)
-                               rgb = Accuracy_GetColor(weapon_stats);
-
-                       drawstring(tmpos + '1 0 0' * padding + '0 1 0' * weapon_height, s, '1 1 0' * fontsize, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               }
-               tmpos.x += weapon_width * rows;
-               pos.x += weapon_width * rows;
-               if (rows == 2 && column == columnns - 1) {
-                       tmpos.x = oldposx;
-                       tmpos.y += height;
-                       pos.y += height;
-               }
-               ++column;
-       });
-
-       if (weapons_with_stats)
-               average_accuracy = floor((average_accuracy * 100 / weapons_with_stats) + 0.5);
-
-       pos.y += height;
-       pos.y += 1.25 * hud_fontsize.y;
-       pos.x = initial_posx;
-       return pos;
-}
-
-vector HUD_DrawKeyValue(vector pos, string key, string value) {
-       float px = pos.x;
-       pos.x += hud_fontsize.x * 0.25;
-       drawstring(pos, key, hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       pos.x = xmax - stringwidth(value, false, hud_fontsize) - hud_fontsize.x * 0.25;
-       drawstring(pos, value, hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       pos.x = px;
-       pos.y+= hud_fontsize.y;
-
-       return pos;
-}
-
-vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
-       float stat_secrets_found, stat_secrets_total;
-       float stat_monsters_killed, stat_monsters_total;
-       float rows = 0;
-       string val;
-
-       // get monster stats
-       stat_monsters_killed = STAT(MONSTERS_KILLED);
-       stat_monsters_total = STAT(MONSTERS_TOTAL);
-
-       // get secrets stats
-       stat_secrets_found = STAT(SECRETS_FOUND);
-       stat_secrets_total = STAT(SECRETS_TOTAL);
-
-       // get number of rows
-       if(stat_secrets_total)
-               rows += 1;
-       if(stat_monsters_total)
-               rows += 1;
-
-       // if no rows, return
-       if (!rows)
-               return pos;
-
-       //  draw table header
-       drawstring(pos, _("Map stats:"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       pos.y += 1.25 * hud_fontsize.y + autocvar_scoreboard_border_thickness;
-
-       // draw table
-       vector tmp = '0 0 0';
-       tmp.x = sbwidth;
-       tmp.y = hud_fontsize.y * rows;
-
-       if (teamplay)
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       else
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
-
-       // draw monsters
-       if(stat_monsters_total)
-       {
-               val = sprintf("%d/%d", stat_monsters_killed, stat_monsters_total);
-               pos = HUD_DrawKeyValue(pos, _("Monsters killed:"), val);
-       }
-
-       // draw secrets
-       if(stat_secrets_total)
-       {
-               val = sprintf("%d/%d", stat_secrets_found, stat_secrets_total);
-               pos = HUD_DrawKeyValue(pos, _("Secrets found:"), val);
-       }
-
-       // update position
-       pos.y += 1.25 * hud_fontsize.y;
-       return pos;
-}
-
-
-vector HUD_DrawScoreboardRankings(vector pos, entity pl,  vector rgb, vector bg_size)
-{
-       int i;
-       RANKINGS_RECEIVED_CNT = 0;
-       for (i=RANKINGS_CNT-1; i>=0; --i)
-               if (grecordtime[i])
-                       ++RANKINGS_RECEIVED_CNT;
-
-       if (RANKINGS_RECEIVED_CNT == 0)
-               return pos;
-
-       float is_spec;
-       is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
-       vector hl_rgb;
-       hl_rgb.x = autocvar_scoreboard_color_bg_r + 0.5;
-       hl_rgb.y = autocvar_scoreboard_color_bg_g + 0.5;
-       hl_rgb.z = autocvar_scoreboard_color_bg_b + 0.5;
-
-       pos.y += hud_fontsize.y;
-       drawstring(pos, _("Rankings"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       pos.y += hud_fontsize.y + autocvar_scoreboard_border_thickness;
-       vector tmp = '0 0 0';
-       tmp.x = sbwidth;
-       tmp.y = 1.25 * hud_fontsize.y * RANKINGS_RECEIVED_CNT;
-
-       if (teamplay)
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       else
-               drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
-       drawborderlines(autocvar_scoreboard_border_thickness, pos, tmp, '0 0 0', scoreboard_alpha_bg * 0.75, DRAWFLAG_NORMAL);
-
-       // row highlighting
-       for(i = 0; i<RANKINGS_RECEIVED_CNT; ++i)
-       {
-               string n, p;
-               float t;
-               t = grecordtime[i];
-               if (t == 0)
-                       continue;
-               n = grecordholder[i];
-               p = count_ordinal(i+1);
-               if(grecordholder[i] == entcs_GetName(player_localnum))
-                       drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize.y, hl_rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
-               else if(!(i % 2) && scoreboard_highlight)
-                       drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize.y, hl_rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
-               drawstring(pos, p, '1 1 0' * hud_fontsize.y, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               drawstring(pos + '3 0 0' * hud_fontsize.y, TIME_ENCODED_TOSTRING(t), '1 1 0' * hud_fontsize.y, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               drawcolorcodedstring(pos + '8 0 0' * hud_fontsize.y, n, '1 1 0' * hud_fontsize.y, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               pos.y += 1.25 * hud_fontsize.y;
-       }
-       pos.y += autocvar_scoreboard_border_thickness;
-
-       return pos;
-}
-
-float hud_woulddrawscoreboard_prev;
-float hud_woulddrawscoreboard_change; // "time" at which HUD_WouldDrawScoreboard() changed
-void HUD_DrawScoreboard()
-{
-       if(!autocvar__hud_configure)
-       {
-               float hud_woulddrawscoreboard;
-               hud_woulddrawscoreboard = scoreboard_active;
-               if(hud_woulddrawscoreboard != hud_woulddrawscoreboard_prev) {
-                       hud_woulddrawscoreboard_change = time;
-                       hud_woulddrawscoreboard_prev = hud_woulddrawscoreboard;
-               }
-       
-               if(hud_woulddrawscoreboard) {
-                       if(menu_enabled == 1)
-                               scoreboard_fade_alpha = 1;
-                       float scoreboard_fadeinspeed = autocvar_scoreboard_fadeinspeed;
-                       if (scoreboard_fadeinspeed)
-                               scoreboard_fade_alpha = bound (0, (time - hud_woulddrawscoreboard_change) * scoreboard_fadeinspeed, 1);
-                       else
-                               scoreboard_fade_alpha = 1;
-               }
-               else {
-                       float scoreboard_fadeoutspeed = autocvar_scoreboard_fadeoutspeed;
-                       if (scoreboard_fadeoutspeed)
-                               scoreboard_fade_alpha = bound (0, (1/scoreboard_fadeoutspeed - (time - hud_woulddrawscoreboard_change)) * scoreboard_fadeoutspeed, 1);
-                       else
-                               scoreboard_fade_alpha = 0;
-               }
-
-               if (!scoreboard_fade_alpha)
-                       return;
-       }
-       else
-               scoreboard_fade_alpha = 0;
-
-       if (autocvar_scoreboard_dynamichud)
-               HUD_Scale_Enable();
-       else
-               HUD_Scale_Disable();
-
-       float hud_fade_alpha_save = hud_fade_alpha;
-       if(menu_enabled == 1)
-               hud_fade_alpha = 1;
-       else
-               hud_fade_alpha = scoreboard_fade_alpha * (1 - autocvar__menu_alpha);
-       HUD_Panel_UpdateCvars();
-
-       scoreboard_alpha_bg = autocvar_scoreboard_alpha_bg * panel_fg_alpha;
-       scoreboard_alpha_fg = autocvar_scoreboard_alpha_fg * panel_fg_alpha;
-       scoreboard_highlight = autocvar_scoreboard_highlight;
-       scoreboard_highlight_alpha = autocvar_scoreboard_highlight_alpha * panel_fg_alpha;
-       scoreboard_highlight_alpha_self = autocvar_scoreboard_highlight_alpha_self * panel_fg_alpha;
-       scoreboard_alpha_name = autocvar_scoreboard_alpha_name * panel_fg_alpha;
-       scoreboard_alpha_name_self = autocvar_scoreboard_alpha_name_self * panel_fg_alpha;
-
-       hud_fade_alpha = hud_fade_alpha_save;
-
-       // don't overlap with con_notify
-       if(!autocvar__hud_configure)
-               panel_pos_y = max((autocvar_con_notify * autocvar_con_notifysize), panel_pos_y);
-
-       HUD_Panel_DrawBg(scoreboard_fade_alpha);
-
-       if(panel_bg_padding)
-       {
-               panel_pos += '1 1 0' * panel_bg_padding;
-               panel_size -= '2 2 0' * panel_bg_padding;
-       }
-
-       HUD_UpdatePlayerTeams();
-
-       vector rgb, pos, tmp;
-       entity pl, tm;
-       string str;
-
-       xmin = panel_pos_x;
-       ymin = panel_pos_y;
-
-       xmax = panel_pos_x + panel_size_x;
-       ymax = panel_pos_y + panel_size_y;
-
-       sbwidth = panel_size_x;
-
-       // Initializes position
-       pos.x = xmin;
-       pos.y = ymin;
-       pos.z = 0;
-
-       // Heading
-       vector sb_heading_fontsize;
-       sb_heading_fontsize = hud_fontsize * 2;
-       draw_beginBoldFont();
-       drawstring(pos, _("Scoreboard"), sb_heading_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       draw_endBoldFont();
-
-       pos.y += sb_heading_fontsize.y + hud_fontsize.y * 0.25;
-
-       // Draw the scoreboard
-       vector bg_size = draw_getimagesize("gfx/scoreboard/scoreboard_bg") * ((autocvar_scoreboard_bg_scale > 0) ? autocvar_scoreboard_bg_scale : 0.25);
-
-       if(teamplay)
-       {
-               vector team_score_baseoffset;
-               team_score_baseoffset = eY * (2 * autocvar_scoreboard_border_thickness + hud_fontsize.y) - eX * (autocvar_scoreboard_border_thickness + hud_fontsize.x * 0.25);
-               for(tm = teams.sort_next; tm; tm = tm.sort_next)
-               {
-                       if(tm.team == NUM_SPECTATOR)
-                               continue;
-                       if(!tm.team && teamplay)
-                               continue;
-
-                       draw_beginBoldFont();
-                       rgb = Team_ColorRGB(tm.team);
-                       str = ftos(tm.(teamscores[ts_primary]));
-                       drawstring(pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize * 1.5), str, hud_fontsize * 1.5, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-
-                       if(ts_primary != ts_secondary)
-                       {
-                               str = ftos(tm.(teamscores[ts_secondary]));
-                               drawstring(pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize) + eY * hud_fontsize.y * 1.5, str, hud_fontsize, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-                       }
-                       draw_endBoldFont();
-
-                       pos = HUD_Scoreboard_MakeTable(pos, tm, rgb, bg_size);
-               }
-               rgb.x = autocvar_scoreboard_color_bg_r;
-               rgb.y = autocvar_scoreboard_color_bg_g;
-               rgb.z = autocvar_scoreboard_color_bg_b;
-       }
-       else
-       {
-               rgb.x = autocvar_scoreboard_color_bg_r;
-               rgb.y = autocvar_scoreboard_color_bg_g;
-               rgb.z = autocvar_scoreboard_color_bg_b;
-
-               for(tm = teams.sort_next; tm; tm = tm.sort_next)
-               {
-                       if(tm.team == NUM_SPECTATOR)
-                               continue;
-                       if(!tm.team && teamplay)
-                               continue;
-
-                       pos = HUD_Scoreboard_MakeTable(pos, tm, rgb, bg_size);
-               }
-       }
-
-       if(gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE) {
-               if(race_speedaward) {
-                       drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, race_speedaward_unit, race_speedaward_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-                       pos.y += 1.25 * hud_fontsize.y;
-               }
-               if(race_speedaward_alltimebest) {
-                       drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d%s ^7(%s^7)"), race_speedaward_alltimebest, race_speedaward_alltimebest_unit, race_speedaward_alltimebest_holder), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-                       pos.y += 1.25 * hud_fontsize.y;
-               }
-               pos = HUD_DrawScoreboardRankings(pos, playerslots[player_localnum], rgb, bg_size);
-       }
-       else if (autocvar_scoreboard_accuracy && !warmup_stage && gametype != MAPINFO_TYPE_NEXBALL) {
-               if(teamplay)
-                       pos = HUD_DrawScoreboardAccuracyStats(pos, Team_ColorRGB(myteam), bg_size);
-               else
-                       pos = HUD_DrawScoreboardAccuracyStats(pos, rgb, bg_size);
-       }
-
-
-       if(teamplay)
-               pos = HUD_DrawMapStats(pos, Team_ColorRGB(myteam), bg_size);
-       else
-               pos = HUD_DrawMapStats(pos, rgb, bg_size);
-
-       // List spectators
-       float specs;
-       specs = 0;
-       tmp = pos;
-       vector item_size;
-       item_size.x = sbwidth;
-       item_size.y = hud_fontsize.y * 1.25;
-       item_size.z = 0;
-       for(pl = players.sort_next; pl; pl = pl.sort_next)
-       {
-               if(pl.team != NUM_SPECTATOR)
-                       continue;
-               pos.y += 1.25 * hud_fontsize.y;
-               HUD_PrintScoreboardItem(pos, item_size, pl, (pl.sv_entnum == player_localnum), specs);
-               ++specs;
-       }
-
-       if(specs)
-       {
-               draw_beginBoldFont();
-               drawstring(tmp, _("Spectators"), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               draw_endBoldFont();
-               pos.y += 1.25 * hud_fontsize.y;
-       }
-
-       // Print info string
-       float tl, fl, ll;
-       str = sprintf(_("playing ^3%s^7 on ^2%s^7"), MapInfo_Type_ToText(gametype), shortmapname);
-       tl = STAT(TIMELIMIT);
-       fl = STAT(FRAGLIMIT);
-       ll = STAT(LEADLIMIT);
-       if(gametype == MAPINFO_TYPE_LMS)
-       {
-               if(tl > 0)
-                       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%1.0f minutes^7"), tl));
-               if(fl > 0)
-               {
-                       if(tl > 0)
-                               str = strcat(str, _(" or"));
-                       if(teamplay)
-                       {
-                               str = strcat(str, sprintf(_(" until ^3%s %s^7"), ScoreString(teamscores_flags[ts_primary], fl),
-                                       (teamscores_label[ts_primary] == "score")   ? CTX(_("SCO^points")) :
-                                       (teamscores_label[ts_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
-                                       TranslateScoresLabel(teamscores_label[ts_primary])));
-                       }
-                       else
-                       {
-                               str = strcat(str, sprintf(_(" until ^3%s %s^7"), ScoreString(scores_flags[ps_primary], fl),
-                                       (scores_label[ps_primary] == "score")   ? CTX(_("SCO^points")) :
-                                       (scores_label[ps_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
-                                       TranslateScoresLabel(scores_label[ps_primary])));
-                       }
-               }
-               if(ll > 0)
-               {
-                       if(tl > 0 || fl > 0)
-                               str = strcat(str, _(" or"));
-                       if(teamplay)
-                       {
-                               str = strcat(str, sprintf(_(" until a lead of ^3%s %s^7"), ScoreString(teamscores_flags[ts_primary], ll),
-                                       (teamscores_label[ts_primary] == "score")   ? CTX(_("SCO^points")) :
-                                       (teamscores_label[ts_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
-                                       TranslateScoresLabel(teamscores_label[ts_primary])));
-                       }
-                       else
-                       {
-                               str = strcat(str, sprintf(_(" until a lead of ^3%s %s^7"), ScoreString(scores_flags[ps_primary], ll),
-                                       (scores_label[ps_primary] == "score")   ? CTX(_("SCO^points")) :
-                                       (scores_label[ps_primary] == "fastest") ? CTX(_("SCO^is beaten")) :
-                                       TranslateScoresLabel(scores_label[ps_primary])));
-                       }
-               }
-       }
-
-       pos.y += 1.2 * hud_fontsize.y;
-       drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-
-       // print information about respawn status
-       float respawn_time = STAT(RESPAWN_TIME);
-       if(!intermission)
-       if(respawn_time)
-       {
-               if(respawn_time < 0)
-               {
-                       // a negative number means we are awaiting respawn, time value is still the same
-                       respawn_time *= -1; // remove mark now that we checked it
-                       respawn_time = max(time, respawn_time); // don't show a negative value while the server is respawning the player (lag)
-
-                       str = sprintf(_("^1Respawning in ^3%s^1..."),
-                               (autocvar_scoreboard_respawntime_decimals ?
-                                       count_seconds_decs(respawn_time - time, autocvar_scoreboard_respawntime_decimals)
-                                       :
-                                       count_seconds(respawn_time - time)
-                               )
-                       );
-               }
-               else if(time < respawn_time)
-               {
-                       str = sprintf(_("You are dead, wait ^3%s^7 before respawning"),
-                               (autocvar_scoreboard_respawntime_decimals ?
-                                       count_seconds_decs(respawn_time - time, autocvar_scoreboard_respawntime_decimals)
-                                       :
-                                       count_seconds(respawn_time - time)
-                               )
-                       );
-               }
-               else if(time >= respawn_time)
-                       str = sprintf(_("You are dead, press ^2%s^7 to respawn"), getcommandkey("jump", "+jump"));
-
-               pos.y += 1.2 * hud_fontsize.y;
-               drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-       }
-
-       scoreboard_bottom = pos.y + 2 * hud_fontsize.y;
-}
diff --git a/qcsrc/client/scoreboard.qh b/qcsrc/client/scoreboard.qh
deleted file mode 100644 (file)
index 8fccae9..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-float xmin, xmax, ymin, ymax, sbwidth;
-
-float scoreboard_active;
-float scoreboard_fade_alpha;
-
-void Cmd_HUD_SetFields(float argc);
-void HUD_DrawScoreboard();
-void HUD_InitScores();
-void HUD_UpdatePlayerPos(entity pl);
-void HUD_UpdateTeamPos(entity Team);
-float HUD_WouldDrawScoreboard();
index 47cf9337d9a98e3375aa3dae1e0ed5f706c89f57..fbfb5d57ac2fe860814651e2a7aa498fa001a1fe 100644 (file)
@@ -3,8 +3,8 @@
 #include "announcer.qh"
 #include "hud/all.qh"
 #include "mapvoting.qh"
-#include "scoreboard.qh"
 #include "shownames.qh"
+#include "hud/panel/scoreboard.qh"
 #include "hud/panel/quickmenu.qh"
 
 #include "mutators/events.qh"