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