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