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