X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2Fhud%2Fpanel%2Fscoreboard.qc;h=4a815424de7ab3948cb9f46913d32b91e90aacab;hb=b534978a4c93a5169504bff10134e451c5b23051;hp=0ac5b8d2c0ab014942ff3f4fceaac61aad73020a;hpb=119bc8cf0d13fabc29aeeb8001ae796057a18715;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/hud/panel/scoreboard.qc b/qcsrc/client/hud/panel/scoreboard.qc index 0ac5b8d2c..4a815424d 100644 --- a/qcsrc/client/hud/panel/scoreboard.qc +++ b/qcsrc/client/hud/panel/scoreboard.qc @@ -34,6 +34,7 @@ void Scoreboard_Draw_Export(int fh) HUD_Write_Cvar("hud_panel_scoreboard_bg_teams_color_team"); HUD_Write_Cvar("hud_panel_scoreboard_accuracy_doublerows"); HUD_Write_Cvar("hud_panel_scoreboard_accuracy_nocolors"); + HUD_Write_Cvar("hud_panel_scoreboard_spectators_position"); } const int MAX_SBT_FIELDS = MAX_SCORE; @@ -80,6 +81,7 @@ float autocvar_hud_panel_scoreboard_table_highlight_alpha_eliminated = 0.6; float autocvar_hud_panel_scoreboard_bg_teams_color_team = 0; float autocvar_hud_panel_scoreboard_namesize = 15; float autocvar_hud_panel_scoreboard_team_size_position = 0; +float autocvar_hud_panel_scoreboard_spectators_position = 1; bool autocvar_hud_panel_scoreboard_accuracy = true; bool autocvar_hud_panel_scoreboard_accuracy_doublerows = false; @@ -89,7 +91,8 @@ float autocvar_hud_panel_scoreboard_accuracy_showdelay_minpos = 0.75; bool autocvar_hud_panel_scoreboard_itemstats = true; bool autocvar_hud_panel_scoreboard_itemstats_doublerows = false; -bool autocvar_hud_panel_scoreboard_itemstats_filter = true; +int autocvar_hud_panel_scoreboard_itemstats_filter = 1; +int autocvar_hud_panel_scoreboard_itemstats_filter_mask = 12; float autocvar_hud_panel_scoreboard_itemstats_showdelay = 2.2; // slightly more delayed than accuracy float autocvar_hud_panel_scoreboard_itemstats_showdelay_minpos = 0.75; @@ -247,14 +250,8 @@ int Scoreboard_CompareScore(int vl, int vr, int f) float Scoreboard_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; + int vl = (left.gotscores) ? entcs_GetTeam(left.sv_entnum) : NUM_SPECTATOR; + int vr = (right.gotscores) ? entcs_GetTeam(right.sv_entnum) : NUM_SPECTATOR; if(vl > vr) return true; @@ -271,6 +268,7 @@ float Scoreboard_ComparePlayerScores(entity left, entity right) } entity fld = NULL; + int r; for (int i = -2; i < SB_EXTRA_SORTING_FIELDS; ++i) { if (i < 0) @@ -311,26 +309,29 @@ void Scoreboard_UpdatePlayerPos(entity player) float Scoreboard_CompareTeamScores(entity left, entity right) { - int i, r; - if(left.team == NUM_SPECTATOR) return 1; if(right.team == NUM_SPECTATOR) return 0; - r = Scoreboard_CompareScore(left.teamscores(ts_primary), right.teamscores(ts_primary), teamscores_flags(ts_primary)); - if (r >= 0) - return r; - - 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_TEAMSCORE; ++i) + int fld_idx = -1; + int r; + for(int i = -2; i < MAX_TEAMSCORE; ++i) { - r = Scoreboard_CompareScore(left.teamscores(i), right.teamscores(i), teamscores_flags(i)); - if (r >= 0) - return r; + if (i < 0) + { + if (fld_idx == -1) fld_idx = ts_primary; + else if (ts_secondary == ts_primary) continue; + else fld_idx = ts_secondary; + } + else + { + fld_idx = i; + if (fld_idx == ts_primary || fld_idx == ts_secondary) continue; + } + + r = Scoreboard_CompareScore(left.teamscores(fld_idx), right.teamscores(fld_idx), teamscores_flags(fld_idx)); + if (r >= 0) return r; } if (left.team < right.team) @@ -438,9 +439,16 @@ void Cmd_Scoreboard_SetFields(int argc) cvar_set("scoreboard_columns", SCOREBOARD_DEFAULT_COLUMNS); argc = tokenizebyseparator(strcat("0 1 ", SCOREBOARD_DEFAULT_COLUMNS), " "); } - else if(argv(2) == "all") + else if(argv(2) == "all" || argv(2) == "ALL") { - string s = "ping pl name |"; // scores without a label + string s = "ping pl name |"; // scores without label (not really scores) + if(argv(2) == "ALL") + { + // scores without label + s = strcat(s, " ", "sum"); + s = strcat(s, " ", "kdratio"); + s = strcat(s, " ", "frags"); + } FOREACH(Scores, true, { if(it != ps_primary) if(it != ps_secondary) @@ -1346,18 +1354,31 @@ vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size) return end_pos; } -.bool uninteresting; -STATIC_INIT(default_order_items_label) +bool is_item_filtered(entity it) { - IL_EACH(default_order_items, true, { - if(!(it.instanceOfPowerup - || it == ITEM_HealthMega || it == ITEM_HealthBig - || it == ITEM_ArmorMega || it == ITEM_ArmorBig - )) + if (!autocvar_hud_panel_scoreboard_itemstats_filter) + return false; + int mask = autocvar_hud_panel_scoreboard_itemstats_filter_mask; + if (mask <= 0) + return false; + if (it.instanceOfArmor || it.instanceOfHealth) + { + int ha_mask = floor(mask) % 10; + switch (ha_mask) { - it.uninteresting = true; + default: return false; + case 4: if (it == ITEM_HealthMega || it == ITEM_ArmorMega) return true; // else fallthrough + case 3: if (it == ITEM_HealthBig || it == ITEM_ArmorBig) return true; // else fallthrough + case 2: if (it == ITEM_HealthMedium || it == ITEM_ArmorMedium) return true; // else fallthrough + case 1: if (it == ITEM_HealthSmall || it == ITEM_ArmorSmall) return true; // else fallthrough } - }); + } + if (it.instanceOfAmmo) + { + int ammo_mask = floor(mask / 10) % 10; + return (ammo_mask == 1); + } + return false; } vector Scoreboard_ItemStats_Draw(vector pos, vector rgb, vector bg_size) @@ -1369,7 +1390,7 @@ vector Scoreboard_ItemStats_Draw(vector pos, vector rgb, vector bg_size) IL_EACH(default_order_items, true, { int q = g_inventory.inv_items[it.m_id]; //q = 1; // debug: display all items - if (autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting) + if (is_item_filtered(it)) ++uninteresting_cnt; else if (!q) ++disowned_cnt; @@ -1436,7 +1457,7 @@ vector Scoreboard_ItemStats_Draw(vector pos, vector rgb, vector bg_size) vector tmpos = pos; int column = 0; - IL_EACH(default_order_items, !(autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting), { + IL_EACH(default_order_items, !is_item_filtered(it), { int n = g_inventory.inv_items[it.m_id]; //n = 1 + floor(i * 3 + 4.8) % 7; // debug: display a value for each item if (n <= 0) continue; @@ -1540,7 +1561,9 @@ vector Scoreboard_MapStats_Draw(vector pos, vector rgb, vector bg_size) { return end_pos; } - +int rankings_rows = 0; +int rankings_columns = 0; +int rankings_cnt = 0; vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector rgb, vector bg_size) { int i; @@ -1554,7 +1577,6 @@ vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector vector hl_rgb = rgb + '0.5 0.5 0.5'; - pos.y += hud_fontsize.y; drawstring(pos + eX * panel_bg_padding, ranktitle, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); pos.y += 1.25 * hud_fontsize.y; if(panel.current_panel_bg != "0") @@ -1579,15 +1601,20 @@ vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector float ranksize = 3 * hud_fontsize.x; float timesize = 5 * hud_fontsize.x; vector columnsize = vec2(ranksize + timesize + namesize + hud_fontsize.x, 1.25 * hud_fontsize.y); - int columns = max(1, floor((panel_size.x - 2 * panel_bg_padding) / columnsize.x)); - columns = min(columns, RANKINGS_RECEIVED_CNT); + rankings_columns = max(1, floor((panel_size.x - 2 * panel_bg_padding) / columnsize.x)); + rankings_columns = min(rankings_columns, RANKINGS_RECEIVED_CNT); + if (!rankings_cnt) + { + rankings_cnt = RANKINGS_RECEIVED_CNT; + rankings_rows = ceil(rankings_cnt / rankings_columns); + } // expand name column to fill the entire row - float available_space = (panel_size.x - 2 * panel_bg_padding - columnsize.x * columns) / columns; + float available_space = (panel_size.x - 2 * panel_bg_padding - columnsize.x * rankings_columns) / rankings_columns; namesize += available_space; columnsize.x += available_space; - panel_size.y = ceil(RANKINGS_RECEIVED_CNT / columns) * 1.25 * hud_fontsize.y; + panel_size.y = rankings_rows * 1.25 * hud_fontsize.y; panel_size.y += panel_bg_padding * 2; HUD_Panel_DrawBg(); @@ -1611,7 +1638,7 @@ vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector string str = ""; int column = 0, j = 0; string zoned_name_self = strzone(strdecolorize(entcs_GetName(player_localnum))); - for(i = 0; i < RANKINGS_RECEIVED_CNT; ++i) + for(i = 0; i < rankings_cnt; ++i) { float t; t = grecordtime[i]; @@ -1633,11 +1660,11 @@ vector Scoreboard_Rankings_Draw(vector pos, string ranktitle, entity pl, vector pos.y += 1.25 * hud_fontsize.y; j++; - if(j >= ceil(RANKINGS_RECEIVED_CNT / columns)) + if(j >= rankings_rows) { column++; j = 0; - pos.x += panel_size.x / columns; + pos.x += panel_size.x / rankings_columns; pos.y = panel_pos.y; } } @@ -1698,7 +1725,7 @@ bool Scoreboard_ItemStats_WouldDraw(float ypos) if (!have_item_stats) { IL_EACH(default_order_items, true, { - if (!(autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting)) + if (!is_item_filtered(it)) { int q = g_inventory.inv_items[it.m_id]; //q = 1; // debug: display all items @@ -1716,6 +1743,36 @@ bool Scoreboard_ItemStats_WouldDraw(float ypos) return true; } +vector Scoreboard_Spectators_Draw(vector pos) { + + entity pl, tm; + string str = ""; + + for(pl = players.sort_next; pl; pl = pl.sort_next) + { + if(pl.team == NUM_SPECTATOR) + { + for(tm = teams.sort_next; tm; tm = tm.sort_next) + if(tm.team == NUM_SPECTATOR) + break; + str = sprintf("%s (%d)", _("Spectators"), tm.team_size); + draw_beginBoldFont(); + drawstring(pos, str, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + draw_endBoldFont(); + pos.y += 1.25 * hud_fontsize.y; + + pos = Scoreboard_DrawOthers(pos, '0 0 0', pl.team, NULL, pl, 0); + pos.y += 1.25 * hud_fontsize.y; + + break; + } + } + if (str != "") // if there's at least one spectator + pos.y += 0.5 * hud_fontsize.y; + + return pos; +} + void Scoreboard_Draw() { if(!autocvar__hud_configure) @@ -1782,14 +1839,16 @@ void Scoreboard_Draw() float excess = max(0, max_namesize - autocvar_hud_panel_scoreboard_namesize * hud_fontsize.x); float fixed_scoreboard_width = bound(vid_conwidth * autocvar_hud_panel_scoreboard_minwidth, vid_conwidth - excess, vid_conwidth * 0.93); - panel_pos.x = 0.5 * (vid_conwidth - fixed_scoreboard_width); + scoreboard_left = 0.5 * (vid_conwidth - fixed_scoreboard_width); + scoreboard_right = scoreboard_left + fixed_scoreboard_width; + panel_pos.x = scoreboard_left; panel_size.x = fixed_scoreboard_width; Scoreboard_UpdatePlayerTeams(); - float initial_pos_y = panel_pos.y; + scoreboard_top = panel_pos.y; vector pos = panel_pos; - entity pl, tm; + entity tm; string str; vector str_pos; @@ -1999,45 +2058,50 @@ void Scoreboard_Draw() pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size); } + // draw scoreboard spectators before accuracy and item stats + if (autocvar_hud_panel_scoreboard_spectators_position == 0) { + pos = Scoreboard_Spectators_Draw(pos); + } + + // draw accuracy and item stats if (Scoreboard_AccuracyStats_WouldDraw(pos.y)) pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size); if (Scoreboard_ItemStats_WouldDraw(pos.y)) pos = Scoreboard_ItemStats_Draw(pos, panel_bg_color, bg_size); + // draw scoreboard spectators after accuracy and item stats and before rankings + if (autocvar_hud_panel_scoreboard_spectators_position == 1) { + pos = Scoreboard_Spectators_Draw(pos); + } + if(MUTATOR_CALLHOOK(ShowRankings)) { string ranktitle = M_ARGV(0, string); + string unit = GetSpeedUnit(autocvar_hud_panel_physics_speed_unit); if(race_speedaward) { - drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, race_speedaward_unit, ColorTranslateRGB(race_speedaward_holder)), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); + drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, unit, ColorTranslateRGB(race_speedaward_holder)), hud_fontsize, panel_fg_alpha, 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, ColorTranslateRGB(race_speedaward_alltimebest_holder)), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); + drawcolorcodedstring(pos, sprintf(_("All-time fastest: %d%s ^7(%s^7)"), race_speedaward_alltimebest, unit, ColorTranslateRGB(race_speedaward_alltimebest_holder)), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); pos.y += 1.25 * hud_fontsize.y; } + if (race_speedaward || race_speedaward_alltimebest) + pos.y += 0.25 * hud_fontsize.y; pos = Scoreboard_Rankings_Draw(pos, ranktitle, playerslots[player_localnum], panel_bg_color, bg_size); } + else + rankings_cnt = 0; - pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size); - - // List spectators - for(pl = players.sort_next; pl; pl = pl.sort_next) - { - if(pl.team == NUM_SPECTATOR) - { - for(tm = teams.sort_next; tm; tm = tm.sort_next) - if(tm.team == NUM_SPECTATOR) - break; - str = sprintf("%s (%d)", _("Spectators"), tm.team_size); - draw_beginBoldFont(); - drawstring(pos, str, hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); - draw_endBoldFont(); - pos.y += 1.25 * hud_fontsize.y; + // draw scoreboard spectators after rankings + if (autocvar_hud_panel_scoreboard_spectators_position == 2) { + pos = Scoreboard_Spectators_Draw(pos); + } - pos = Scoreboard_DrawOthers(pos, '0 0 0', pl.team, NULL, pl, 0); - pos.y += 1.25 * hud_fontsize.y; + pos = Scoreboard_MapStats_Draw(pos, panel_bg_color, bg_size); - break; - } + // draw scoreboard spectators after mapstats + if (autocvar_hud_panel_scoreboard_spectators_position == 3) { + pos = Scoreboard_Spectators_Draw(pos); } @@ -2079,14 +2143,23 @@ void Scoreboard_Draw() drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL); } - pos.y += 2 * hud_fontsize.y; + pos.y += hud_fontsize.y; if (scoreboard_fade_alpha < 1) - scoreboard_bottom = initial_pos_y + (pos.y - initial_pos_y) * scoreboard_fade_alpha; + scoreboard_bottom = scoreboard_top + (pos.y - scoreboard_top) * scoreboard_fade_alpha; else if (pos.y != scoreboard_bottom) { if (pos.y > scoreboard_bottom) - scoreboard_bottom = min(pos.y, scoreboard_bottom + frametime * 10 * (pos.y - initial_pos_y)); + scoreboard_bottom = min(pos.y, scoreboard_bottom + frametime * 10 * (pos.y - scoreboard_top)); else - scoreboard_bottom = max(pos.y, scoreboard_bottom - frametime * 10 * (pos.y - initial_pos_y)); + scoreboard_bottom = max(pos.y, scoreboard_bottom - frametime * 10 * (pos.y - scoreboard_top)); + } + + if (scoreboard_fade_alpha == 1) + { + if (scoreboard_bottom > 0.95 * vid_conheight) + rankings_rows = max(1, rankings_rows - 1); + else if (scoreboard_bottom + 1.25 * hud_fontsize.y < 0.95 * vid_conheight) + rankings_rows = min(ceil(RANKINGS_RECEIVED_CNT / rankings_columns), rankings_rows + 1); } + rankings_cnt = rankings_rows * rankings_columns; }