]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/client/sbar.qc
oops
[divverent/nexuiz.git] / data / qcsrc / client / sbar.qc
1
2 float sb_lines; // still don't know what to do with that NOTE: check dp's sbar.c to see what that should be
3
4 vector sbar;
5 vector sbar_fontsize;
6
7 entity sortedPlayers;
8 entity sortedTeams;
9
10 .float sb_frags;
11 .float sb_team;
12 .float sb_player;
13 .float sb_caps;
14
15 void Sbar_FinaleOverlay()
16 {
17         vector pos;
18         pos_x = (vid_conwidth - 1)/2;
19         pos_y = 16;
20         pos_z = 0;
21         drawpic(pos, "gfx/finale", '0 0', '1 1 1', sbar_alpha_fg, DRAWFLAG_NORMAL);
22 }
23
24 void Sbar_DrawWeapon(float nr, float fade, float active)
25 {
26         vector pos, vsize, color;
27         float value;
28         
29         value = (active) ? 1 : 0.6;
30         color_x = color_y = color_z = value;
31         
32         if(sbar_hudselector == 1)
33         {
34                 // width = 300, height = 100
35                 const float w_width = 32, w_height = 12, w_space = 2, font_size = 8;
36                 
37                 pos_x = (vid_conwidth - w_width * 9) * 0.5 + w_width * nr;
38                 pos_y = (vid_conheight - w_height);
39                 pos_z = 0;
40                 vsize_x = w_width;
41                 vsize_y = w_height;
42                 vsize_z = 0;
43                 drawpic(pos, strcat("gfx/inv_weapon", ftos(nr)), vsize, color, value * fade * sbar_alpha_fg, 0);
44                 pos_x += w_space;
45                 pos_y += w_space;
46                 vsize_x = font_size;
47                 vsize_y = font_size;
48                 vsize_z = 0;
49                 drawstring(pos, ftos(nr+1), vsize, '1 1 0', sbar_alpha_fg, 0);
50
51         }
52         else
53         {
54                 // width = 300, height = 100
55                 const float w2_width = 300, w2_height = 100, w2_space = 10;
56                 const float w2_scale = 0.4;
57
58                 pos_x = vid_conwidth - (w2_width + w2_space) * w2_scale;
59                 pos_y = (w2_height + w2_space) * w2_scale * nr + w2_space;
60                 pos_z = 0;
61                 vsize_x = w2_width * w2_scale;
62                 vsize_y = w2_height * w2_scale;
63                 vsize_z = 0;
64                 
65                 drawpic(pos, strcat("gfx/inv_weapon", ftos(nr)), vsize, color, value * fade * sbar_alpha_fg, 0);
66         }
67 }
68 void Sbar_DrawXNum (vector pos, float num, float digits, float lettersize, vector rgb, float a, float dflags)
69 {
70         float l, i;
71         string str, tmp;
72         float minus;
73         vector vsize;
74
75         vsize_x = vsize_y = lettersize;
76         vsize_z = 0;
77
78         if(num < 0)
79         {
80                 minus = true;
81                 num = -num;
82                 pos_x -= lettersize;
83         } else
84                 minus = false;
85         
86         if(digits < 0)
87         {
88                 tmp = ftos(num);
89                 digits = -digits;
90                 str = strcat(substring("0000000000", 0, digits - strlen(tmp)), tmp);
91         } else
92                 str = ftos(num);
93         
94         l = strlen(str);
95
96         if(l > digits)
97         {
98                 str = substring(str, l-digits, 999);
99                 l = strlen(str);
100         } else if(l < digits)
101                 pos_x += (digits-l) * lettersize;
102
103         if(minus)
104         {
105                 drawpic(sbar + pos, "gfx/num_minus", vsize, rgb, a * sbar_alpha_fg, dflags);
106                 pos_x += lettersize;
107         }
108
109         for(i = 0; i < l; ++i)
110         {
111                 drawpic(sbar + pos, strcat("gfx/num_", substring(str, i, 1)), vsize, rgb, a * sbar_alpha_fg, dflags);
112                 pos_x += lettersize;
113         }
114 }
115
116 float Sbar_PlayerCmp(entity l, entity r)
117 {
118         if(teamplay)
119         {
120                 if(l.sb_team > r.sb_team)
121                         return true;
122                 else if(l.sb_team > r.sb_team)
123                         return false;
124                 if(gametype == GAME_CTF)
125                 {
126                         if(l.sb_caps > r.sb_caps)
127                                 return true;
128                         else if(l.sb_caps < r.sb_caps)
129                                 return false;
130                 }
131         }
132         if(l.sb_frags > r.sb_frags)
133                 return true;
134         else if(l.sb_frags < r.sb_frags)
135                 return false;
136         return (l.sb_player > r.sb_player);
137 }
138 float Sbar_TeamCmp(entity l, entity r)
139 {
140         if(gametype == GAME_CTF)
141         {
142                 if(l.sb_caps > r.sb_caps)
143                         return true;
144                 else if(l.sb_caps < r.sb_caps)
145                         return false;
146         }
147         if(l.sb_frags > r.sb_frags)
148                 return true;
149         else if(l.sb_frags < r.sb_frags)
150                 return false;
151         return (l.sb_player > r.sb_player);
152 }
153
154 void Sbar_SortFrags()
155 {
156         float i;
157         entity tmp;
158         entity t1, t2, t3, t4, ts;
159         
160         Sort_Remove(sortedPlayers);
161         sortedPlayers = Sort_New(Sbar_PlayerCmp);
162
163         numteams = 0;
164         if(teamplay)
165         {
166                 Sort_Remove(sortedTeams);
167         
168                 t1 = spawn();
169                 t2 = spawn();
170                 t3 = spawn();
171                 t4 = spawn();
172                 ts = spawn();
173         
174                 t1.sb_team = COLOR_TEAM1;
175                 t2.sb_team = COLOR_TEAM2;
176                 t3.sb_team = COLOR_TEAM3;
177                 t4.sb_team = COLOR_TEAM4;
178                 ts.sb_team = COLOR_SPECTATOR;
179
180                 t1.sb_player = t2.sb_player = t3.sb_player = t4.sb_player = ts.sb_player = 0;
181                 t1.sb_frags = t2.sb_frags = t3.sb_frags = t4.sb_frags = 0;
182                 t1.sb_caps = caps_team1;
183                 t2.sb_caps = caps_team2;
184                 sortedTeams = Sort_New(Sbar_TeamCmp);
185                 
186                 for(i = 0; i < maxclients; ++i)
187                 {
188                         if(strlen(getplayerkey(i, "name")) <= 0)
189                                 continue;
190                 
191                         tmp = spawn();
192                         tmp.sb_player = i;
193                         tmp.sb_frags = stof(getplayerkey(i, "frags"));
194                         tmp.sb_caps = stof(bufstr_get(databuf, DATABUF_CAPTURES + tmp.sb_player));
195                         
196                         if(tmp.sb_frags == -666)
197                                 tmp.sb_team = COLOR_SPECTATOR;
198                         else
199                                 tmp.sb_team = GetPlayerColor(i);
200
201                         switch(tmp.sb_team)
202                         {
203                         case COLOR_TEAM1: t1.sb_frags += tmp.sb_frags; t1.sb_player++; break;
204                         case COLOR_TEAM2: t2.sb_frags += tmp.sb_frags; t2.sb_player++; break;
205                         case COLOR_TEAM3: t3.sb_frags += tmp.sb_frags; t3.sb_player++; break;
206                         case COLOR_TEAM4: t4.sb_frags += tmp.sb_frags; t4.sb_player++; break;
207                         case COLOR_SPECTATOR: ts.sb_frags += tmp.sb_frags; ts.sb_player++; break;
208                         }
209
210                         if(i == player_localentnum-1)
211                                 myteam = tmp.sb_team;
212
213                         Sort_Add(sortedPlayers, tmp);
214                 }
215                 if(t1.sb_player) ++numteams;
216                 if(t2.sb_player) ++numteams;
217                 if(t3.sb_player) ++numteams;
218                 if(t4.sb_player) ++numteams;
219
220                 Sort_Add(sortedTeams, t1);
221                 Sort_Add(sortedTeams, t2);
222                 Sort_Add(sortedTeams, t3);
223                 Sort_Add(sortedTeams, t4);
224                 Sort_Add(sortedTeams, ts);
225
226         } else {
227                 for(i = 0; i < maxclients; ++i)
228                 {
229                         if(strlen(getplayerkey(i, "name")) <= 0)
230                                 continue;
231                 
232                         tmp = spawn();
233                         tmp.sb_player = i;
234                         tmp.sb_frags = stof(getplayerkey(i, "frags"));
235                         if(tmp.sb_frags == -666)
236                                 tmp.sb_team = COLOR_SPECTATOR;
237                         else
238                                 tmp.sb_team = COLOR_TEAM1;
239                         Sort_Add(sortedPlayers, tmp);
240                 }
241         }
242 }
243
244 void Cmd_Sbar_Help(float argc)
245 {
246         print("You can modify the scoreboard using the\n");
247         print("^3|---------------------------------------------------------------|\n");
248         print("^2sbar_columns^7 cvar and the ^2sbar_columns_set command.\n");
249         print("^2sbar_columns^7             specifies the default layout and\n");
250         print("^2sbar_columns_set^7         actually changes the layout.\n");
251         print("You can call ^2sbar_columns_set^7 with the new layout\n");
252         print("as parameters, or eithout parameters it will read the cvar.\n\n");
253         print("Usage:\n");
254         print("^2sbar_columns_set ^7filed1 field2 ...\n");
255         print("Fields which are not relevant to the current gametype\n");
256         print("won't be displayed\n\n");
257         print("The following field names are recognized (case INsensitive):\n");
258         print("^3name^7 or ^3nick^7             Name of a player\n");
259         print("^3caps^7 or ^3captures^7         Number of flags captured\n");
260         print("^3rets^7 or ^3returns^7          Number of flags returned\n");
261         print("^3frags^7 or ^3kills^7           Frags\n");
262         print("^3deaths^7 or ^3dths^7           Number of deaths\n");
263         print("^3kd^7 or ^3kdr^7 or ^3kdratio^7 or ^3k/d\n");
264         print("                         The kill-death ratio\n");
265         print("^3ping^7                     Ping time\n\n");
266         print("You can use a ^3|^7 to start the right-aligned fields.\n");
267         print("Example: ping name | caps rets frags k/d\n");
268         print("This will put the ping and the name on the left side.\n");
269         print("The captures, returns, frags and kill-death ratio will be\n");
270         print("rendered beginning on the right side.\n");
271
272 }
273
274 #define MIN_NAMELEN 24
275 #define MAX_NAMELEN 24
276
277 void Cmd_Sbar_SetFields(float argc)
278 {
279         float i;
280         string str;
281         float digit;
282
283         if(argc < 2)
284                 argc = tokenize(strcat("x ", cvar_string("sbar_columns")));
285         
286         argc = min(MAX_SBAR_FIELDS, argc);
287         sbar_num_fields = 0;
288         drawfont = FONT_USER+1;
289         digit = stringwidth("0123456789", FALSE) / 10;
290         for(i = 0; i < argc-1; ++i)
291         {
292                 str = argv(i+1);
293                 strunzone(sbar_title[i]);
294                 sbar_title[i] = strzone(str);
295                 sbar_size[i] = stringwidth(str, FALSE);
296                 str = strtolower(str);
297                 if(str == "ping") {
298                         sbar_field[i] = SBF_PING;
299                 } else if(str == "name" || str == "nick") {
300                         sbar_field[i] = SBF_NAME;
301                         sbar_size[i] = MIN_NAMELEN; // minimum size? any use?
302                 } else if(str == "caps" || str == "captures") {
303                         if(sbar_size[i] < 3*digit)
304                                 sbar_size[i] = 3*digit;
305                         sbar_field[i] = SBF_CAPS;
306                 } else if(str == "rets" || str == "returns") {
307                         if(sbar_size[i] < 3*digit)
308                                 sbar_size[i] = 3*digit;
309                         sbar_field[i] = SBF_RETS;
310                 } else if(str == "frags" || str == "kills") {
311                         if(sbar_size[i] < 5*digit)
312                                 sbar_size[i] = 5*digit;
313                         sbar_field[i] = SBF_FRAGS;
314                 } else if(str == "deaths" || str == "dths") {
315                         if(sbar_size[i] < 5*digit)
316                                 sbar_size[i] = 5*digit;
317                         sbar_field[i] = SBF_DEATHS;
318                 } else if(str == "kdratio") {
319                         sbar_field[i] = SBF_KDRATIO;
320                 } else if(str == "kdr" || str == "k/d") {
321                         sbar_field[i] = SBF_KDRATIO;
322                 } else if(str == "kd") {
323                         sbar_field[i] = SBF_KDRATIO;
324                 } else if(str == "|") {
325                         sbar_field[i] = SBF_SEPARATOR;
326                 } else {
327                         print(strcat("^1Error:^7 Unknown score field: '", str, "'\n"));
328                         --sbar_num_fields;
329                 }
330                 ++sbar_num_fields;
331         }
332         sbar_field[i] = SBF_END;
333 }
334
335 vector sbar_field_rgb;
336 string Sbar_GetField(entity pl, float field)
337 {
338         float tmp;
339         string str;
340         sbar_field_rgb = '1 1 1';
341         switch(field)
342         {
343         case SBF_PING:
344                 str = bufstr_get(databuf, DATABUF_PING + pl.sb_player);
345                 tmp = max(0, min(220, stof(str)-80)) / 220;
346                 sbar_field_rgb = '1 1 1' - '0 1 1'*tmp;
347                 return str;
348         case SBF_NAME: return getplayerkey(pl.sb_player, "name");
349         case SBF_CAPS: return ftos(pl.sb_caps);
350         case SBF_RETS: return bufstr_get(databuf, DATABUF_RETURNS + pl.sb_player);
351         case SBF_FRAGS: return ftos(pl.sb_frags);
352         case SBF_DEATHS: return bufstr_get(databuf, DATABUF_DEATHS + pl.sb_player);
353         case SBF_KDRATIO:
354                 tmp = stof(bufstr_get(databuf, DATABUF_DEATHS + pl.sb_player));
355                 if(tmp == 0) {
356                         sbar_field_rgb = '0 1 0';
357                         str = ftos(pl.sb_frags);
358                 } else if(pl.sb_frags <= 0) {
359                         sbar_field_rgb = '1 0 0';
360                         str = ftos(pl.sb_frags / tmp);
361                 } else
362                         str = ftos(pl.sb_frags / tmp);
363                 
364                 tmp = strstrofs(str, ".", 0);
365                 if(tmp > 0)
366                         str = substring(str, 0, tmp+2);
367                 return str;
368         }
369 }
370
371 float Sbar_IsFieldMasked(float field, float mask)
372 {
373         if(mask&1) // spectator
374                 return (field != SBF_NAME && field != SBF_PING);
375         if(gametype != GAME_CTF)
376                 return (field == SBF_CAPS || field == SBF_RETS);
377         return false;
378 }
379
380 // shamelessly stolen from menu QC :P
381 float textLengthUpToWidth(string theText, float maxWidth, float handleColors)
382 {
383         // STOP.
384         // The following function is SLOW.
385         // For your safety and for the protection of those around you...
386         // DO NOT CALL THIS AT HOME.
387         // No really, don't.
388         if(stringwidth(theText, handleColors) <= maxWidth)
389                 return strlen(theText); // yeah!
390
391         // binary search for right place to cut string
392         float left, right, middle; // this always works
393         left = 0;
394         right = strlen(theText); // this always fails
395         do
396         {
397                 middle = floor((left + right) / 2);
398                 if(stringwidth(substring(theText, 0, middle), handleColors) <= maxWidth)
399                         left = middle;
400                 else
401                         right = middle;
402         }
403         while(left < right - 1);
404
405         // NOTE: when color codes are involved, this binary search is,
406         // mathematically, BROKEN. However, it is obviously guaranteed to
407         // terminate, as the range still halves each time - but nevertheless, it is
408         // guaranteed that it finds ONE valid cutoff place (where "left" is in
409         // range, and "right" is outside).
410
411         return left;
412 }
413 string textShortenToWidth(string theText, float maxWidth, float handleColors)
414 {
415         if(stringwidth(theText, handleColors) <= maxWidth)
416                 return theText;
417         else
418                 return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - stringwidth("...", handleColors), handleColors)), "...");
419 }
420
421 float xmin, xmax, ymin, ymax, sbwidth, sbheight;
422 void Sbar_PrintScoreboardItem(vector pos, entity pl, float is_self, float mask)
423 {
424         vector tmp;
425         string str, tempstr;
426         float i, field, len;
427
428         // Layout:
429         tmp_z = 0;
430         if(is_self)
431         {
432                 tmp_x = sbwidth;
433                 tmp_y = sbar_fontsize_y;
434                 drawfill(pos - '1 1', tmp + '2 2', '1 1 1', 0.3, DRAWFLAG_NORMAL);
435         }       
436         tmp_y = 0;
437         
438         for(i = 0; i < sbar_num_fields; ++i)
439         {
440                 field = sbar_field[i];
441                 if(field == SBF_SEPARATOR)
442                         break;
443                 if(Sbar_IsFieldMasked(field, mask))
444                         continue;
445
446                 str = Sbar_GetField(pl, field);
447
448                 if(field == SBF_NAME)
449                 {
450                         float realsize;
451                         float j;
452                         realsize = sbar_size[i];
453                         if(i+1 < sbar_num_fields)
454                                 if(sbar_field[i+1] == SBF_SEPARATOR)
455                                 {
456                                         realsize = (xmax - xmin) / sbar_fontsize_x;
457                                         for(j = 0; j < sbar_num_fields; ++j) if(j != i) if(sbar_field[j] != SBF_SEPARATOR)
458                                                 realsize -= sbar_size[j] + 1;
459                                         realsize += 1;
460                                 }
461                         str = textShortenToWidth(str, realsize, TRUE);
462                 }
463                 len = stringwidth(str, TRUE);
464                 
465                 if(sbar_size[i] < len)
466                         sbar_size[i] = len;
467
468                 pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
469                 if(field == SBF_NAME) {
470                         tmp_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
471                         drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
472                 } else {
473                         tmp_x = len*sbar_fontsize_x + sbar_fontsize_x;
474                         drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, 1, DRAWFLAG_NORMAL);
475                 }
476         }
477         
478         if(sbar_field[i] == SBF_SEPARATOR)
479         {
480                 pos_x = xmax;
481                 for(i = sbar_num_fields-1; i > 0; --i)
482                 {
483                         field = sbar_field[i];
484                         if(field == SBF_SEPARATOR)
485                                 break;
486                         if(Sbar_IsFieldMasked(field, mask))
487                                 continue;
488                         
489                         str = Sbar_GetField(pl, field);
490
491                         if(field == SBF_NAME)
492                                 str = textShortenToWidth(str, sbar_size[i], TRUE);
493                         len = stringwidth(str, TRUE);
494
495                         if(sbar_size[i] < len)
496                                 sbar_size[i] = len;
497                         
498                         if(field == SBF_NAME) {
499                                 tmp_x = sbar_fontsize_x*len; // left or right aligned? let's put it right...
500                                 drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
501                         } else {
502                                 tmp_x = sbar_fontsize_x*len; //strlen(str);
503                                 drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, 1, DRAWFLAG_NORMAL);
504                         }
505                         pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
506                 }
507         }
508 }
509
510 void Sbar_DrawScoreboard()
511 {
512         //float xmin, ymin, xmax, ymax;
513         vector rgb, pos, tmp, sbar_save;
514         entity pl, tm;
515         float specs, i;
516         float center_x;
517         string str;
518
519         sbar_fontsize = stov(cvar_string("sbar_fontsize"));
520         if(sbar_fontsize_x == 0)
521                 sbar_fontsize = '8 8 0';
522         if(sbar_fontsize_y == 0)
523                 sbar_fontsize_y = sbar_fontsize_x;
524         
525         xmin = vid_conwidth / 5;
526         ymin = 20;
527
528         xmax = vid_conwidth - xmin;
529         ymax = vid_conheight - 0.2*vid_conheight;
530
531         sbwidth = xmax - xmin;
532         sbheight = ymax - ymin;
533
534         center_x = xmin + 0.5*sbwidth;
535
536         //Sbar_UpdateFields();
537
538         // Initializes position
539         //pos_x = xmin;
540         pos_y = ymin;
541         pos_z = 0;
542
543         // Heading
544         drawfont = FONT_USER+1;
545         pos_x = center_x - stringwidth("Scoreboard", TRUE)*0.5*24;
546         drawstring(pos, "Scoreboard", '24 24', '1 1 1', 1, DRAWFLAG_NORMAL);
547         pos_x = xmin;
548         pos_y += 24 + 4;
549
550         // Titlebar background:
551         tmp_x = sbwidth;
552         tmp_y = sbar_fontsize_y;
553         drawfill(pos - '1 1', tmp + '2 2', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
554         
555         for(i = 0; i < sbar_num_fields; ++i)
556         {
557                 if(sbar_field[i] == SBF_SEPARATOR)
558                         break;
559                 drawstring(pos, sbar_title[i], sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
560                 pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
561         }
562         
563         if(sbar_field[i] == SBF_SEPARATOR)
564         {
565                 pos_x = xmax + sbar_fontsize_x;
566                 tmp_y = tmp_z = 0;
567                 for(i = sbar_num_fields-1; i > 0; --i)
568                 {
569                         if(sbar_field[i] == SBF_SEPARATOR)
570                                 break;
571                         
572                         pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
573                         /**
574                          * FTEQCC BUG!
575                          * Using the following line will fuck it all up:
576                          **
577                          * tmp_x = sbar_size[i] - strlen(sbar_title[i])*8;
578                          */
579                         tmp_x = sbar_fontsize_x*sbar_size[i];
580                         tmp_x -= stringwidth(sbar_title[i], FALSE)*sbar_fontsize_x;
581                         drawstring(pos + tmp, sbar_title[i], sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
582                 }
583         }
584                 
585         pos_x = xmin;
586         pos_y += 1.5 * sbar_fontsize_y;
587
588         sbar_save = sbar;
589         sbar = '0 0 0';
590         
591         if(teamplay)
592         {
593                 for(tm = sortedTeams.sort_next; tm; tm = tm.sort_next)
594                 {
595                         if(!tm.sb_player || tm.sb_team == COLOR_SPECTATOR) // no players in it?
596                                 continue;
597
598                         rgb = GetTeamRGB(tm.sb_team);
599
600                         pos_x = xmin - 4*24;
601                         if(gametype == GAME_CTF)
602                         {
603                                 if(tm.sb_team == COLOR_TEAM1)
604                                         Sbar_DrawXNum(pos, caps_team1, 4, 24, rgb, 1, DRAWFLAG_NORMAL);
605                                 else if(tm.sb_team == COLOR_TEAM2)
606                                         Sbar_DrawXNum(pos, caps_team2, 4, 24, rgb, 1, DRAWFLAG_NORMAL);
607                                 pos_x = xmin - 4*10;
608                                 Sbar_DrawXNum(pos + '0 24', tm.sb_frags, 4, 10, rgb, 1, DRAWFLAG_NORMAL);
609                                 pos_x = xmin;
610                         } else
611                                 Sbar_DrawXNum(pos, tm.sb_frags, 4, 24, rgb, 1, DRAWFLAG_NORMAL);
612                         pos_x = xmin;
613
614                         // abuse specs as playerounter
615                         specs = 0;
616                         for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
617                         {
618                                 if(pl.sb_team == tm.sb_team)
619                                         ++specs;
620                         }
621
622                         if(specs < 2)
623                                 specs = 2;
624                         if(gametype == GAME_CTF && specs < 4)
625                                 specs = 4;
626                         
627                         tmp_x = sbwidth;
628                         tmp_y = 1.25 * sbar_fontsize_y * specs;
629                         drawfill(pos - '1 1', tmp + '2 0', rgb, 0.2, DRAWFLAG_NORMAL);
630                         
631                         for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
632                         {
633                                 if(pl.sb_team != tm.sb_team)
634                                         continue;
635                                 Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 0);
636                                 pos_y += 1.25 * sbar_fontsize_y;
637                                 tmp_y -= 1.25 * sbar_fontsize_y;
638                         }
639                         pos_y += tmp_y + 1.5 * sbar_fontsize_y;
640                 }
641                 // rgb := tempvector :)
642                 rgb = pos + '0 1.5 0' * sbar_fontsize_y;
643                 pos_y += 3 * sbar_fontsize_y;
644                 specs = 0;
645                 for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
646                 {
647                         if(pl.sb_team != COLOR_SPECTATOR)
648                                 continue;
649                         //drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
650                         Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), 1);
651                         pos += '0 1.25 0' * sbar_fontsize_y;
652                         ++specs;
653                 }
654                         
655                 if(specs)
656                         drawstring(rgb, "Spectators", sbar_fontsize, '1 1 1', 1, 0);
657         }
658         sbar = sbar_save;
659 }
660
661 void Sbar_Score(float margin)
662 {
663         float timelimit, timeleft, minutes, seconds, distribution, myplace;
664         vector sbar_save, place;
665         entity tm, pl, me;
666         sbar_save = sbar;
667
668         sbar_y = vid_conheight - (32+12);
669         sbar_x -= margin;
670         
671         place = '-48 -12 0';
672         if(teamplay)
673         {
674                 // Layout:
675                 //
676                 //   team1 team3 team4
677                 //
678                 //         TEAM2
679                 //for(i = 0; i < 4; ++i)
680                 for(tm = sortedTeams.sort_next; tm; tm = tm.sort_next)
681                 {
682                         if(tm.sb_team == COLOR_SPECTATOR || !tm.sb_player) // no players? don't display
683                                 continue;
684                         // -32*4 = -128
685                         if(tm.sb_team == myteam)
686                                 Sbar_DrawXNum('-128 0', tm.sb_frags, 4, 32, GetTeamRGB(tm.sb_team), 1, DRAWFLAG_NORMAL);
687                         else
688                         {
689                                 Sbar_DrawXNum(place, tm.sb_frags, 4, 12, GetTeamRGB(tm.sb_team), 1, DRAWFLAG_NORMAL);
690                                 place_x -= 4*12;
691                         }
692                 }
693         } else {
694                 // me vector := [team/connected frags id]
695                 myplace = 0;
696                 for(me = sortedPlayers.sort_next; me; me = me.sort_next)
697                 {
698                         if(me.sb_team != COLOR_SPECTATOR)
699                                 ++myplace;
700                         if(me.sb_player == player_localentnum - 1)
701                                 break;
702                 }
703                 pl = sortedPlayers.sort_next;
704                 if(pl == me)
705                         pl = pl.sort_next;
706                 
707                 if(pl && myplace != 1)
708                 {
709                         distribution = me.sb_frags - pl.sb_frags;
710                 } else if(pl) {
711                         distribution = me.sb_frags - pl.sb_frags;
712                 } else
713                         distribution = 0;
714                 
715                 if(myplace == 1)
716                         Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
717                 else if(myplace == 2)
718                         Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
719                 else
720                         Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 0 0', 1, DRAWFLAG_NORMAL);
721
722                 if(distribution >= 0)
723                 {
724                         Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 1 1', 1, DRAWFLAG_NORMAL);
725                         Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 1 1', 1, DRAWFLAG_NORMAL);
726                 } else if(distribution >= -5)
727                 {
728                         Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 1 0', 1, DRAWFLAG_NORMAL);
729                         Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 1 0', 1, DRAWFLAG_NORMAL);
730                 } else {
731                         Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 0 0', 1, DRAWFLAG_NORMAL);
732                         Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 0 0', 1, DRAWFLAG_NORMAL);
733                 }
734         }
735         timelimit = getstatf(STAT_TIMELIMIT);
736         if(timelimit)
737         {
738                 timeleft = max(0, timelimit * 60 - time);
739                 minutes = floor(timeleft / 60);
740                 seconds = floor(timeleft - minutes*60);
741                 if(minutes >= 5)
742                 {
743                         Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
744                         drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 1', sbar_alpha_fg, 0);
745                         Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
746                 } else if(minutes >= 1)
747                 {
748                         Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
749                         drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 0', sbar_alpha_fg, 0);
750                         Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
751                 } else {
752                         Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 0 0', 1, DRAWFLAG_NORMAL);
753                 }
754         } else {
755                 minutes = floor(time / 60);
756                 seconds = floor(time - minutes*60);
757                 Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
758                 drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 1', sbar_alpha_fg, 0);
759                 Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
760         }
761         sbar = sbar_save;
762 }
763
764 void Sbar_MiniscoreItem(vector pos, entity pl, float is_self)
765 {
766         float x;
767         pos_x += 72;
768         
769         if(teamplay)
770                 drawfill(pos + '0 1 0', '40 6 0', GetTeamRGB(pl.sb_team)*0.5, 1, DRAWFLAG_NORMAL);
771         else
772                 drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
773         x = pos_x;
774         pos_x += 5*8;
775         pos_x -= stringwidth(ftos(pl.sb_frags), FALSE)*8;
776         drawstring(pos, ftos(pl.sb_frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
777         pos_x = x;
778         if(is_self)
779         {
780                 pos_x += 48;
781                 drawstring(pos, "\x0D", '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
782                 pos_x += 8;
783         } else
784                 pos_x += 56;
785         drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
786 }
787
788 void Sbar_MiniscoreTeamItem(vector pos, float color, float frags, float is_self)
789 {
790         float x;
791         pos_x += 72;
792         
793         if(teamplay)
794                 drawfill(pos + '0 1 0', '40 6 0', GetTeamRGB(color)*0.5, 1, DRAWFLAG_NORMAL);
795         else
796                 drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
797         x = pos_x;
798         pos_x += 5*8;
799         pos_x -= stringwidth(ftos(frags), FALSE)*8;
800         drawstring(pos, ftos(frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
801         pos_x = x;
802         if(is_self)
803         {
804                 pos_x += 48;
805                 drawstring(pos, "\x0D", '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
806                 pos_x += 8;
807         } else
808                 pos_x += 56;
809         drawstring(pos, GetTeamName(color), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
810 }
811
812 void Sbar_MiniDeathmatchOverlay(vector pos)
813 {
814         float numlines, up, down;
815         entity me, tm, pl;
816         float miniscoreboard_size;
817         miniscoreboard_size = cvar("sbar_miniscoreboard_size");
818         
819         if(miniscoreboard_size == 0)
820                 return;
821         pos_y = vid_conheight - 8;
822         
823         if(miniscoreboard_size < 0)
824                 numlines = (vid_conheight - sbar_y + 7) / 8;
825         else
826                 numlines = miniscoreboard_size;
827
828         // give up if there isn't enough room
829         if(pos_x >= vid_conwidth || pos_y >= vid_conheight || numlines < 1)
830                 return;
831
832         // me vector := [team/connected frags id]
833         for(me = sortedPlayers.sort_next; me; me = me.sort_next)
834         {
835                 if(me.sb_player == player_localentnum - 1)
836                         break;
837         }
838
839         if(teamplay)
840                 numlines -= numteams;
841
842         // figure out how many players above and below we can show
843         up = floor(numlines/2);
844         down = up;
845         if((up + down) > numlines)
846                 down = numlines - up;
847
848         // render bottom-up
849         for(pl = me.sort_next; pl && down > 0; pl = pl.sort_next)
850         {
851                 if(pl.sb_team == COLOR_SPECTATOR)
852                         continue;
853                 Sbar_MiniscoreItem(pos, pl, false);
854                 pos_y -= 9;
855                 --down;
856         }
857         Sbar_MiniscoreItem(pos, me, true);
858         pos_y -= 9;
859         up += down; // if there weren't enough lines below... add them
860         for(pl = me.sort_prev; pl != sortedPlayers && up > 0; pl = pl.sort_prev)
861         {
862                 if(pl.sb_team == COLOR_SPECTATOR)
863                         continue;
864                 Sbar_MiniscoreItem(pos, pl, false);
865                 pos_y -= 9;
866                 --up;
867         }
868
869         if(teamplay)
870         {
871                 for(tm = sortedTeams.sort_next; tm.sort_next; tm = tm.sort_next);
872                 for(; tm != sortedTeams; tm = tm.sort_prev)
873                 {
874                         if(!tm.sb_player || tm.sb_team == COLOR_SPECTATOR) // no players?
875                                 continue;
876                         Sbar_MiniscoreTeamItem(pos, tm.sb_team, tm.sb_frags, (tm.sb_team == me.sb_team));
877                         pos_y -= 9;
878                 }
879         }
880 }
881
882 void Sbar_Draw (void)
883 {
884         float i;
885         float x, fade;
886         float stat_items;
887
888         Sbar_SortFrags();
889
890         sb_lines = 24;
891         
892         if (sb_showscores)
893                 Sbar_DrawScoreboard();
894         else if (intermission == 1)
895         {
896                 Sbar_DrawScoreboard();
897                 return;
898         }
899         else if (intermission == 2)
900                 Sbar_FinaleOverlay();
901         else
902         {
903                 if (sb_showscores || (getstati(STAT_HEALTH) <= 0 && cvar("cl_deathscoreboard")))
904                 {
905                         sbar_x = (vid_conwidth - 640.0)*0.5;
906                         sbar_y = vid_conheight - 47;
907                         //Sbar_DrawAlphaPic (sbar_x, sbar_y, sb_scorebar, sbar_alpha_bg.value);
908                         //drawpic('0 0', "gfx/scorebar", '0 0 0', '1 1 1', cvar("sbar_alpha_bg"), 0);
909                         Sbar_DrawScoreboard ();
910                 }
911                 else
912                 {
913                         if (sb_lines && sbar_hudselector == 1)
914                         {
915                                 stat_items = getstati(STAT_ITEMS);
916
917                                 sbar_x = (vid_conwidth - 320.0)*0.5;
918                                 sbar_y = vid_conheight - 24.0 - 16.0;
919                                 sbar_z = 0;
920                         
921                                 fade = 3.2 - 2 * (time - weapontime);
922                                 fade = bound(0.7, fade, 1);
923
924                                 x = 1.0;
925                                 for(i = 0; i < 8; ++i)
926                                 {
927                                         if(stat_items & x)
928                                         {
929                                                 Sbar_DrawWeapon(i+1, fade, (i + 2 == activeweapon));
930                                         }
931                                         x *= 2;
932                                 }
933                                 x *= 2*2*2*2;
934                                 if(stat_items & x)
935                                 {
936                                         Sbar_DrawWeapon(0, fade, (activeweapon == 1));
937                                 }
938
939                                 // armor
940                                 x = getstati(STAT_ARMOR);
941                                 if (x > 0)
942                                 {
943                                         // "gfx/sb_armor"
944                                         //Sbar_DrawStretchPic (72, 0, sb_armor[0], sbar_alpha_fg.value, 24, 24);
945                                         drawpic(sbar + '72 0', "gfx/sb_armor", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
946                                         if(x > 200)
947                                                 Sbar_DrawXNum('0 0', x, 3, 24, '0 1 0', 1, 0);
948                                         else if(x > 100)
949                                                 Sbar_DrawXNum('0 0', x, 3, 24, '0.2 1 0', 1, 0);
950                                         else if(x > 50)
951                                                 Sbar_DrawXNum('0 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
952                                         else if(x > 25)
953                                                 Sbar_DrawXNum('0 0', x, 3, 24, '1 1 0.2', 1, 0);
954                                         else
955                                                 Sbar_DrawXNum('0 0', x, 3, 24, '0.7 0 0', 1, 0);
956                                 }
957
958                                 // health
959                                 x = getstati(STAT_HEALTH);
960                                 if (x != 0)
961                                 {
962                                         // "gfx/sb_health"
963                                         //Sbar_DrawStretchPic (184, 0, sb_health, sbar_alpha_fg.value, 24, 24);
964                                         drawpic(sbar + '184 0', "gfx/sb_health", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
965                                         if(x > 200)
966                                                 Sbar_DrawXNum('112 0', x, 3, 24, '0 1 0', 1, 0);
967                                         else if(x > 100)
968                                                 Sbar_DrawXNum('112 0', x, 3, 24, '0.2 1 0', 1, 0);
969                                         else if(x > 50)
970                                                 Sbar_DrawXNum('112 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
971                                         else if(x > 25)
972                                                 Sbar_DrawXNum('112 0', x, 3, 24, '1 1 0.2', 1, 0);
973                                         else
974                                                 Sbar_DrawXNum('112 0', x, 3, 24, '0.7 0 0', 1, 0);
975                                 }
976
977                                 // ammo
978                                 x = getstati(STAT_AMMO);
979                                 if ((stat_items & (NEX_IT_SHELLS | NEX_IT_BULLETS | NEX_IT_ROCKETS | NEX_IT_CELLS)) || x != 0)
980                                 {
981                                         if (stat_items & NEX_IT_SHELLS)
982                                                 drawpic(sbar + '296 0', "gfx/sb_shells", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
983                                         else if (stat_items & NEX_IT_BULLETS)
984                                                 drawpic(sbar + '296 0', "gfx/sb_bullets", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
985                                         else if (stat_items & NEX_IT_ROCKETS)
986                                                 drawpic(sbar + '296 0', "gfx/sb_rocket", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
987                                         else if (stat_items & NEX_IT_CELLS)
988                                                 drawpic(sbar + '296 0', "gfx/sb_cells", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
989                                         if(x > 10)
990                                                 Sbar_DrawXNum('224 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
991                                         else
992                                                 Sbar_DrawXNum('224 0', x, 3, 24, '0.7 0 0', 1, 0);
993                                 }
994
995                                 if (sbar_x + 320 + 160 <= vid_conwidth)
996                                         Sbar_MiniDeathmatchOverlay(sbar + '320 0');
997                                 if (sbar_x > 0)
998                                         Sbar_Score(16);
999                                 // The margin can be at most 8 to support 640x480 console size:
1000                                 //   320 + 2 * (144 + 16) = 640
1001                         }
1002                         else if (sb_lines)
1003                         {
1004                         
1005                                 stat_items = getstati(STAT_ITEMS);
1006                         
1007                                 sbar_x = (vid_conwidth - 640.0)*0.5;
1008                                 sbar_y = vid_conheight - 47;
1009                                 sbar_z = 0;
1010
1011                                 fade = 3 - 2 * (time - weapontime);
1012
1013                                 x = 1.0;
1014                                 for(i = 0; i < 8; ++i)
1015                                 {
1016                                         if(stat_items & x)
1017                                         {
1018                                                 Sbar_DrawWeapon(i+1, fade, (i + 2 == activeweapon));
1019                                         }
1020                                         x *= 2;
1021                                 }
1022                                 x *= 2*2*2*2;
1023                                 if(stat_items & x)
1024                                 {
1025                                         Sbar_DrawWeapon(0, fade, (activeweapon == 1));
1026                                 }
1027
1028                                 if (sb_lines > 24)
1029                                         drawpic(sbar, "gfx/sbar", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
1030                                 else
1031                                         drawpic(sbar, "gfx/sbar_minimal", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
1032
1033                                 // armor
1034                                 // (340-3*24) = 268
1035                                 Sbar_DrawXNum('268 12', getstati(STAT_ARMOR), 3, 24, '0.6 0.7 0.8', 1, 0);
1036
1037                                 // health
1038                                 // (154-3*24) = 82
1039                                 x = getstati(STAT_HEALTH);
1040                                 if(x > 100)
1041                                         Sbar_DrawXNum('82 12', x, 3, 24, '1 1 1', 1, 0);
1042                                 else if(x <= 25 && time - floor(time) > 0.5)
1043                                         Sbar_DrawXNum('82 12', x, 3, 24, '0.7 0 0', 1, 0);
1044                                 else
1045                                         Sbar_DrawXNum('81 12', x, 3, 24, '0.6 0.7 0.8', 1, 0);
1046
1047                                 // AK dont draw ammo for the laser
1048                                 x = getstati(STAT_AMMO);
1049                                 if(activeweapon != 12)
1050                                 {
1051                                         // (519-3*24) = 447
1052                                         if (stat_items & NEX_IT_SHELLS)
1053                                                 drawpic(sbar + '519 0', "gfx/sb_shells", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
1054                                         else if (stat_items & NEX_IT_BULLETS)
1055                                                 drawpic(sbar + '519 0', "gfx/sb_bullets", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
1056                                         else if (stat_items & NEX_IT_ROCKETS)
1057                                                 drawpic(sbar + '519 0', "gfx/sb_rocket", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
1058                                         else if (stat_items & NEX_IT_CELLS)
1059                                                 drawpic(sbar + '519 0', "gfx/sb_cells", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
1060                                         if(x > 10)
1061                                                 Sbar_DrawXNum('447 12', x, 3, 24, '0.6 0.7 0.8', 1, 0);
1062                                         else
1063                                                 Sbar_DrawXNum('447 12', x, 3, 24, '0.7 0 0', 1, 0);
1064                                 }
1065
1066                                 if (sb_lines > 24)
1067                                         drawpic(sbar, "gfx/sbar_overlay", '0 0 0', '1 1 1', 1, DRAWFLAG_MODULATE);
1068
1069                                 if (sbar_x + 600 + 160 <= vid_conwidth)
1070                                         Sbar_MiniDeathmatchOverlay (sbar + '600 0');
1071
1072                                 if (sbar_x > 0)
1073                                         Sbar_Score(-16);
1074                                 // Because:
1075                                 //   Mini scoreboard uses 12*4 per other team, that is, 144
1076                                 //   pixels when there are four teams...
1077                                 //   Nexuiz by default sets vid_conwidth to 800... makes
1078                                 //   sbar_x == 80...
1079                                 //   so we need to shift it by 64 pixels to the right to fit
1080                                 //   BUT: then it overlaps with the image that gets drawn
1081                                 //   for viewsize 100! Therefore, just account for 3 teams,
1082                                 //   that is, 96 pixels mini scoreboard size, needing 16 pixels
1083                                 //   to the right!
1084                         }
1085                 
1086                 
1087                         if(gametype == GAME_KEYHUNT)
1088                         {
1089                                 CSQC_kh_hud();
1090                         } else if(gametype == GAME_CTF)
1091                         {
1092                                 CSQC_ctf_hud();
1093                         }
1094                 }
1095         }
1096 }
1097
1098 void CSQC_ctf_hud(void)
1099 {
1100         // cvar("sbar_flagstatus_right") move the flag icons right
1101         // cvar("sbar_flagstatus_pos") pixel position of the nexuiz flagstatus icons
1102         float redflag, blueflag;
1103         float stat_items;
1104         vector pos;
1105         
1106         stat_items = getstati(STAT_ITEMS);
1107         redflag = (stat_items/32768) & 3;
1108         blueflag = (stat_items/131072) & 3;
1109
1110         /**
1111          * FTEQCC BUG!
1112          * For some reason now not even THAT works there...
1113          * Maybe the minus' precedence screws it up? The last one there, maybe I should use brackets
1114          **
1115          * pos_x = (cvar("sbar_flagstatus_right")) ? vid_conwidth - 10 - sbar_x - 64 : 10 - sbar_x;
1116          ** Should try those later:
1117          * pos_x = (cvar("sbar_flagstatus_right")) ? (vid_conwidth - 10 - sbar_x - 64) : (10 - sbar_x);
1118          * pos_x = ( (cvar("sbar_flagstatus_right")) ? vid_conwidth - 10 - 64 : 10 ) - sbar_x;
1119          */
1120         
1121         if(cvar("sbar_flagstatus_right"))
1122                 pos_x = vid_conwidth - 10 - sbar_x - 64;
1123         else
1124                 pos_x = 10 - sbar_x;
1125         
1126         pos_z = 0;
1127
1128         if(sbar_hudselector == 1)
1129                 pos_y = (vid_conheight - sbar_y) - cvar("sbar_flagstatus_pos") - 64;
1130         else
1131                 pos_y = -117;
1132
1133         pos += sbar;
1134
1135         switch(redflag)
1136         {
1137         case 1: drawpic(pos, "gfx/sb_flag_red_taken", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
1138         case 2: drawpic(pos, "gfx/sb_flag_red_lost", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
1139         case 3: drawpic(pos, "gfx/sb_flag_red_carrying", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
1140         }
1141
1142         pos_y -= 64;
1143         
1144         switch(blueflag)
1145         {
1146         case 1: drawpic(pos, "gfx/sb_flag_blue_taken", '0 0 0', '1 1 1', 1, 0); break;
1147         case 2: drawpic(pos, "gfx/sb_flag_blue_lost", '0 0 0', '1 1 1', 1, 0); break;
1148         case 3: drawpic(pos, "gfx/sb_flag_blue_carrying", '0 0 0', '1 1 1', 1, 0); break;
1149         }
1150 }