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