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