#include <common/stats.qh>
#include <common/teams.qh>
+// Scoreboard (#24)
+
+string autocvar_hud_fontsize;
+string hud_fontsize_str;
+
float sbt_bg_alpha;
float sbt_fg_alpha;
float sbt_fg_alpha_self;
float sbt_highlight_alpha;
float sbt_highlight_alpha_self;
+// provide basic panel cvars to old clients
+// TODO remove them after a future release (0.8.2+)
+string autocvar_hud_panel_scoreboard_pos = "0.150000 0.150000";
+string autocvar_hud_panel_scoreboard_size = "0.700000 0.700000";
+string autocvar_hud_panel_scoreboard_bg = "border_default";
+string autocvar_hud_panel_scoreboard_bg_color = "0 0.3 0.5";
+string autocvar_hud_panel_scoreboard_bg_color_team = "";
+string autocvar_hud_panel_scoreboard_bg_alpha = "0.7";
+string autocvar_hud_panel_scoreboard_bg_border = "";
+string autocvar_hud_panel_scoreboard_bg_padding = "";
+
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_alpha = 0;
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;
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 "dmg": return CTX(_("SCO^damage"));
case "dmgtaken": return CTX(_("SCO^dmgtaken"));
case "drops": return CTX(_("SCO^drops"));
case "faults": return CTX(_("SCO^faults"));
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 "kd": return CTX(_("SCO^k/d"));
case "kdr": return CTX(_("SCO^kdr"));
case "kills": return CTX(_("SCO^kills"));
case "laps": return CTX(_("SCO^laps"));
case "rank": return CTX(_("SCO^rank"));
case "returns": return CTX(_("SCO^returns"));
case "revivals": return CTX(_("SCO^revivals"));
+ case "rounds": return CTX(_("SCO^rounds won"));
case "score": return CTX(_("SCO^score"));
case "suicides": return CTX(_("SCO^suicides"));
case "takes": return CTX(_("SCO^takes"));
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 = SP_SCORE;
- scores_label(ps_primary) = strzone("score");
- scores_flags(ps_primary) = SFL_ALLOW_HIDE;
- }
+ return; // do nothing, we don't know gametype and scores yet
+
+ // sbt_fields uses strunzone on the titles!
+ if(!sbt_field_title[0])
+ for(i = 0; i < MAX_SBT_FIELDS; ++i)
+ sbt_field_title[i] = strzone("(null)");
// TODO: re enable with gametype dependant cvars?
if(argc < 3) // no arguments provided
{
case "ping": sbt_field[sbt_num_fields] = SP_PING; break;
case "pl": sbt_field[sbt_num_fields] = SP_PL; break;
- case "kd": case "kdr": case "kdratio": case "k/d": sbt_field[sbt_num_fields] = SP_KDRATIO; break;
+ case "kd": case "kdr": case "kdratio": sbt_field[sbt_num_fields] = SP_KDRATIO; break;
case "sum": case "diff": case "k-d": sbt_field[sbt_num_fields] = SP_SUM; break;
case "name": case "nick": sbt_field[sbt_num_fields] = SP_NAME; have_name = true; break;
case "|": sbt_field[sbt_num_fields] = SP_SEPARATOR; have_separator = true; break;
case "elo": sbt_field[sbt_num_fields] = SP_ELO; break;
- case "dmg": sbt_field[sbt_num_fields] = SP_DMG; break;
- case "dmgtaken": sbt_field[sbt_num_fields] = SP_DMGTAKEN; break;
+ case "dmg": case "damage": sbt_field[sbt_num_fields] = SP_DMG; break;
+ case "dmgtaken": case "damagetaken": sbt_field[sbt_num_fields] = SP_DMGTAKEN; break;
default:
{
FOREACH(Scores, true, {
}
else if(!teamplay)
{
- f = stof(getplayerkeyvalue(pl.sv_entnum, "colors"));
+ f = entcs_GetClientColors(pl.sv_entnum);
{
sbt_field_icon0 = "gfx/scoreboard/playercolor_base";
sbt_field_icon1 = "gfx/scoreboard/playercolor_shirt";
}
}
- 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;
+ case SP_DMG: case SP_DMGTAKEN:
+ return sprintf("%.1f k", pl.(scores(field)) / 1000);
default:
tmp = pl.(scores(field));
TC(int, i);
float f;
vector sz;
- PlayerScoreField field = sbt_field[i];
sbt_fixcolumnwidth_iconlen = 0;
else
sbt_fixcolumnwidth_marginlen = 0;
- if(field == SP_NAME) // name gets all remaining space
+ if(sbt_field[i] == SP_NAME) // name gets all remaining space
{
int j;
float namesize;
return str;
}
+void Scoreboard_initFieldSizes()
+{
+ for(int i = 0; i < sbt_num_fields; ++i)
+ sbt_field_size[i] = stringwidth(sbt_field_title[i], false, hud_fontsize);
+}
+
vector Scoreboard_DrawHeader(vector pos, vector rgb)
{
int 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;
+ 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);
}
TC(bool, is_self); TC(int, pl_number);
string str;
bool is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
- if(is_spec && !is_self)
- rgb = '0 0 0';
vector h_pos = item_pos;
vector h_size = eX * panel_size.x + eY * hud_fontsize.y * 1.25;
panel_pos = pos;
panel_size.y = 1.25 * hud_fontsize.y * (1 + max(1, tm.team_size));
panel_size.y += panel_bg_padding * 2;
- HUD_Panel_DrawBg(scoreboard_fade_alpha);
+ HUD_Panel_DrawBg();
vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
if(panel.current_panel_bg != "0")
WepSet weapons_stat = WepSet_GetFromStat();
WepSet weapons_inmap = WepSet_GetFromStat_InMap();
int disownedcnt = 0;
+ int nHidden = 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;
+ if (weapon_stats < 0)
+ {
+ if (!(weapons_stat & set) && (it.spawnflags & WEP_FLAG_HIDDEN || it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
+ nHidden += 1;
+ else if (!(weapons_stat & set || weapons_inmap & set))
+ ++disownedcnt;
+ }
});
- int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt;
+ int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt - nHidden;
if (weapon_cnt <= 0) return pos;
int rows = 1;
- if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
+ if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - nHidden - 1) * 0.5))
rows = 2;
int columnns = ceil(weapon_cnt / rows);
- float height = 40;
+ float weapon_height = 29;
+ float height = hud_fontsize.y + weapon_height;
drawstring(pos + eX * panel_bg_padding, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
panel_pos = pos;
panel_size.y = height * rows;
panel_size.y += panel_bg_padding * 2;
- HUD_Panel_DrawBg(scoreboard_fade_alpha);
+ HUD_Panel_DrawBg();
vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
if(panel.current_panel_bg != "0")
pos = panel_pos;
vector tmp = panel_size;
- float fontsize = height * 1/3;
- float weapon_height = height * 2/3;
float weapon_width = tmp.x / columnns / rows;
if (sbt_bg_alpha)
// 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);
+ drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * hud_fontsize.y, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
}
average_accuracy = 0;
s = sprintf("%d%%", weapon_stats * 100);
float padding;
- padding = (weapon_width - stringwidth(s, false, eX * fontsize)) / 2; // center the accuracy value
+ padding = (weapon_width - stringwidth(s, false, hud_fontsize)) / 2; // center the accuracy value
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);
+ drawstring(tmpos + eX * padding + eY * weapon_height, s, hud_fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
}
tmpos.x += weapon_width * rows;
pos.x += weapon_width * rows;
// 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)
panel_pos = pos;
panel_size.y = hud_fontsize.y * rows;
panel_size.y += panel_bg_padding * 2;
- HUD_Panel_DrawBg(scoreboard_fade_alpha);
+ HUD_Panel_DrawBg();
vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
if(panel.current_panel_bg != "0")
panel_pos = pos;
panel_size.y = 1.25 * hud_fontsize.y * RANKINGS_RECEIVED_CNT;
panel_size.y += panel_bg_padding * 2;
- HUD_Panel_DrawBg(scoreboard_fade_alpha);
+ HUD_Panel_DrawBg();
vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
if(panel.current_panel_bg != "0")
{
if(!autocvar__hud_configure)
{
+ if(!hud_draw_maximized) return;
+
// frametime checks allow to toggle the scoreboard even when the game is paused
if(scoreboard_active) {
- if(menu_enabled == 1)
+ if(hud_configure_menu_open == 1)
scoreboard_fade_alpha = 1;
float scoreboard_fadeinspeed = autocvar_hud_panel_scoreboard_fadeinspeed;
if (scoreboard_fadeinspeed && frametime)
scoreboard_fade_alpha = min(1, scoreboard_fade_alpha + frametime * scoreboard_fadeinspeed);
else
scoreboard_fade_alpha = 1;
+ if(hud_fontsize_str != autocvar_hud_fontsize)
+ {
+ hud_fontsize = HUD_GetFontsize("hud_fontsize");
+ Scoreboard_initFieldSizes();
+ if(hud_fontsize_str)
+ strunzone(hud_fontsize_str);
+ hud_fontsize_str = strzone(autocvar_hud_fontsize);
+ }
}
else {
float scoreboard_fadeoutspeed = autocvar_hud_panel_scoreboard_fadeoutspeed;
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();
+ if(scoreboard_fade_alpha <= 0)
+ return;
+ panel_fade_alpha *= scoreboard_fade_alpha;
+ HUD_Panel_LoadCvars();
sbt_bg_alpha = autocvar_hud_panel_scoreboard_table_bg_alpha * panel_fg_alpha;
sbt_highlight = autocvar_hud_panel_scoreboard_table_highlight;
sbt_fg_alpha = autocvar_hud_panel_scoreboard_table_fg_alpha * panel_fg_alpha;
sbt_fg_alpha_self = autocvar_hud_panel_scoreboard_table_fg_alpha_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);
{
if(tm.team == NUM_SPECTATOR)
continue;
- if(!tm.team && teamplay)
+ if(!tm.team)
continue;
draw_beginBoldFont();
{
if(tm.team == NUM_SPECTATOR)
continue;
- if(!tm.team && teamplay)
- continue;
pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
}
if(pl.team != NUM_SPECTATOR)
continue;
pos.y += 1.25 * hud_fontsize.y;
- Scoreboard_DrawItem(pos, panel_bg_color, pl, (pl.sv_entnum == player_localnum), specs);
+ Scoreboard_DrawItem(pos, '0 0 0', pl, (pl.sv_entnum == player_localnum), specs);
++specs;
}
{
// 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_hud_panel_scoreboard_respawntime_decimals ?
- count_seconds_decs(respawn_time - time, autocvar_hud_panel_scoreboard_respawntime_decimals)
- :
- count_seconds(respawn_time - time)
- )
- );
+ if(respawn_time < time) // it happens for a few frames when server is respawning the player
+ str = ""; // draw an empty string to not change suddenly scoreboard_bottom
+ else
+ str = sprintf(_("^1Respawning in ^3%s^1..."),
+ (autocvar_hud_panel_scoreboard_respawntime_decimals ?
+ count_seconds_decs(respawn_time - time, autocvar_hud_panel_scoreboard_respawntime_decimals)
+ :
+ count_seconds(ceil(respawn_time - time))
+ )
+ );
}
else if(time < respawn_time)
{
(autocvar_hud_panel_scoreboard_respawntime_decimals ?
count_seconds_decs(respawn_time - time, autocvar_hud_panel_scoreboard_respawntime_decimals)
:
- count_seconds(respawn_time - time)
+ count_seconds(ceil(respawn_time - time))
)
);
}