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