3 #include <client/draw.qh>
4 #include <client/hud/panel/scoreboard.qh>
5 #include <common/ent_cs.qh>
6 #include <common/scores.qh>
10 void HUD_Score_Export(int fh)
12 // allow saving cvars that aesthetically change the panel into hud skin files
13 HUD_Write_Cvar("hud_panel_score_rankings");
16 void HUD_Score_Rankings(vector pos, vector mySize, entity me)
20 int SCOREPANEL_MAX_ENTRIES = 6;
21 float SCOREPANEL_ASPECTRATIO = 2;
22 int entries = bound(1, floor(SCOREPANEL_MAX_ENTRIES * mySize.y/mySize.x * SCOREPANEL_ASPECTRATIO), SCOREPANEL_MAX_ENTRIES);
23 vector fontsize = '1 1 0' * (mySize.y/entries);
25 vector rgb, score_color;
27 score_color = '1 1 1';
29 float name_size = mySize.x*0.75;
30 float spacing_size = mySize.x*0.04;
31 const float highlight_alpha = 0.2;
32 int i = 0, first_pl = 0;
33 bool me_printed = false;
35 if (autocvar__hud_configure)
37 float players_per_team = 0;
40 // show team scores in the first line
41 float score_size = mySize.x / team_count;
42 players_per_team = max(2, ceil((entries - 1) / team_count));
43 for(i=0; i<team_count; ++i) {
44 if (i == floor((entries - 2) / players_per_team) || (entries == 1 && i == 0))
45 HUD_Panel_DrawHighlight(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
46 drawstring_aspect(pos + eX * score_size * i, ftos(175 - 23*i), vec2(score_size, fontsize.y), Team_ColorRGB(ColorByTeam(i)) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
51 score = 10 + SCOREPANEL_MAX_ENTRIES * 3;
52 for (i=first_pl; i<entries; ++i)
54 //simulate my score is lower than all displayed players,
55 //so that I don't appear at all showing pure rankings.
56 //This is to better show the difference between the 2 ranking views
57 if (i == entries-1 && autocvar_hud_panel_score_rankings == 1)
60 drawfill(pos, vec2(mySize.x, fontsize.y), rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
61 s = entcs_GetName(player_localnum);
66 s = sprintf(_("Player %d"), i + 1 - first_pl);
71 score_color = Team_ColorRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
72 s = textShortenToWidth(s, name_size, fontsize, stringwidth_colors);
73 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
74 drawstring(pos + eX * (name_size + spacing_size), ftos(score), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
83 // show team scores in the first line
84 float score_size = mySize.x / team_count;
85 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
86 if(tm.team == NUM_SPECTATOR)
91 if (tm.team == myteam)
92 drawfill(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
93 drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores(ts_primary))), vec2(score_size, fontsize.y), Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
102 // z411 Basic team stats
106 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
107 if(tm.team == NUM_SPECTATOR)
112 /*if (tm.team == myteam)
113 drawfill(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
114 drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores(ts_primary))), vec2(score_size, fontsize.y), Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
117 if (tm.team == myteam)
120 rgb = '0 1 0'; //first: green
122 drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
125 score_color = Team_ColorRGB(tm.team) * 0.8;
127 // TODO secondary scores test, remove
128 if(gametype.m_modscores)
131 if(tm.team == NUM_TEAM_1)
132 icon = "gfx/hud/luma/player_red";
133 else if(tm.team == NUM_TEAM_2)
134 icon = "gfx/hud/luma/player_blue";
136 icon = "gfx/hud/luma/player_neutral";
138 vector icon_sz = draw_getimagesize(icon);
139 vector icon_sz_new = vec2(fontsize.y*(icon_sz.x/icon_sz.y), fontsize.y);
141 s = ftos(gametype.m_modscores(tm.team));
142 float s_width = stringwidth(s, false, fontsize) + icon_sz_new.x;
144 //drawfill(pos, eX * s_width + eY * fontsize.y, score_color, panel_fg_alpha * 0.3, DRAWFLAG_NORMAL);
145 drawpic(pos, icon, icon_sz_new, '1 1 1', panel_fg_alpha * 0.7, DRAWFLAG_NORMAL);
146 drawstring(pos + eX * icon_sz_new.x, s, fontsize, '1 1 1', panel_fg_alpha * 0.7, DRAWFLAG_NORMAL);
148 s = textShortenToWidth(Team_CustomName(tm.team), name_size - s_width, fontsize, stringwidth_colors);
150 s = textShortenToWidth(Team_CustomName(tm.team), name_size, fontsize, stringwidth_colors);
153 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
155 draw_beginBoldFont();
156 drawstring(pos + eX * (name_size + spacing_size), ftos(tm.(teamscores(ts_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
166 for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
168 if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
171 if (i == entries-1 && !me_printed && pl != me)
172 if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
174 for (pl = me.sort_next; pl; pl = pl.sort_next)
175 if (pl.team != NUM_SPECTATOR)
179 rgb = '1 1 0'; //not last but not among the leading players: yellow
181 rgb = '1 0 0'; //last: red
186 score_color = Team_ColorRGB(pl.team) * 0.8;
191 rgb = '0 1 0'; //first: green
193 drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
196 s = textShortenToWidth(entcs_GetName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
197 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
198 drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores(ps_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
202 while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
208 if(!autocvar__hud_configure)
210 if(!autocvar_hud_panel_score) return;
211 if(MUTATOR_CALLHOOK(HUD_Score_show)) return;
214 if (!scoreboard_fade_alpha) // the scoreboard too calls Scoreboard_UpdatePlayerTeams
215 Scoreboard_UpdatePlayerTeams();
217 if(spectatee_status) {
218 if(teamplay && autocvar_hud_spectatorteamdisplay) return;
219 if(gametype == MAPINFO_TYPE_DUEL && autocvar_hud_spectatordueldisplay) return;
222 HUD_Panel_LoadCvars();
227 if (autocvar_hud_panel_score_dynamichud)
234 pos += '1 1 0' * panel_bg_padding;
235 mySize -= '2 2 0' * panel_bg_padding;
238 float score, distribution = 0;
240 vector distribution_color;
243 me = playerslots[current_player];
245 if((scores_flags(ps_primary) & SFL_TIME) && !teamplay) { // race/cts record display on HUD
246 string timer, distrtimer;
248 pl = players.sort_next;
251 if(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)
252 if(pl.scores(ps_primary) == 0)
255 score = me.(scores(ps_primary));
256 timer = TIME_ENCODED_TOSTRING(score);
258 draw_beginBoldFont();
259 if (pl && ((!(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)) || score)) {
260 // distribution display
261 distribution = me.(scores(ps_primary)) - pl.(scores(ps_primary));
263 distrtimer = ftos_decimals(fabs(distribution/(10 ** TIME_DECIMALS)), TIME_DECIMALS);
265 if (distribution <= 0) {
266 distribution_color = '0 1 0';
270 distribution_color = '1 0 0';
273 drawstring_aspect(pos + eX * 0.75 * mySize.x, strcat(sign, distrtimer), vec2(0.25 * mySize.x, (1/3) * mySize.y), distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
275 // race record display
276 if (distribution <= 0)
277 HUD_Panel_DrawHighlight(pos, vec2(0.75 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
278 drawstring_aspect(pos, timer, vec2(0.75 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
280 } else if (!teamplay) { // non-teamgames
281 if ((spectatee_status == -1 && !autocvar__hud_configure) || autocvar_hud_panel_score_rankings)
283 HUD_Score_Rankings(pos, mySize, me);
286 // me vector := [team/connected frags id]
287 pl = players.sort_next;
291 if(autocvar__hud_configure)
294 distribution = me.(scores(ps_primary)) - pl.(scores(ps_primary));
298 score = me.(scores(ps_primary));
299 if(autocvar__hud_configure)
302 if(distribution >= 5)
303 distribution_color = eY;
304 else if(distribution >= 0)
305 distribution_color = '1 1 1';
306 else if(distribution >= -5)
307 distribution_color = '1 1 0';
309 distribution_color = eX;
311 string distribution_str;
312 distribution_str = ftos(distribution);
313 draw_beginBoldFont();
314 if (distribution >= 0)
316 if (distribution > 0)
317 distribution_str = strcat("+", distribution_str);
318 HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
320 drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize.x + eY * mySize.y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
321 drawstring_aspect(pos + eX * 0.75 * mySize.x, distribution_str, vec2(0.25 * mySize.x, (1/3) * mySize.y), distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
323 } else { // teamgames
324 float row, column, rows = 0, columns = 0;
325 vector offset = '0 0 0';
326 vector score_pos, score_size; //for scores other than myteam
327 if(autocvar_hud_panel_score_rankings)
329 HUD_Score_Rankings(pos, mySize, me);
332 if(spectatee_status == -1)
334 rows = HUD_GetRowCount(team_count, mySize, 3);
335 columns = ceil(team_count/rows);
336 score_size = vec2(mySize.x / columns, mySize.y / rows);
339 if(score_size.x/score_size.y > 3)
341 newSize = 3 * score_size.y;
342 offset.x = score_size.x - newSize;
344 score_size.x = newSize;
348 newSize = 1/3 * score_size.x;
349 offset.y = score_size.y - newSize;
351 score_size.y = newSize;
355 score_size = vec2(mySize.x / 4, mySize.y / 3);
359 draw_beginBoldFont();
361 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
362 if(tm.team == NUM_SPECTATOR)
367 score = tm.(teamscores(ts_primary));
368 if(autocvar__hud_configure)
371 if (score > max_fragcount)
372 max_fragcount = score;
374 if (spectatee_status == -1)
376 score_pos = pos + vec2(column * (score_size.x + offset.x), row * (score_size.y + offset.y));
377 if (max_fragcount == score)
378 HUD_Panel_DrawHighlight(score_pos, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
379 drawstring_aspect(score_pos, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
387 else if(tm.team == myteam) {
388 if (max_fragcount == score)
389 HUD_Panel_DrawHighlight(pos, vec2(0.75 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
390 drawstring_aspect(pos, ftos(score), vec2(0.75 * mySize.x, mySize.y), Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
392 if (max_fragcount == score)
393 HUD_Panel_DrawHighlight(pos + vec2(0.75 * mySize.x, (1/3) * rows * mySize.y), score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
394 drawstring_aspect(pos + vec2(0.75 * mySize.x, (1/3) * rows * mySize.y), ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);