]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud/panel/scoreboard.qc
Add a team color setting for team tables so that accuracy and rankings can be display...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / scoreboard.qc
index 4ca9843c8effd0e67604246c62fed31b49b44179..4a7a8b65639a987dbea84b6edfa2177a789f0630 100644 (file)
@@ -15,13 +15,24 @@ bool sbt_highlight;
 float sbt_highlight_alpha;
 float sbt_highlight_alpha_self;
 
-// TODO init autocvars
-float autocvar_hud_panel_scoreboard_table_bg_alpha;
-float autocvar_hud_panel_scoreboard_table_fg_alpha;
-float autocvar_hud_panel_scoreboard_table_fg_alpha_self;
-bool autocvar_hud_panel_scoreboard_table_highlight;
-float autocvar_hud_panel_scoreboard_table_highlight_alpha;
-float autocvar_hud_panel_scoreboard_table_highlight_alpha_self;
+float autocvar_hud_panel_scoreboard_fadeinspeed = 10;
+float autocvar_hud_panel_scoreboard_fadeoutspeed = 5;
+float autocvar_hud_panel_scoreboard_respawntime_decimals = 1;
+float autocvar_hud_panel_scoreboard_table_bg_alpha = 0.7;
+float autocvar_hud_panel_scoreboard_table_bg_scale = 0.25;
+float autocvar_hud_panel_scoreboard_table_fg_alpha = 0.9;
+float autocvar_hud_panel_scoreboard_table_fg_alpha_self = 1;
+bool autocvar_hud_panel_scoreboard_table_highlight = true;
+float autocvar_hud_panel_scoreboard_table_highlight_alpha = 0.2;
+float autocvar_hud_panel_scoreboard_table_highlight_alpha_self = 0.5;
+float autocvar_hud_panel_scoreboard_bg_teams_color_team = 0;
+
+bool autocvar_hud_panel_scoreboard_accuracy = true;
+bool autocvar_hud_panel_scoreboard_accuracy_doublerows = false;
+bool autocvar_hud_panel_scoreboard_accuracy_nocolors = false;
+
+bool autocvar_hud_panel_scoreboard_dynamichud = false;
+
 
 void drawstringright(vector, string, vector, vector, float, float);
 void drawstringcenter(vector, string, vector, vector, float, float);
@@ -71,7 +82,7 @@ string TranslateScoresLabel(string l)
        }
 }
 
-void HUD_InitScores()
+void Scoreboard_InitScores()
 {
        int i, f;
 
@@ -117,7 +128,7 @@ void Scoreboard_UpdatePlayerTeams()
                if(SetTeam(pl, Team))
                {
                        tmp = pl.sort_prev;
-                       HUD_UpdatePlayerPos(pl);
+                       Scoreboard_UpdatePlayerPos(pl);
                        if(tmp)
                                pl = tmp;
                        else
@@ -131,7 +142,7 @@ void Scoreboard_UpdatePlayerTeams()
        */
 }
 
-int HUD_CompareScore(int vl, int vr, int f)
+int Scoreboard_CompareScore(int vl, int vr, int f)
 {
     TC(int, vl); TC(int, vr); TC(int, f);
        if(f & SFL_ZERO_IS_WORST)
@@ -148,7 +159,7 @@ int HUD_CompareScore(int vl, int vr, int f)
        return -1;
 }
 
-float HUD_ComparePlayerScores(entity left, entity right)
+float Scoreboard_ComparePlayerScores(entity left, entity right)
 {
        float vl, vr, r;
        vl = entcs_GetTeam(left.sv_entnum);
@@ -173,18 +184,18 @@ float HUD_ComparePlayerScores(entity left, entity right)
                return false;
        }
 
-       r = HUD_CompareScore(left.scores[ps_primary], right.scores[ps_primary], scores_flags[ps_primary]);
+       r = Scoreboard_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]);
+       r = Scoreboard_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]);
+               r = Scoreboard_CompareScore(left.scores[i], right.scores[i], scores_flags[i]);
                if (r >= 0)
                        return r;
        }
@@ -195,20 +206,20 @@ float HUD_ComparePlayerScores(entity left, entity right)
        return false;
 }
 
