]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/hud/panel/scoreboard.qc
New medals
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / scoreboard.qc
index c863d11153fd43ba03a91011c5c0f3b59eff93f3..0fcb5c5608ec68e370278364818bd3b5053e8bda 100644 (file)
@@ -1,19 +1,19 @@
 #include "scoreboard.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/main.qh>
 #include <client/miscfunctions.qh>
+#include <client/hud/panel/racetimer.qh>
 #include "quickmenu.qh"
 #include <common/ent_cs.qh>
 #include <common/constants.qh>
-#include <common/gamemodes/_mod.qh>
 #include <common/net_linked.qh>
 #include <common/mapinfo.qh>
 #include <common/minigames/cl_minigames.qh>
 #include <common/scores.qh>
 #include <common/stats.qh>
 #include <common/teams.qh>
+#include <common/items/inventory.qh>
 
 // Scoreboard (#24)
 
@@ -46,6 +46,11 @@ string autocvar_hud_fontsize;
 string hud_fontsize_str;
 float max_namesize;
 
+vector duel_score_fontsize;
+vector duel_name_fontsize;
+vector duel_score_size;
+int total_medals;
+
 float sbt_bg_alpha;
 float sbt_fg_alpha;
 float sbt_fg_alpha_self;
@@ -430,6 +435,10 @@ void Cmd_Scoreboard_SetFields(int argc)
        sbt_num_fields = 0;
 
        hud_fontsize = HUD_GetFontsize("hud_fontsize");
