3 #include <client/autocvars.qh>
4 #include <client/main.qh>
5 #include <client/miscfunctions.qh>
6 #include "scoreboard.qh"
7 #include <common/ent_cs.qh>
8 #include <common/scores.qh>
12 void HUD_Score_Export(int fh)
14 // allow saving cvars that aesthetically change the panel into hud skin files
15 HUD_Write_Cvar("hud_panel_score_rankings");
18 void HUD_Score_Rankings(vector pos, vector mySize, entity me)
22 int SCOREPANEL_MAX_ENTRIES = 6;
23 float SCOREPANEL_ASPECTRATIO = 2;
24 int entries = bound(1, floor(SCOREPANEL_MAX_ENTRIES * mySize.y/mySize.x * SCOREPANEL_ASPECTRATIO), SCOREPANEL_MAX_ENTRIES);
25 vector fontsize = '1 1 0' * (mySize.y/entries);
27 vector rgb, score_color;
29 score_color = '1 1 1';
31 float name_size = mySize.x*0.75;
32 float spacing_size = mySize.x*0.04;
33 const float highlight_alpha = 0.2;
34 int i = 0, first_pl = 0;
35 bool me_printed = false;
37 if (autocvar__hud_configure)
39 float players_per_team = 0;
42 // show team scores in the first line
43 float score_size = mySize.x / team_count;
44 players_per_team = max(2, ceil((entries - 1) / team_count));
45 for(i=0; i<team_count; ++i) {
46 if (i == floor((entries - 2) / players_per_team) || (entries == 1 && i == 0))
47 HUD_Panel_DrawHighlight(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
48 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);
53 score = 10 + SCOREPANEL_MAX_ENTRIES * 3;
54 for (i=first_pl; i<entries; ++i)
56 //simulate my score is lower than all displayed players,
57 //so that I don't appear at all showing pure rankings.
58 //This is to better show the difference between the 2 ranking views
59 if (i == entries-1 && autocvar_hud_panel_score_rankings == 1)
62 drawfill(pos, vec2(mySize.x, fontsize.y), rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
63 s = entcs_GetName(player_localnum);
68 s = sprintf(_("Player %d"), i + 1 - first_pl);
73 score_color = Team_ColorRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
74 s = textShortenToWidth(s, name_size, fontsize, stringwidth_colors);
75 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
76 drawstring(pos + eX * (name_size + spacing_size), ftos(score), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
82 if (!scoreboard_fade_alpha) // the scoreboard too calls Scoreboard_UpdatePlayerTeams
83 Scoreboard_UpdatePlayerTeams();
88 // show team scores in the first line
89 float score_size = mySize.x / team_count;
90 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
91 if(tm.team == NUM_SPECTATOR)
96 if (tm.team == myteam)
97 drawfill(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
98 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);
103 tm = teams.sort_next;
111 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
112 if(tm.team == NUM_SPECTATOR)
117 /*if (tm.team == myteam)
118 drawfill(pos + eX * score_size * i, vec2(score_size, fontsize.y), '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
119 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);
122 if (tm.team == myteam)
125 rgb = '0 1 0'; //first: green
127 drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
130 s = strcat(Team_ColorCode(tm.team), strtoupper(Team_ColorName(tm.team)), "^7 team");
131 //s = textShortenToWidth(Team_ColorName(tm.team), name_size, fontsize, stringwidth_colors);
132 score_color = Team_ColorRGB(tm.team) * 0.8;
134 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
135 drawstring(pos + eX * (name_size + spacing_size), ftos(tm.(teamscores(ts_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
143 for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
145 if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
148 if (i == entries-1 && !me_printed && pl != me)
149 if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
151 for (pl = me.sort_next; pl; pl = pl.sort_next)
152 if (pl.team != NUM_SPECTATOR)
156 rgb = '1 1 0'; //not last but not among the leading players: yellow
158 rgb = '1 0 0'; //last: red
163 score_color = Team_ColorRGB(pl.team) * 0.8;
165 entity entcs = entcs_receiver(pl.sv_entnum);
166 if(entcs.m_entcs_private) {
167 // z411 draw health/armor bar
168 vector bar_sz = vec2(mySize.x, fontsize.y);
170 bar_sz.x *= entcs.healthvalue / autocvar_hud_panel_healtharmor_maxhealth;
171 drawfill(pos, bar_sz, ((team_count) ? score_color : '0.8 0.8 0'), 0.5, DRAWFLAG_NORMAL);
173 bar_sz.x *= GetResource(entcs, RES_ARMOR) / autocvar_hud_panel_healtharmor_maxarmor;
174 drawfill(pos + eY * (bar_sz.y * 0.7), bar_sz - eY * (bar_sz.y * 0.7), ((team_count) ? score_color : '0 0.8 0.8'), 1, DRAWFLAG_NORMAL);
180 rgb = '0 1 0'; //first: green
182 drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
185 s = textShortenToWidth(entcs_GetName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
186 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
187 drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores(ps_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
191 while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
197 if(!autocvar__hud_configure)
199 if(!autocvar_hud_panel_score) return;
200 if(MUTATOR_CALLHOOK(HUD_Score_show)) return;
203 HUD_Panel_LoadCvars();
208 if (autocvar_hud_panel_score_dynamichud)
215 pos += '1 1 0' * panel_bg_padding;
216 mySize -= '2 2 0' * panel_bg_padding;
219 float score, distribution = 0;
221 vector distribution_color;
224 me = playerslots[current_player];
226 if((scores_flags(ps_primary) & SFL_TIME) && !teamplay) { // race/cts record display on HUD
227 string timer, distrtimer;
229 pl = players.sort_next;
232 if(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)
233 if(pl.scores(ps_primary) == 0)
236 score = me.(scores(ps_primary));
237 timer = TIME_ENCODED_TOSTRING(score);
239 draw_beginBoldFont();
240 if (pl && ((!(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)) || score)) {
241 // distribution display
242 distribution = me.(scores(ps_primary)) - pl.(scores(ps_primary));
244 distrtimer = ftos_decimals(fabs(distribution/(10 ** TIME_DECIMALS)), TIME_DECIMALS);
246 if (distribution <= 0) {
247 distribution_color = '0 1 0';
251 distribution_color = '1 0 0';
254 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);
256 // race record display
257 if (distribution <= 0)
258 HUD_Panel_DrawHighlight(pos, vec2(0.75 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
259 drawstring_aspect(pos, timer, vec2(0.75 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
261 } else if (!teamplay) { // non-teamgames
262 if ((spectatee_status == -1 && !autocvar__hud_configure) || autocvar_hud_panel_score_rankings)
264 HUD_Score_Rankings(pos, mySize, me);
267 // me vector := [team/connected frags id]
268 pl = players.sort_next;
272 if(autocvar__hud_configure)
275 distribution = me.(scores(ps_primary)) - pl.(scores(ps_primary));
279 score = me.(scores(ps_primary));
280 if(autocvar__hud_configure)
283 if(distribution >= 5)
284 distribution_color = eY;
285 else if(distribution >= 0)
286 distribution_color = '1 1 1';
287 else if(distribution >= -5)
288 distribution_color = '1 1 0';
290 distribution_color = eX;
292 string distribution_str;
293 distribution_str = ftos(distribution);
294 draw_beginBoldFont();
295 if (distribution >= 0)
297 if (distribution > 0)
298 distribution_str = strcat("+", distribution_str);
299 HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
301 drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize.x + eY * mySize.y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
302 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);
304 } else { // teamgames
305 float row, column, rows = 0, columns = 0;
306 vector offset = '0 0 0';
307 vector score_pos, score_size; //for scores other than myteam
308 if(autocvar_hud_panel_score_rankings)
310 HUD_Score_Rankings(pos, mySize, me);
313 if(spectatee_status == -1)
315 rows = HUD_GetRowCount(team_count, mySize, 3);
316 columns = ceil(team_count/rows);
317 score_size = vec2(mySize.x / columns, mySize.y / rows);
320 if(score_size.x/score_size.y > 3)
322 newSize = 3 * score_size.y;
323 offset.x = score_size.x - newSize;
325 score_size.x = newSize;
329 newSize = 1/3 * score_size.x;
330 offset.y = score_size.y - newSize;
332 score_size.y = newSize;
336 score_size = vec2(mySize.x / 4, mySize.y / 3);
340 draw_beginBoldFont();
342 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
343 if(tm.team == NUM_SPECTATOR)
348 score = tm.(teamscores(ts_primary));
349 if(autocvar__hud_configure)
352 if (score > max_fragcount)
353 max_fragcount = score;
355 if (spectatee_status == -1)
357 score_pos = pos + vec2(column * (score_size.x + offset.x), row * (score_size.y + offset.y));
358 if (max_fragcount == score)
359 HUD_Panel_DrawHighlight(score_pos, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
360 drawstring_aspect(score_pos, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
368 else if(tm.team == myteam) {
369 if (max_fragcount == score)
370 HUD_Panel_DrawHighlight(pos, vec2(0.75 * mySize.x, mySize.y), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
371 drawstring_aspect(pos, ftos(score), vec2(0.75 * mySize.x, mySize.y), Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
373 if (max_fragcount == score)
374 HUD_Panel_DrawHighlight(pos + vec2(0.75 * mySize.x, (1/3) * rows * mySize.y), score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
375 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);