-void HUD_UpdatePlayerPos(entity player)
+void Scoreboard_UpdatePlayerPos(entity player)
 {
        entity ent;
-       for(ent = player.sort_next; ent && HUD_ComparePlayerScores(player, ent); ent = player.sort_next)
+       for(ent = player.sort_next; ent && Scoreboard_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)
+       for(ent = player.sort_prev; ent != players && Scoreboard_ComparePlayerScores(ent, player); ent = player.sort_prev)
        {
                SORT_SWAP(ent, player);
        }
 }
 
-float HUD_CompareTeamScores(entity left, entity right)
+float Scoreboard_CompareTeamScores(entity left, entity right)
 {
        int i, r;
 
@@ -217,17 +228,17 @@ float HUD_CompareTeamScores(entity left, entity right)
        if(right.team == NUM_SPECTATOR)
                return 0;
 
-       r = HUD_CompareScore(left.teamscores[ts_primary], right.teamscores[ts_primary], teamscores_flags[ts_primary]);
+       r = Scoreboard_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]);
+       r = Scoreboard_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]);
+               r = Scoreboard_CompareScore(left.teamscores[i], right.teamscores[i], teamscores_flags[i]);
                if (r >= 0)
                        return r;
        }
@@ -238,14 +249,14 @@ float HUD_CompareTeamScores(entity left, entity right)
        return false;
 }
 