+       
+       duel_score_fontsize = hud_fontsize * 3;
+       duel_name_fontsize = hud_fontsize * 1.5;
+       duel_score_size = vec2(duel_score_fontsize.x * 1.5, duel_score_fontsize.y * 1.25);
 
        for(i = 1; i < argc - 1; ++i)
        {
@@ -618,8 +627,13 @@ string Scoreboard_GetField(entity pl, PlayerScoreField field)
                        f = pl.ping;
                        if(f == 0)
                                return _("N/A");
-                       tmp = max(0, min(220, f-80)) / 220;
-                       sbt_field_rgb = '1 1 1' - '0 1 1' * tmp;
+                       if(f < 80) {
+                               tmp = max(0, min(60, f-20)) / 60; // 20-80 range is green
+                               sbt_field_rgb = '0 1 0' + '1 0 1' * tmp;
+                       } else {
+                               tmp = max(0, min(220, f-80)) / 220; // 80-300 range is red
+                               sbt_field_rgb = '1 1 1' - '0 1 1' * tmp;
+                       }
                        return ftos(f);
 
                case SP_PL:
@@ -1042,6 +1056,263 @@ vector Scoreboard_DrawOthers(vector item_pos, vector rgb, int this_team, entity
        return vec2(item_pos.x, item_pos.y + i * hud_fontsize.y * 1.25);
 }
 
+vector Scoreboard_DrawMedal(vector pos, string icon, float height, float number)
+{
+       if(!number) return pos;
+       total_medals += number;
+       
+       vector tmp_sz, tmp_sz2;
+       tmp_sz = draw_getimagesize(icon);
+       tmp_sz2 = vec2(height*(tmp_sz.x/tmp_sz.y), height);
+       string val = ftos(number);
+       
+       drawpic(pos, icon, tmp_sz2, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.x += tmp_sz2.x + hud_fontsize.x * 0.25;
+       drawstring(pos + eY * ((tmp_sz2.y - hud_fontsize.y) / 2), val, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.x += stringwidth(val, false, hud_fontsize) + hud_fontsize.x * 0.5;
+       return pos;
+}
+
+vector Scoreboard_Duel_DrawPickup(vector pos, bool skinned, string icon, vector sz, float number, bool invert)
+{
+       vector tmp_in = pos;
+       vector tmp_sz, tmp_sz2;
+       string picpath;
+       
+       // Icon
+       if(skinned) {
+               picpath = strcat(hud_skin_path, "/", icon);
+               if(precache_pic(picpath) == "")
+                       picpath = strcat("gfx/hud/default/", icon);
+       } else {
+               picpath = icon;
+       }
+               
+       tmp_sz = draw_getimagesize(picpath);
+       tmp_sz2 = vec2(sz.y*(tmp_sz.x/tmp_sz.y), sz.y);
+       
+       tmp_in.x = pos.x + ((sz.x - tmp_sz2.x) / 2);
+       drawpic(tmp_in, picpath, tmp_sz2, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       // Number
+       if(invert)
+               tmp_in.x += tmp_sz2.x + hud_fontsize.x * 0.25;
+       else
+               tmp_in.x -= hud_fontsize.x * 0.25 + hud_fontsize.x;
+       tmp_in.y += (tmp_sz2.y - hud_fontsize.y) / 2;
+       drawstring(tmp_in, ftos(number), hud_fontsize, (number ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.y += sz.y * 1.1;
+       return pos;
+}
+
+void Scoreboard_Duel_DrawTable(vector pos, bool invert, entity pl, entity tm)
+{
+       vector tmp, tmp_in, tmp_sz, tmp_acc;
+       string tmp_str;
+       float sz;
+       float average_acc = 0;
+       
+       panel_pos = pos;
+       
+       HUD_Panel_DrawBg();
+       
+       // Stop here if there are no scores available
+       if(pl.team != tm.team) return;
+       
+       tmp = pos;
+       tmp.x += panel_bg_padding;
+       tmp.y += panel_bg_padding;
+       panel_size.x -= panel_bg_padding * 2;
+       
+       //if (sbt_bg_alpha)
+       //      drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", tmp, panel_size, rgb, sbt_bg_alpha, DRAWFLAG_NORMAL);
+
+       // Score: highlight
+       if(invert) { tmp.x += panel_size.x; tmp.x -= duel_score_size.x; }
+       drawfill(tmp, duel_score_size, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+       
+       // Score: text
+       tmp_str = ftos(pl.(scores(SP_SCORE)));
+       tmp_in = tmp;
+       tmp_in.x += (duel_score_size.x / 2) - (stringwidth(tmp_str, true, duel_score_fontsize) / 2);
+       tmp_in.y += (duel_score_size.y / 2) - (duel_score_fontsize.y / 2);
+       
+       draw_beginBoldFont();
+       drawstring(tmp_in, tmp_str, duel_score_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       draw_endBoldFont();
+       
+       // Player name
+       tmp_str = Scoreboard_GetField(pl, SP_NAME);
+       tmp_in = tmp;
+       if(invert)
+               tmp_in.x -= stringwidth_colors(tmp_str, duel_name_fontsize) + duel_name_fontsize.x * 0.5;
+       else
+               tmp_in.x += duel_score_size.x + duel_name_fontsize.x * 0.5;
+       tmp_in.y += (duel_score_size.y / 2) - (duel_name_fontsize.y / 2);
+       drawcolorcodedstring(tmp_in, tmp_str, duel_name_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       // Header
+       float column_width = panel_size.x / 5;
+       tmp.x = pos.x + panel_bg_padding;
+       tmp.y += hud_fontsize.y * 3 + hud_fontsize.y;
+       
+       vector column_dim;
+       int i;
+
+       i = (invert ? 4 : 0);
+       column_dim = vec2(column_width * 4, hud_fontsize.y);
+       
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("kills", false, hud_fontsize) / 2),
+               "kills", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("dmg", false, hud_fontsize) / 2),
+               "dmg", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("acc", false, hud_fontsize) / 2),
+               "acc", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("hits", false, hud_fontsize) / 2),
+               "hits", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth("ping", false, hud_fontsize) / 2),
+               "ping", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       tmp.x = pos.x + panel_bg_padding;
+       tmp.y += hud_fontsize.y;
+       
+       // Main row
+       i = (invert ? 4 : 0);
+       
+       tmp_str = ftos(pl.(scores(SP_KILLS)));
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+               tmp_str, hud_fontsize  * 1.25, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       tmp_str = ftos(pl.(scores(SP_DMG)));
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+               tmp_str, hud_fontsize  * 1.25, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               
+       tmp_acc = tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2);
+               
+       if(invert)
+               i--;
+       else
+               i++;
+       
+       tmp_str = Scoreboard_GetField(pl, SP_PING);
+       drawstring(tmp + eX * column_width * (invert ? i-- : i++) + (eX * column_width / 2) - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+               tmp_str, hud_fontsize * 1.25, sbt_field_rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       tmp.x = pos.x + panel_bg_padding;
+       tmp.y += hud_fontsize.y * 2;
+       
+       tmp_in = tmp;
+       
+       int total_weapons = 0;
+       
+       // Accuracy rows
+       WepSet weapons_inmap = WepSet_GetFromStat_InMap();
+       FOREACH(Weapons, it != WEP_Null, {
+               WepSet set = it.m_wepset;
+               if (!(weapons_inmap & set))
+                       continue;
+               if (it.spawnflags & WEP_TYPE_OTHER)
+                       continue;
+               
+               int weapon_cnt_fired = pl.accuracy_cnt_fired[i - WEP_FIRST];
+               int weapon_cnt_hit   = pl.accuracy_cnt_hit[i - WEP_FIRST];
+               int weapon_acc = floor((weapon_cnt_hit / weapon_cnt_fired) * 100);
+               average_acc += weapon_acc;
+               
+               string draw_str;
+               
+               // weapon stats
+               int c = (invert ? 4 : 0);
+               
+               drawfill(tmp_in + eX * column_width * (invert ? 1 : 0), column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+               
+               draw_str = ftos(pl.accuracy_frags[i - WEP_FIRST]);
+               drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * ((column_width - stringwidth(draw_str, false, hud_fontsize)) / 2),
+                       draw_str, hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
+               
+               draw_str = ftos(pl.accuracy_hit[i - WEP_FIRST]);
+               drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * ((column_width - stringwidth(draw_str, false, hud_fontsize)) / 2),
+                       draw_str, hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
+                       
+               draw_str = sprintf("%d%%", weapon_acc);
+               drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * ((column_width - stringwidth(draw_str, false, hud_fontsize)) / 2),
+                       draw_str, hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
+                       
+               draw_str = strcat(ftos(weapon_cnt_hit), " / ", ftos(weapon_cnt_fired));
+               drawstring(tmp_in + eX * column_width * (invert ? c-- : c++) + eX * (column_width / 2) - eX * stringwidth("36 /", false, hud_fontsize),
+                       draw_str,hud_fontsize, (weapon_cnt_fired ? '1 1 1' : '0.5 0.5 0.5'), panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+               // weapon icon
+               if(invert) {
+                       tmp_in.x = pos.x + panel_size.x - panel_bg_padding - hud_fontsize.x / 2;
+                       drawpic_aspect_skin(tmp_in, it.model2, vec2(50, hud_fontsize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               }
+               
+               tmp_in.x = pos.x + panel_bg_padding;
+               tmp_in.y += hud_fontsize.y * 1.25;
+               
+               if(weapon_cnt_fired)
+                       total_weapons++;
+       });
+       average_acc = floor((average_acc / total_weapons) + 0.5);
+       
+       // draw total accuracy now
+       tmp_str = sprintf("%d%%", average_acc);
+       drawstring(tmp_acc - eX * (stringwidth(tmp_str, false, hud_fontsize * 1.25) / 2),
+               tmp_str, hud_fontsize * 1.25, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       // Icon column
+       vector icon_sz = vec2(column_width, hud_fontsize.y*1.5);
+       
+       if(!invert)
+               tmp.x += column_width * 4;
+       // Medal rows
+       drawstring(tmp + eX * ((column_width - stringwidth("medals", false, hud_fontsize)) / 2),
+               "medals", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       tmp.y += hud_fontsize.y * 1.25;
+       
+       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/humiliation", icon_sz, pl.(scores(SP_MEDAL_HUMILIATION)), invert);
+       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/impressive", icon_sz, pl.(scores(SP_MEDAL_IMPRESSIVE)), invert);
+       tmp = Scoreboard_Duel_DrawPickup(tmp, false, "gfx/medal/excellent", icon_sz, pl.(scores(SP_MEDAL_EXCELLENT)), invert);
+       
+       // Item rows
+       drawstring(tmp + eX * ((column_width - stringwidth("items", false, hud_fontsize)) / 2),
+               "items", hud_fontsize, '0.5 0.5 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       tmp.y += hud_fontsize.y * 1.25;
+
+       FOREACH(Items,
+               it.m_id == ITEM_ArmorMega.m_id ||
+               it.m_id == ITEM_HealthMega.m_id ||
+               it.m_id == ITEM_ArmorBig.m_id, {
+               tmp = Scoreboard_Duel_DrawPickup(tmp, true, it.m_icon, icon_sz, inventoryslots[pl.sv_entnum].inv_items[it.m_id], invert);
+               
+               if(it.m_id == REGISTRY_MAX(Items))
+               break;
+       });
+}
+vector Scoreboard_MakeDuelTable(vector pos, entity tm, vector rgb, vector bg_size)
+{
+       vector end_pos = pos;
+       float screen_half = panel_size.x / 2;
+       float weapon_margin = hud_fontsize.x;
+       
+       panel_size.x = screen_half - weapon_margin;
+       panel_size.y = (duel_score_size.y * 5.5);
+       
+       entity pl_left = players.sort_next;
+       entity pl_right = pl_left.sort_next;
+       
+       Scoreboard_Duel_DrawTable(pos, true, pl_left, tm);
+       Scoreboard_Duel_DrawTable(pos + eX * screen_half + eX * weapon_margin, false, pl_right, tm);
+       
+       end_pos.y += panel_size.y + (panel_bg_padding * 2);
+       panel_size.x = screen_half * 2;
+       return end_pos;
+}
+
 vector Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_size)
 {
        int max_players = 999;
@@ -1157,6 +1428,41 @@ bool Scoreboard_WouldDraw()
        return false;
 }
 
+vector Scoreboard_MedalStats_Draw(vector pos)
+{
+       vector orig = pos;
+       float height = hud_fontsize.y * 2;
+       
+       entity pl = playerslots[current_player];
+       
+       vector title_pos = pos;
+       pos.x += 0.5 * hud_fontsize.x + panel_bg_padding;
+       pos.y += 1.25 * hud_fontsize.y;
+       
+       total_medals = 0;
+       
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/airshot",            height, pl.(scores(SP_MEDAL_AIRSHOT)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/assist",             height, pl.(scores(SP_MEDAL_ASSIST)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/damage",             height, pl.(scores(SP_MEDAL_DAMAGE)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/defense",            height, pl.(scores(SP_MEDAL_DEFENSE)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/electrobitch",       height, pl.(scores(SP_MEDAL_ELECTROBITCH)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/excellent",          height, pl.(scores(SP_MEDAL_EXCELLENT)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/firstblood",         height, pl.(scores(SP_MEDAL_FIRSTBLOOD)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/headshot",           height, pl.(scores(SP_MEDAL_HEADSHOT)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/humiliation",        height, pl.(scores(SP_MEDAL_HUMILIATION)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/impressive",         height, pl.(scores(SP_MEDAL_IMPRESSIVE)));
+       pos = Scoreboard_DrawMedal(pos, "gfx/medal/yoda",                       height, pl.(scores(SP_MEDAL_YODA)));
+       
+       if(!total_medals) return orig;
+       
+       drawstring(title_pos, sprintf(_("Medal stats (total %d)"), total_medals),
+               hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.x = orig.x;
+       pos.y += height + hud_fontsize.y * 0.5;
+       return pos;
+}
+
 float average_accuracy;
 vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
 {
@@ -1505,7 +1811,7 @@ float scoreboard_time;
 bool have_weapon_stats;
 bool Scoreboard_AccuracyStats_WouldDraw(float ypos)
 {
-       if (ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || ISGAMETYPE(NEXBALL))
+       if (MUTATOR_CALLHOOK(DrawScoreboardAccuracy))
                return false;
        if (!autocvar_hud_panel_scoreboard_accuracy || warmup_stage || ypos > 0.91 * vid_conheight)
                return false;
@@ -1614,12 +1920,32 @@ void Scoreboard_Draw()
        sb_gameinfo_type_fontsize = hud_fontsize * 2.5;
        sb_gameinfo_detail_fontsize = hud_fontsize * 1.3;
 
+       // z411 server name
+       //drawcolorcodedstring(pos, "bienvenidoainternet.org", sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+       //drawpic_aspect(pos + '1 0 0' * (panel_size.x - 150), "gfx/bai_logo", vec2(150, sb_gameinfo_type_fontsize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       //pos.y += sb_gameinfo_type_fontsize.y;
+       
        // Game Info: Game Type
        str = MapInfo_Type_ToText(gametype);
+       
        draw_beginBoldFont();
-       drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_type_fontsize)), str, sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+       //drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_type_fontsize)), str, sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawcolorcodedstring(pos, str, sb_gameinfo_type_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
        draw_endBoldFont();
+       
+       vector tmp_old_sz = draw_getimagesize("gfx/bai_logo");
+       float tmp_aspect = tmp_old_sz.x/tmp_old_sz.y;
+       vector tmp_new_sz = vec2(sb_gameinfo_type_fontsize.y * tmp_aspect, sb_gameinfo_type_fontsize.y);
 
+       drawpic(pos + '1 0 0' * (panel_size.x - tmp_new_sz.x), "gfx/bai_logo", tmp_new_sz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.y += sb_gameinfo_type_fontsize.y;
+       
+       // z411 servername
+       drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth_colors(hostname_full, sb_gameinfo_detail_fontsize)), hostname_full, sb_gameinfo_detail_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
+       
+       pos.y += sb_gameinfo_detail_fontsize.y;
+       
        // Game Info: Game Detail
        float tl = STAT(TIMELIMIT);
        float fl = STAT(FRAGLIMIT);
@@ -1628,7 +1954,7 @@ void Scoreboard_Draw()
        str = "";
        if(tl > 0)
                str = strcat(str, sprintf(_("^3%1.0f minutes"), tl));
-       if(!ISGAMETYPE(LMS))
+       if(!gametype.m_hidelimits)
        {
                if(fl > 0)
                {
@@ -1677,7 +2003,6 @@ void Scoreboard_Draw()
                }
        }
 
-       pos.y += sb_gameinfo_type_fontsize.y;
        drawcolorcodedstring(pos + '1 0 0' * (panel_size.x - stringwidth(str, true, sb_gameinfo_detail_fontsize)), str, sb_gameinfo_detail_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); // align right
        // map name
        str = sprintf(_("^7Map: ^2%s"), shortmapname);
@@ -1702,7 +2027,7 @@ void Scoreboard_Draw()
                if (autocvar_hud_panel_scoreboard_team_size_position != 1) // team size not on left
                {
                        // put team score to the left of scoreboard (and team size to the right)
-                       team_score_baseoffset = eY * hud_fontsize.y - eX * hud_fontsize.x * 0.5;
+                       team_score_baseoffset = eY * hud_fontsize.y - eX * hud_fontsize.x * 1.5;
                        team_size_baseoffset = eY * hud_fontsize.y + eX * hud_fontsize.x * 0.5;
                        if(panel.current_panel_bg != "0")
                        {
@@ -1713,7 +2038,7 @@ void Scoreboard_Draw()
                else
                {
                        // put team score to the right of scoreboard (and team size to the left)
-                       team_score_baseoffset = eY * hud_fontsize.y + eX * hud_fontsize.x * 0.5;
+                       team_score_baseoffset = eY * hud_fontsize.y + eX * hud_fontsize.x * 1.5;
                        team_size_baseoffset = eY * hud_fontsize.y - eX * hud_fontsize.x * 0.5;
                        if(panel.current_panel_bg != "0")
                        {
@@ -1744,14 +2069,14 @@ void Scoreboard_Draw()
                        if (autocvar_hud_panel_scoreboard_team_size_position != 1) // team size not on left
                        {
                                // team score on the left (default)
-                               str_pos = pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize * 1.5);
+                               str_pos = pos + team_score_baseoffset - eX * stringwidth(str, false, hud_fontsize * 3);
                        }
                        else
                        {
                                // team score on the right
-                               str_pos = pos + team_score_baseoffset + eX * (panel_size.x + hud_fontsize.x * 1.5);
+                               str_pos = pos + team_score_baseoffset + eX * (panel_size.x + hud_fontsize.x * 3);
                        }
-                       drawstring(str_pos, str, hud_fontsize * 1.5, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
+                       drawstring(str_pos, str, hud_fontsize * 3, rgb, panel_fg_alpha, DRAWFLAG_NORMAL);
 
                        // team size (if set to show on the side)
                        if (autocvar_hud_panel_scoreboard_team_size_position != 0) // team size not off
@@ -1804,6 +2129,15 @@ void Scoreboard_Draw()
                }
                panel_bg_color = panel_bg_color_save;
        }
+       else if(gametype == MAPINFO_TYPE_DUEL)
+       {
+               for(tm = teams.sort_next; tm; tm = tm.sort_next)
+                       if(tm.team != NUM_SPECTATOR)
+                               break;
+               
+               // z411 make DUEL TABLE
+               pos = Scoreboard_MakeDuelTable(pos, tm, panel_bg_color, bg_size);
+       }
        else
        {
                for(tm = teams.sort_next; tm; tm = tm.sort_next)
@@ -1814,6 +2148,8 @@ void Scoreboard_Draw()
                pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
        }
 
+       pos = Scoreboard_MedalStats_Draw(pos);
+       
        if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
                pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);