]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/client/hud/panel/score.qc
Implement fading of panels when showing the scoreboard making use of a new show flag
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / hud / panel / score.qc
1 #include "score.qh"
2
3 #include "scoreboard.qh"
4 #include <common/ent_cs.qh>
5 #include <common/mapinfo.qh>
6
7 // Score (#7)
8
9 void Scoreboard_UpdatePlayerTeams();
10 void HUD_Score_Rankings(vector pos, vector mySize, entity me)
11 {
12         float score;
13         entity tm = NULL, pl;
14         int SCOREPANEL_MAX_ENTRIES = 6;
15         float SCOREPANEL_ASPECTRATIO = 2;
16         int entries = bound(1, floor(SCOREPANEL_MAX_ENTRIES * mySize.y/mySize.x * SCOREPANEL_ASPECTRATIO), SCOREPANEL_MAX_ENTRIES);
17         vector fontsize = '1 1 0' * (mySize.y/entries);
18
19         vector rgb, score_color;
20         rgb = '1 1 1';
21         score_color = '1 1 1';
22
23         float name_size = mySize.x*0.75;
24         float spacing_size = mySize.x*0.04;
25         const float highlight_alpha = 0.2;
26         int i = 0, first_pl = 0;
27         bool me_printed = false;
28         string s;
29         if (autocvar__hud_configure)
30         {
31                 float players_per_team = 0;
32                 if (team_count)
33                 {
34                         // show team scores in the first line
35                         float score_size = mySize.x / team_count;
36                         players_per_team = max(2, ceil((entries - 1) / team_count));
37                         for(i=0; i<team_count; ++i) {
38                                 if (i == floor((entries - 2) / players_per_team) || (entries == 1 && i == 0))
39                                         HUD_Panel_DrawHighlight(pos + eX * score_size * i, eX * score_size + eY * fontsize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
40                                 drawstring_aspect(pos + eX * score_size * i, ftos(175 - 23*i), eX * score_size + eY * fontsize.y, Team_ColorRGB(ColorByTeam(i)) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
41                         }
42                         first_pl = 1;
43                         pos.y += fontsize.y;
44                 }
45                 score = 10 + SCOREPANEL_MAX_ENTRIES * 3;
46                 for (i=first_pl; i<entries; ++i)
47                 {
48                         //simulate my score is lower than all displayed players,
49                         //so that I don't appear at all showing pure rankings.
50                         //This is to better show the difference between the 2 ranking views
51                         if (i == entries-1 && autocvar_hud_panel_score_rankings == 1)
52                         {
53                                 rgb = '1 1 0';
54                                 drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
55                                 s = entcs_GetName(player_localnum);
56                                 score = 7;
57                         }
58                         else
59                         {
60                                 s = sprintf(_("Player %d"), i + 1 - first_pl);
61                                 score -= 3;
62                         }
63
64                         if (team_count)
65                                 score_color = Team_ColorRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
66                         s = textShortenToWidth(s, name_size, fontsize, stringwidth_colors);
67                         drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
68                         drawstring(pos + eX * (name_size + spacing_size), ftos(score), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
69                         pos.y += fontsize.y;
70                 }
71                 return;
72         }
73
74         if (!scoreboard_fade_alpha) // the scoreboard too calls Scoreboard_UpdatePlayerTeams
75                 Scoreboard_UpdatePlayerTeams();
76         if (team_count)
77         {
78                 // show team scores in the first line
79                 float score_size = mySize.x / team_count;
80                 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
81                         if(tm.team == NUM_SPECTATOR)
82                                 continue;
83                         if(!tm.team)
84                                 continue;
85
86                         if (tm.team == myteam)
87                                 drawfill(pos + eX * score_size * i, eX * score_size + eY * fontsize.y, '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
88                         drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores(ts_primary))), eX * score_size + eY * fontsize.y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
89                         ++i;
90                 }
91                 first_pl = 1;
92                 pos.y += fontsize.y;
93                 tm = teams.sort_next;
94         }
95         i = first_pl;
96
97         do
98         for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
99         {
100                 if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
101                         continue;
102
103                 if (i == entries-1 && !me_printed && pl != me)
104                 if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
105                 {
106                         for (pl = me.sort_next; pl; pl = pl.sort_next)
107                                 if (pl.team != NUM_SPECTATOR)
108                                         break;
109
110                         if (pl)
111                                 rgb = '1 1 0'; //not last but not among the leading players: yellow
112                         else
113                                 rgb = '1 0 0'; //last: red
114                         pl = me;
115                 }
116
117                 if (pl == me)
118                 {
119                         if (i == first_pl)
120                                 rgb = '0 1 0'; //first: green
121                         me_printed = true;
122                         drawfill(pos, eX * mySize.x + eY * fontsize.y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
123                 }
124                 if (team_count)
125                         score_color = Team_ColorRGB(pl.team) * 0.8;
126                 s = textShortenToWidth(entcs_GetName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
127                 drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, true, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
128                 drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores(ps_primary))), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
129                 pos.y += fontsize.y;
130                 ++i;
131         }
132         while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
133 }
134
135 void HUD_Score()
136 {
137         if(!autocvar__hud_configure)
138         {
139                 if(!autocvar_hud_panel_score) return;
140                 if(spectatee_status == -1 && (gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) return;
141         }
142
143         HUD_Panel_LoadCvars();
144         vector pos, mySize;
145         pos = panel_pos;
146         mySize = panel_size;
147
148         if (autocvar_hud_panel_score_dynamichud)
149                 HUD_Scale_Enable();
150         else
151                 HUD_Scale_Disable();
152         HUD_Panel_DrawBg();
153         if(panel_bg_padding)
154         {
155                 pos += '1 1 0' * panel_bg_padding;
156                 mySize -= '2 2 0' * panel_bg_padding;
157         }
158
159         float score, distribution = 0;
160         string sign;
161         vector distribution_color;
162         entity tm, pl, me;
163
164         me = playerslots[current_player];
165
166         if((scores_flags(ps_primary) & SFL_TIME) && !teamplay) { // race/cts record display on HUD
167                 string timer, distrtimer;
168
169                 pl = players.sort_next;
170                 if(pl == me)
171                         pl = pl.sort_next;
172                 if(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)
173                         if(pl.scores(ps_primary) == 0)
174                                 pl = NULL;
175
176                 score = me.(scores(ps_primary));
177                 timer = TIME_ENCODED_TOSTRING(score);
178
179                 draw_beginBoldFont();
180                 if (pl && ((!(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)) || score)) {
181                         // distribution display
182                         distribution = me.(scores(ps_primary)) - pl.(scores(ps_primary));
183
184                         distrtimer = ftos_decimals(fabs(distribution/pow(10, TIME_DECIMALS)), TIME_DECIMALS);
185
186                         if (distribution <= 0) {
187                                 distribution_color = '0 1 0';
188                                 sign = "-";
189                         }
190                         else {
191                                 distribution_color = '1 0 0';
192                                 sign = "+";
193                         }
194                         drawstring_aspect(pos + eX * 0.75 * mySize.x, strcat(sign, distrtimer), eX * 0.25 * mySize.x + eY * (1/3) * mySize.y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
195                 }
196                 // race record display
197                 if (distribution <= 0)
198                         HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
199                 drawstring_aspect(pos, timer, eX * 0.75 * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
200                 draw_endBoldFont();
201         } else if (!teamplay) { // non-teamgames
202                 if ((spectatee_status == -1 && !autocvar__hud_configure) || autocvar_hud_panel_score_rankings)
203                 {
204                         HUD_Score_Rankings(pos, mySize, me);
205                         return;
206                 }
207                 // me vector := [team/connected frags id]
208                 pl = players.sort_next;
209                 if(pl == me)
210                         pl = pl.sort_next;
211
212                 if(autocvar__hud_configure)
213                         distribution = 42;
214                 else if(pl)
215                         distribution = me.(scores(ps_primary)) - pl.(scores(ps_primary));
216                 else
217                         distribution = 0;
218
219                 score = me.(scores(ps_primary));
220                 if(autocvar__hud_configure)
221                         score = 123;
222
223                 if(distribution >= 5)
224                         distribution_color = eY;
225                 else if(distribution >= 0)
226                         distribution_color = '1 1 1';
227                 else if(distribution >= -5)
228                         distribution_color = '1 1 0';
229                 else
230                         distribution_color = eX;
231
232                 string distribution_str;
233                 distribution_str = ftos(distribution);
234                 draw_beginBoldFont();
235                 if (distribution >= 0)
236                 {
237                         if (distribution > 0)
238                                 distribution_str = strcat("+", distribution_str);
239                         HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
240                 }
241                 drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize.x + eY * mySize.y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
242                 drawstring_aspect(pos + eX * 0.75 * mySize.x, distribution_str, eX * 0.25 * mySize.x + eY * (1/3) * mySize.y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
243                 draw_endBoldFont();
244         } else { // teamgames
245                 float row, column, rows = 0, columns = 0;
246                 vector offset = '0 0 0';
247                 vector score_pos, score_size; //for scores other than myteam
248                 if(autocvar_hud_panel_score_rankings)
249                 {
250                         HUD_Score_Rankings(pos, mySize, me);
251                         return;
252                 }
253                 if(spectatee_status == -1)
254                 {
255                         rows = HUD_GetRowCount(team_count, mySize, 3);
256                         columns = ceil(team_count/rows);
257                         score_size = eX * mySize.x*(1/columns) + eY * mySize.y*(1/rows);
258
259                         float newSize;
260                         if(score_size.x/score_size.y > 3)
261                         {
262                                 newSize = 3 * score_size.y;
263                                 offset.x = score_size.x - newSize;
264                                 pos.x += offset.x/2;
265                                 score_size.x = newSize;
266                         }
267                         else
268                         {
269                                 newSize = 1/3 * score_size.x;
270                                 offset.y = score_size.y - newSize;
271                                 pos.y += offset.y/2;
272                                 score_size.y = newSize;
273                         }
274                 }
275                 else
276                         score_size = eX * mySize.x*(1/4) + eY * mySize.y*(1/3);
277
278                 float max_fragcount;
279                 max_fragcount = -99;
280                 draw_beginBoldFont();
281                 row = column = 0;
282                 for(tm = teams.sort_next; tm; tm = tm.sort_next) {
283                         if(tm.team == NUM_SPECTATOR)
284                                 continue;
285                         if(!tm.team)
286                                 continue;
287
288                         score = tm.(teamscores(ts_primary));
289                         if(autocvar__hud_configure)
290                                 score = 123;
291
292                         if (score > max_fragcount)
293                                 max_fragcount = score;
294
295                         if (spectatee_status == -1)
296                         {
297                                 score_pos = pos + eX * column * (score_size.x + offset.x) + eY * row * (score_size.y + offset.y);
298                                 if (max_fragcount == score)
299                                         HUD_Panel_DrawHighlight(score_pos, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
300                                 drawstring_aspect(score_pos, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
301                                 ++row;
302                                 if(row >= rows)
303                                 {
304                                         row = 0;
305                                         ++column;
306                                 }
307                         }
308                         else if(tm.team == myteam) {
309                                 if (max_fragcount == score)
310                                         HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
311                                 drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize.x + eY * mySize.y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
312                         } else {
313                                 if (max_fragcount == score)
314                                         HUD_Panel_DrawHighlight(pos + eX * 0.75 * mySize.x + eY * (1/3) * rows * mySize.y, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
315                                 drawstring_aspect(pos + eX * 0.75 * mySize.x + eY * (1/3) * rows * mySize.y, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
316                                 ++rows;
317                         }
318                 }
319                 draw_endBoldFont();
320         }
321 }