-void HUD_UpdateTeamPos(entity Team)
+void Scoreboard_UpdateTeamPos(entity Team)
 {
        entity ent;
-       for(ent = Team.sort_next; ent && HUD_CompareTeamScores(Team, ent); ent = Team.sort_next)
+       for(ent = Team.sort_next; ent && Scoreboard_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)
+       for(ent = Team.sort_prev; ent != teams && Scoreboard_CompareTeamScores(ent, Team); ent = Team.sort_prev)
        {
                SORT_SWAP(ent, Team);
        }
@@ -528,7 +539,7 @@ vector sbt_field_icon2_rgb;
 float sbt_field_icon0_alpha;
 float sbt_field_icon1_alpha;
 float sbt_field_icon2_alpha;
-string HUD_GetField(entity pl, int field)
+string Scoreboard_GetField(entity pl, int field)
 {
     TC(int, field);
        float tmp, num, denom;
@@ -653,7 +664,7 @@ float sbt_fixcolumnwidth_len;
 float sbt_fixcolumnwidth_iconlen;
 float sbt_fixcolumnwidth_marginlen;
 
-string HUD_FixScoreboardColumnWidth(int i, string str)
+string Scoreboard_FixColumnWidth(int i, string str)
 {
     TC(int, i);
        float field, f;
@@ -720,7 +731,54 @@ string HUD_FixScoreboardColumnWidth(int i, string str)
        return str;
 }
 
-void HUD_PrintScoreboardItem(vector item_pos, vector rgb, entity pl, bool is_self, int pl_number)
+vector Scoreboard_DrawHeader(vector pos, vector rgb)
+{
+       int i;
+       vector column_dim = eY * panel_size.y;
+       vector text_offset = eY * (1.25 - 1) / 2 * hud_fontsize.y;
+       for(i = 0; i < sbt_num_fields; ++i)
+       {
+               if(sbt_field[i] == SP_SEPARATOR)
+                       break;
+               column_dim.x = sbt_field_size[i] + hud_fontsize.x;
+               if (sbt_highlight)
+                       if (i % 2)
+                               drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+               drawstring(pos + text_offset, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
+               pos.x += column_dim.x;
+       }
+       if(sbt_field[i] == SP_SEPARATOR)
+       {
+               pos.x = panel_pos.x + panel_size.x;
+               for(i = sbt_num_fields - 1; i > 0; --i)
+               {
+                       if(sbt_field[i] == SP_SEPARATOR)
+                               break;
+
+                       pos.x -= sbt_field_size[i];
+
+                       if (sbt_highlight)
+                               if (!(i % 2))
+                               {
+                                       if (i == sbt_num_fields-1)
+                                               column_dim.x = sbt_field_size[i] + hud_fontsize.x * 0.5;
+                                       else
+                                               column_dim.x = sbt_field_size[i] + hud_fontsize.x;
+                                       drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+                               }
+
+                       text_offset.x = sbt_field_size[i] - stringwidth(sbt_field_title[i], false, hud_fontsize);
+                       drawstring(pos + text_offset, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
+                       pos.x -= hud_fontsize.x;
+               }
+       }
+
+       pos.x = panel_pos.x;
+       pos.y += 1.25 * hud_fontsize.y;
+       return pos;
+}
+
+void Scoreboard_DrawItem(vector item_pos, vector rgb, entity pl, bool is_self, int pl_number)
 {
     TC(bool, is_self); TC(int, pl_number);
        string str;
@@ -739,6 +797,7 @@ void HUD_PrintScoreboardItem(vector item_pos, vector rgb, entity pl, bool is_sel
                drawfill(h_pos, h_size, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
 
        vector pos = item_pos;
+       pos.y += (1.25 - 1) / 2 * hud_fontsize.y; // center text vertically
        vector tmp = '0 0 0';
        int i;
        for(i = 0; i < sbt_num_fields; ++i)
@@ -751,8 +810,8 @@ void HUD_PrintScoreboardItem(vector item_pos, vector rgb, entity pl, bool is_sel
                        pos.x += sbt_field_size[i] + hud_fontsize.x;
                        continue;
                }
-               str = HUD_GetField(pl, field);
-               str = HUD_FixScoreboardColumnWidth(i, str);
+               str = Scoreboard_GetField(pl, field);
+               str = Scoreboard_FixColumnWidth(i, str);
 
                pos.x += sbt_field_size[i] + hud_fontsize.x;
 
@@ -802,8 +861,8 @@ void HUD_PrintScoreboardItem(vector item_pos, vector rgb, entity pl, bool is_sel
                                continue;
                        }
 
-                       str = HUD_GetField(pl, field);
-                       str = HUD_FixScoreboardColumnWidth(i, str);
+                       str = Scoreboard_GetField(pl, field);
+                       str = Scoreboard_FixColumnWidth(i, str);
 
                        if(field == SP_NAME) {
                                tmp.x = sbt_fixcolumnwidth_len; // left or right aligned? let's put it right...
@@ -843,9 +902,8 @@ void HUD_PrintScoreboardItem(vector item_pos, vector rgb, entity pl, bool is_sel
                drawfill(h_pos, h_size, '0 0 0', 0.5 * panel_fg_alpha, DRAWFLAG_NORMAL);
 }
 
-vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
+vector Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
 {
-       vector column_dim = '0 0 0';
        entity pl;
 
        panel_pos = pos;
@@ -875,75 +933,18 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
        if (sbt_bg_alpha)
                drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, sbt_bg_alpha, DRAWFLAG_NORMAL);
 
-       // go back to the top to make alternated columns highlighting and to print the strings
-       pos.y -= 1.25 * hud_fontsize.y;
-
-       if (sbt_highlight)
-               column_dim.y = panel_size.y;
-
-       // print the strings of the columns headers and draw the columns
-       int i;
-       for(i = 0; i < sbt_num_fields; ++i)
-       {
-               if(sbt_field[i] == SP_SEPARATOR)
-                       break;
-               column_dim.x = sbt_field_size[i] + hud_fontsize.x;
-               if (sbt_highlight)
-               {
-                       if (i % 2)
-                               drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
-               }
-               drawstring(pos, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
-               pos.x += column_dim.x;
-       }
-       if(sbt_field[i] == SP_SEPARATOR)
-       {
-               pos.x = panel_pos.x + panel_size.x;
-               tmp.y = 0;
-               for(i = sbt_num_fields - 1; i > 0; --i)
-               {
-                       if(sbt_field[i] == SP_SEPARATOR)
-                               break;
-
-                       pos.x -= sbt_field_size[i];
 
-                       if (sbt_highlight)
-                       {
-                               if (!(i % 2))
-                               {
-                                       if (i == sbt_num_fields-1)
-                                               column_dim.x = sbt_field_size[i] + hud_fontsize.x * 0.5;
-                                       else
-                                               column_dim.x = sbt_field_size[i] + hud_fontsize.x;
-                                       if(i == sbt_num_fields - 1)
-                                               drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
-                                       else
-                                               drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
-                               }
-                       }
-
-                       tmp.x = stringwidth(sbt_field_title[i], false, hud_fontsize);
-                       tmp.x = (sbt_field_size[i] - tmp.x);
-                       drawstring(pos + tmp, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL);
-                       pos.x -= hud_fontsize.x;
-               }
-       }
-
-       pos.x = panel_pos.x;
-       pos.y += 1.25 * hud_fontsize.y; // skip the header
-
-       // item size
-       tmp.x = panel_size.x;
-       tmp.y = hud_fontsize.y * 1.25;
+       // print header row and highlight columns
+       pos = Scoreboard_DrawHeader(panel_pos, rgb);
 
        // fill the table and draw the rows
-       i = 0;
+       int i = 0;
        if (teamplay)
                for(pl = players.sort_next; pl; pl = pl.sort_next)
                {
                        if(pl.team != tm.team)
                                continue;
-                       HUD_PrintScoreboardItem(pos, rgb, pl, (pl.sv_entnum == player_localnum), i);
+                       Scoreboard_DrawItem(pos, rgb, pl, (pl.sv_entnum == player_localnum), i);
                        pos.y += 1.25 * hud_fontsize.y;
                        ++i;
                }
@@ -952,7 +953,7 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
                {
                        if(pl.team == NUM_SPECTATOR)
                                continue;
-                       HUD_PrintScoreboardItem(pos, rgb, pl, (pl.sv_entnum == player_localnum), i);
+                       Scoreboard_DrawItem(pos, rgb, pl, (pl.sv_entnum == player_localnum), i);
                        pos.y += 1.25 * hud_fontsize.y;
                        ++i;
                }
@@ -961,7 +962,7 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
        return end_pos;
 }
 
-float HUD_WouldDrawScoreboard() {
+float Scoreboard_WouldDraw() {
        if (QuickMenu_IsOpened())
                return 0;
        else if (HUD_Radar_Clickable())
@@ -980,7 +981,7 @@ float HUD_WouldDrawScoreboard() {
 }
 
 float average_accuracy;
-vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
+vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
 {
        WepSet weapons_stat = WepSet_GetFromStat();
        WepSet weapons_inmap = WepSet_GetFromStat_InMap();
@@ -997,7 +998,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
        if (weapon_cnt <= 0) return pos;
 
        int rows = 1;
-       if (autocvar_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
+       if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
                rows = 2;
        int columnns = ceil(weapon_cnt / rows);
 
@@ -1030,21 +1031,24 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
        if (sbt_bg_alpha)
                drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, sbt_bg_alpha, DRAWFLAG_NORMAL);
 
-       // column highlighting
-       for (int i = 0; i < columnns; ++i)
-               if ((i % 2) == 0)
-                       drawfill(pos + eX * weapon_width * rows * i, eY * height * rows + eX * weapon_width * rows, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
-
-       // row highlighting
-       for (int i = 0; i < rows; ++i)
-               drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * fontsize, '1 1 1', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+       if(sbt_highlight)
+       {
+               // column highlighting
+               for (int i = 0; i < columnns; ++i)
+                       if ((i % 2) == 0)
+                               drawfill(pos + eX * weapon_width * rows * i, eY * height * rows + eX * weapon_width * rows, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+
+               // row highlighting
+               for (int i = 0; i < rows; ++i)
+                       drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * fontsize, '1 1 1', sbt_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)
+       if (autocvar_hud_panel_scoreboard_accuracy_nocolors)
                rgb = '1 1 1';
        else
                Accuracy_LoadColors();
@@ -1079,7 +1083,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
                        float padding;
                        padding = (weapon_width - stringwidth(s, false, eX * fontsize)) / 2; // center the accuracy value
 
-                       if(!autocvar_scoreboard_accuracy_nocolors)
+                       if(!autocvar_hud_panel_scoreboard_accuracy_nocolors)
                                rgb = Accuracy_GetColor(weapon_stats);
 
                        drawstring(tmpos + eX * padding + eY * weapon_height, s, '1 1 0' * fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
@@ -1101,7 +1105,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
        return end_pos;
 }
 
-vector HUD_DrawKeyValue(vector pos, string key, string value) {
+vector MapStats_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', sbt_fg_alpha, DRAWFLAG_NORMAL);
@@ -1113,7 +1117,7 @@ vector HUD_DrawKeyValue(vector pos, string key, string value) {
        return pos;
 }
 
-vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
+vector Scoreboard_MapStats_Draw(vector pos, vector rgb, vector bg_size) {
        float stat_secrets_found, stat_secrets_total;
        float stat_monsters_killed, stat_monsters_total;
        float rows = 0;
@@ -1122,10 +1126,14 @@ vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
        // get monster stats
        stat_monsters_killed = STAT(MONSTERS_KILLED);
        stat_monsters_total = STAT(MONSTERS_TOTAL);
+       stat_monsters_killed = 14;
+       stat_monsters_total = 22;
 
        // get secrets stats
        stat_secrets_found = STAT(SECRETS_FOUND);
        stat_secrets_total = STAT(SECRETS_TOTAL);
+       stat_secrets_found = 5;
+       stat_secrets_total = 7;
 
        // get number of rows
        if(stat_secrets_total)
@@ -1165,14 +1173,14 @@ vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
        if(stat_monsters_total)
        {
                val = sprintf("%d/%d", stat_monsters_killed, stat_monsters_total);
-               pos = HUD_DrawKeyValue(pos, _("Monsters killed:"), val);
+               pos = MapStats_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);
+               pos = MapStats_DrawKeyValue(pos, _("Secrets found:"), val);
        }
 
        panel_size.x += panel_bg_padding * 2; // restore initial width
@@ -1180,7 +1188,7 @@ vector HUD_DrawMapStats(vector pos, vector rgb, vector bg_size) {
 }
 
 
-vector HUD_DrawScoreboardRankings(vector pos, entity pl, vector rgb, vector bg_size)
+vector Scoreboard_Rankings_Draw(vector pos, entity pl, vector rgb, vector bg_size)
 {
        int i;
        RANKINGS_RECEIVED_CNT = 0;
@@ -1241,32 +1249,23 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl, vector rgb, vector bg_s
        return end_pos;
 }
 
-float hud_woulddrawscoreboard_prev;
-float hud_woulddrawscoreboard_change; // "time" at which HUD_WouldDrawScoreboard() changed
-void HUD_DrawScoreboard()
+void Scoreboard_Draw()
 {
        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(scoreboard_active) {
                        if(menu_enabled == 1)
                                scoreboard_fade_alpha = 1;
-                       float scoreboard_fadeinspeed = autocvar_scoreboard_fadeinspeed;
+                       float scoreboard_fadeinspeed = autocvar_hud_panel_scoreboard_fadeinspeed;
                        if (scoreboard_fadeinspeed)
-                               scoreboard_fade_alpha = bound (0, (time - hud_woulddrawscoreboard_change) * scoreboard_fadeinspeed, 1);
+                               scoreboard_fade_alpha = min(1, scoreboard_fade_alpha + frametime * scoreboard_fadeinspeed);
                        else
                                scoreboard_fade_alpha = 1;
                }
                else {
-                       float scoreboard_fadeoutspeed = autocvar_scoreboard_fadeoutspeed;
+                       float scoreboard_fadeoutspeed = autocvar_hud_panel_scoreboard_fadeoutspeed;
                        if (scoreboard_fadeoutspeed)
-                               scoreboard_fade_alpha = bound (0, (1/scoreboard_fadeoutspeed - (time - hud_woulddrawscoreboard_change)) * scoreboard_fadeoutspeed, 1);
+                               scoreboard_fade_alpha = max(0, scoreboard_fade_alpha - frametime * scoreboard_fadeoutspeed);
                        else
                                scoreboard_fade_alpha = 0;
                }
@@ -1277,7 +1276,7 @@ void HUD_DrawScoreboard()
        else
                scoreboard_fade_alpha = 0;
 
-       if (autocvar_scoreboard_dynamichud)
+       if (autocvar_hud_panel_scoreboard_dynamichud)
                HUD_Scale_Enable();
        else
                HUD_Scale_Disable();
@@ -1289,7 +1288,7 @@ void HUD_DrawScoreboard()
                hud_fade_alpha = scoreboard_fade_alpha * (1 - autocvar__menu_alpha);
        HUD_Panel_UpdateCvars();
 
-       sbt_bg_alpha = autocvar_hud_panel_scoreboard_table_bg_alpha;
+       sbt_bg_alpha = autocvar_hud_panel_scoreboard_table_bg_alpha * panel_fg_alpha;
        sbt_highlight = autocvar_hud_panel_scoreboard_table_highlight;
        sbt_highlight_alpha = autocvar_hud_panel_scoreboard_table_highlight_alpha * panel_fg_alpha;
        sbt_highlight_alpha_self = autocvar_hud_panel_scoreboard_table_highlight_alpha_self * panel_fg_alpha;
@@ -1322,10 +1321,14 @@ void HUD_DrawScoreboard()
        pos.y += panel_bg_border;
 
        // Draw the scoreboard
-       vector bg_size = draw_getimagesize("gfx/scoreboard/scoreboard_bg") * ((autocvar_scoreboard_bg_scale > 0) ? autocvar_scoreboard_bg_scale : 0.25);
+       float scale = autocvar_hud_panel_scoreboard_table_bg_scale;
+       if(scale <= 0)
+               scale = 0.25;
+       vector bg_size = draw_getimagesize("gfx/scoreboard/scoreboard_bg") * scale;
 
        if(teamplay)
        {
+               vector panel_bg_color_save = panel_bg_color;
                vector team_score_baseoffset = eY * hud_fontsize.y - eX * (panel_bg_border + hud_fontsize.x * 0.5);
                for(tm = teams.sort_next; tm; tm = tm.sort_next)
                {
@@ -1345,11 +1348,15 @@ void HUD_DrawScoreboard()
                                drawstring(pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize) + eY * hud_fontsize.y * 1.5, str, hud_fontsize, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
                        }
                        draw_endBoldFont();
-
-                       panel_bg_color = rgb * panel_bg_color_team;
-                       pos = HUD_Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
+                       if(autocvar_hud_panel_scoreboard_bg_teams_color_team > 0)
+                               panel_bg_color = rgb * autocvar_hud_panel_scoreboard_bg_teams_color_team;
+                       else if(panel_bg_color_team > 0)
+                               panel_bg_color = rgb * panel_bg_color_team;
+                       else
+                               panel_bg_color = rgb;
+                       pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
                }
-               panel_bg_color = Team_ColorRGB(myteam) * panel_bg_color_team;
+               panel_bg_color = panel_bg_color_save;
        }
        else
        {
@@ -1360,7 +1367,7 @@ void HUD_DrawScoreboard()
                        if(!tm.team && teamplay)
                                continue;
 
-                       pos = HUD_Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
+                       pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
                }
        }
 
@@ -1373,13 +1380,12 @@ void HUD_DrawScoreboard()
                        drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d%s ^7(%s^7)"), race_speedaward_alltimebest, race_speedaward_alltimebest_unit, race_speedaward_alltimebest_holder), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
                        pos.y += 1.25 * hud_fontsize.y;
                }
-               pos = HUD_DrawScoreboardRankings(pos, playerslots[player_localnum], panel_bg_color, bg_size);
-       }
-       else if (autocvar_scoreboard_accuracy && !warmup_stage && gametype != MAPINFO_TYPE_NEXBALL) {
-               pos = HUD_DrawScoreboardAccuracyStats(pos, panel_bg_color, bg_size);
+               pos = Scoreboard_Rankings_Draw(pos, playerslots[player_localnum], panel_bg_color, bg_size);
        }
+       else if (autocvar_hud_panel_scoreboard_accuracy && !warmup_stage && gametype != MAPINFO_TYPE_NEXBALL)
+               pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
 
-       pos = HUD_DrawMapStats(pos, panel_bg_color, bg_size);
+       pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size);
 
        // List spectators
        float specs = 0;
@@ -1389,7 +1395,7 @@ void HUD_DrawScoreboard()
                if(pl.team != NUM_SPECTATOR)
                        continue;
                pos.y += 1.25 * hud_fontsize.y;
-               HUD_PrintScoreboardItem(pos, panel_bg_color, pl, (pl.sv_entnum == player_localnum), specs);
+               Scoreboard_DrawItem(pos, panel_bg_color, pl, (pl.sv_entnum == player_localnum), specs);
                ++specs;
        }
 
@@ -1471,8 +1477,8 @@ void HUD_DrawScoreboard()
                        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)
+                               (autocvar_hud_panel_scoreboard_respawntime_decimals ?
+                                       count_seconds_decs(respawn_time - time, autocvar_hud_panel_scoreboard_respawntime_decimals)
                                        :
                                        count_seconds(respawn_time - time)
                                )
@@ -1481,8 +1487,8 @@ void HUD_DrawScoreboard()
                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)
+                               (autocvar_hud_panel_scoreboard_respawntime_decimals ?
+                                       count_seconds_decs(respawn_time - time, autocvar_hud_panel_scoreboard_respawntime_decimals)
                                        :
                                        count_seconds(respawn_time - time)
                                )