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