enabled player scoreboard in coop (note that this overrides the intermission screen)
[divverent/darkplaces.git] / sbar.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // sbar.c -- status bar code
21
22 #include "quakedef.h"
23
24 cachepic_t *sb_disc;
25
26 #define STAT_MINUS 10 // num frame for '-' stats digit
27 cachepic_t *sb_nums[2][11];
28 cachepic_t *sb_colon, *sb_slash;
29 cachepic_t *sb_ibar;
30 cachepic_t *sb_sbar;
31 cachepic_t *sb_scorebar;
32 // AK only used by NEX
33 cachepic_t *sb_sbar_minimal;
34 cachepic_t *sb_sbar_overlay;
35
36 // AK changed the bound to 9
37 cachepic_t *sb_weapons[7][9]; // 0 is active, 1 is owned, 2-5 are flashes
38 cachepic_t *sb_ammo[4];
39 cachepic_t *sb_sigil[4];
40 cachepic_t *sb_armor[3];
41 cachepic_t *sb_items[32];
42
43 // 0-4 are based on health (in 20 increments)
44 // 0 is static, 1 is temporary animation
45 cachepic_t *sb_faces[5][2];
46
47 cachepic_t *sb_face_invis;
48 cachepic_t *sb_face_quad;
49 cachepic_t *sb_face_invuln;
50 cachepic_t *sb_face_invis_invuln;
51
52 qboolean sb_showscores;
53
54 int sb_lines;                   // scan lines to draw
55
56 cachepic_t *rsb_invbar[2];
57 cachepic_t *rsb_weapons[5];
58 cachepic_t *rsb_items[2];
59 cachepic_t *rsb_ammo[3];
60 cachepic_t *rsb_teambord;               // PGM 01/19/97 - team color border
61
62 //MED 01/04/97 added two more weapons + 3 alternates for grenade launcher
63 cachepic_t *hsb_weapons[7][5];   // 0 is active, 1 is owned, 2-5 are flashes
64 //MED 01/04/97 added array to simplify weapon parsing
65 int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_PROXIMITY_GUN_BIT};
66 //MED 01/04/97 added hipnotic items array
67 cachepic_t *hsb_items[2];
68
69 //GAME_SOM stuff:
70 cachepic_t *somsb_health;
71 cachepic_t *somsb_ammo[4];
72 cachepic_t *somsb_armor[3];
73
74 cachepic_t *zymsb_crosshair_center;
75 cachepic_t *zymsb_crosshair_line;
76 cachepic_t *zymsb_crosshair_health;
77 cachepic_t *zymsb_crosshair_ammo;
78 cachepic_t *zymsb_crosshair_clip;
79 cachepic_t *zymsb_crosshair_background;
80 cachepic_t *zymsb_crosshair_left1;
81 cachepic_t *zymsb_crosshair_left2;
82 cachepic_t *zymsb_crosshair_right;
83
84 cachepic_t *sb_ranking;
85 cachepic_t *sb_complete;
86 cachepic_t *sb_inter;
87 cachepic_t *sb_finale;
88
89 cvar_t showfps = {CVAR_SAVE, "showfps", "0", "shows your rendered fps (frames per second)"};
90 cvar_t showtime = {CVAR_SAVE, "showtime", "0", "shows current time of day (useful on screenshots)"};
91 cvar_t showtime_format = {CVAR_SAVE, "showtime_format", "%H:%M:%S", "format string for time of day"};
92 cvar_t showdate = {CVAR_SAVE, "showdate", "0", "shows current date (useful on screenshots)"};
93 cvar_t showdate_format = {CVAR_SAVE, "showdate_format", "%Y-%m-%d", "format string for date"};
94 cvar_t sbar_alpha_bg = {CVAR_SAVE, "sbar_alpha_bg", "0.4", "opacity value of the statusbar background image"};
95 cvar_t sbar_alpha_fg = {CVAR_SAVE, "sbar_alpha_fg", "1", "opacity value of the statusbar weapon/item icons and numbers"};
96
97 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
98
99 cvar_t crosshair_color_red = {CVAR_SAVE, "crosshair_color_red", "1", "customizable crosshair color"};
100 cvar_t crosshair_color_green = {CVAR_SAVE, "crosshair_color_green", "0", "customizable crosshair color"};
101 cvar_t crosshair_color_blue = {CVAR_SAVE, "crosshair_color_blue", "0", "customizable crosshair color"};
102 cvar_t crosshair_color_alpha = {CVAR_SAVE, "crosshair_color_alpha", "1", "how opaque the crosshair should be"};
103 cvar_t crosshair_size = {CVAR_SAVE, "crosshair_size", "1", "adjusts size of the crosshair on the screen"};
104
105 void Sbar_MiniDeathmatchOverlay (int x, int y);
106 void Sbar_DeathmatchOverlay (void);
107 void Sbar_IntermissionOverlay (void);
108 void Sbar_FinaleOverlay (void);
109
110
111 /*
112 ===============
113 Sbar_ShowScores
114
115 Tab key down
116 ===============
117 */
118 void Sbar_ShowScores (void)
119 {
120         if (sb_showscores)
121                 return;
122         sb_showscores = true;
123 }
124
125 /*
126 ===============
127 Sbar_DontShowScores
128
129 Tab key up
130 ===============
131 */
132 void Sbar_DontShowScores (void)
133 {
134         sb_showscores = false;
135 }
136
137 void sbar_start(void)
138 {
139         int i;
140
141         if (gamemode == GAME_NETHERWORLD)
142         {
143         }
144         else if (gamemode == GAME_SOM)
145         {
146                 sb_disc = Draw_CachePic("gfx/disc", true);
147
148                 for (i = 0;i < 10;i++)
149                         sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
150
151                 somsb_health = Draw_CachePic("gfx/hud_health", true);
152                 somsb_ammo[0] = Draw_CachePic("gfx/sb_shells", true);
153                 somsb_ammo[1] = Draw_CachePic("gfx/sb_nails", true);
154                 somsb_ammo[2] = Draw_CachePic("gfx/sb_rocket", true);
155                 somsb_ammo[3] = Draw_CachePic("gfx/sb_cells", true);
156                 somsb_armor[0] = Draw_CachePic("gfx/sb_armor1", true);
157                 somsb_armor[1] = Draw_CachePic("gfx/sb_armor2", true);
158                 somsb_armor[2] = Draw_CachePic("gfx/sb_armor3", true);
159         }
160         else if (gamemode == GAME_NEXUIZ)
161         {
162                 for (i = 0;i < 10;i++)
163                         sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
164                 sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
165
166                 sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
167                 sb_ammo[1] = Draw_CachePic ("gfx/sb_bullets", true);
168                 sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
169                 sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
170
171                 sb_items[2] = Draw_CachePic ("gfx/sb_slowmo", true);
172                 sb_items[3] = Draw_CachePic ("gfx/sb_invinc", true);
173                 sb_items[4] = Draw_CachePic ("gfx/sb_energy", true);
174                 sb_items[5] = Draw_CachePic ("gfx/sb_str", true);
175
176                 sb_sbar = Draw_CachePic("gfx/sbar", true);
177                 sb_sbar_minimal = Draw_CachePic("gfx/sbar_minimal", true);
178                 sb_sbar_overlay = Draw_CachePic("gfx/sbar_overlay", true);
179
180                 for(i = 0; i < 9;i++)
181                         sb_weapons[0][i] = Draw_CachePic(va("gfx/inv_weapon%i",i), true);
182         }
183         else if (gamemode == GAME_ZYMOTIC)
184         {
185                 zymsb_crosshair_center = Draw_CachePic ("gfx/hud/crosshair_center", true);
186                 zymsb_crosshair_line = Draw_CachePic ("gfx/hud/crosshair_line", true);
187                 zymsb_crosshair_health = Draw_CachePic ("gfx/hud/crosshair_health", true);
188                 zymsb_crosshair_clip = Draw_CachePic ("gfx/hud/crosshair_clip", true);
189                 zymsb_crosshair_ammo = Draw_CachePic ("gfx/hud/crosshair_ammo", true);
190                 zymsb_crosshair_background = Draw_CachePic ("gfx/hud/crosshair_background", true);
191                 zymsb_crosshair_left1 = Draw_CachePic ("gfx/hud/crosshair_left1", true);
192                 zymsb_crosshair_left2 = Draw_CachePic ("gfx/hud/crosshair_left2", true);
193                 zymsb_crosshair_right = Draw_CachePic ("gfx/hud/crosshair_right", true);
194         }
195         else
196         {
197                 sb_disc = Draw_CachePic("gfx/disc", true);
198
199                 for (i = 0;i < 10;i++)
200                 {
201                         sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
202                         sb_nums[1][i] = Draw_CachePic (va("gfx/anum_%i",i), true);
203                 }
204
205                 sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
206                 sb_nums[1][10] = Draw_CachePic ("gfx/anum_minus", true);
207
208                 sb_colon = Draw_CachePic ("gfx/num_colon", true);
209                 sb_slash = Draw_CachePic ("gfx/num_slash", true);
210
211                 sb_weapons[0][0] = Draw_CachePic ("gfx/inv_shotgun", true);
212                 sb_weapons[0][1] = Draw_CachePic ("gfx/inv_sshotgun", true);
213                 sb_weapons[0][2] = Draw_CachePic ("gfx/inv_nailgun", true);
214                 sb_weapons[0][3] = Draw_CachePic ("gfx/inv_snailgun", true);
215                 sb_weapons[0][4] = Draw_CachePic ("gfx/inv_rlaunch", true);
216                 sb_weapons[0][5] = Draw_CachePic ("gfx/inv_srlaunch", true);
217                 sb_weapons[0][6] = Draw_CachePic ("gfx/inv_lightng", true);
218
219                 sb_weapons[1][0] = Draw_CachePic ("gfx/inv2_shotgun", true);
220                 sb_weapons[1][1] = Draw_CachePic ("gfx/inv2_sshotgun", true);
221                 sb_weapons[1][2] = Draw_CachePic ("gfx/inv2_nailgun", true);
222                 sb_weapons[1][3] = Draw_CachePic ("gfx/inv2_snailgun", true);
223                 sb_weapons[1][4] = Draw_CachePic ("gfx/inv2_rlaunch", true);
224                 sb_weapons[1][5] = Draw_CachePic ("gfx/inv2_srlaunch", true);
225                 sb_weapons[1][6] = Draw_CachePic ("gfx/inv2_lightng", true);
226
227                 for (i = 0;i < 5;i++)
228                 {
229                         sb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_shotgun",i+1), true);
230                         sb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_sshotgun",i+1), true);
231                         sb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_nailgun",i+1), true);
232                         sb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_snailgun",i+1), true);
233                         sb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_rlaunch",i+1), true);
234                         sb_weapons[2+i][5] = Draw_CachePic (va("gfx/inva%i_srlaunch",i+1), true);
235                         sb_weapons[2+i][6] = Draw_CachePic (va("gfx/inva%i_lightng",i+1), true);
236                 }
237
238                 sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
239                 sb_ammo[1] = Draw_CachePic ("gfx/sb_nails", true);
240                 sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
241                 sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
242
243                 sb_armor[0] = Draw_CachePic ("gfx/sb_armor1", true);
244                 sb_armor[1] = Draw_CachePic ("gfx/sb_armor2", true);
245                 sb_armor[2] = Draw_CachePic ("gfx/sb_armor3", true);
246
247                 sb_items[0] = Draw_CachePic ("gfx/sb_key1", true);
248                 sb_items[1] = Draw_CachePic ("gfx/sb_key2", true);
249                 sb_items[2] = Draw_CachePic ("gfx/sb_invis", true);
250                 sb_items[3] = Draw_CachePic ("gfx/sb_invuln", true);
251                 sb_items[4] = Draw_CachePic ("gfx/sb_suit", true);
252                 sb_items[5] = Draw_CachePic ("gfx/sb_quad", true);
253
254                 sb_sigil[0] = Draw_CachePic ("gfx/sb_sigil1", true);
255                 sb_sigil[1] = Draw_CachePic ("gfx/sb_sigil2", true);
256                 sb_sigil[2] = Draw_CachePic ("gfx/sb_sigil3", true);
257                 sb_sigil[3] = Draw_CachePic ("gfx/sb_sigil4", true);
258
259                 sb_faces[4][0] = Draw_CachePic ("gfx/face1", true);
260                 sb_faces[4][1] = Draw_CachePic ("gfx/face_p1", true);
261                 sb_faces[3][0] = Draw_CachePic ("gfx/face2", true);
262                 sb_faces[3][1] = Draw_CachePic ("gfx/face_p2", true);
263                 sb_faces[2][0] = Draw_CachePic ("gfx/face3", true);
264                 sb_faces[2][1] = Draw_CachePic ("gfx/face_p3", true);
265                 sb_faces[1][0] = Draw_CachePic ("gfx/face4", true);
266                 sb_faces[1][1] = Draw_CachePic ("gfx/face_p4", true);
267                 sb_faces[0][0] = Draw_CachePic ("gfx/face5", true);
268                 sb_faces[0][1] = Draw_CachePic ("gfx/face_p5", true);
269
270                 sb_face_invis = Draw_CachePic ("gfx/face_invis", true);
271                 sb_face_invuln = Draw_CachePic ("gfx/face_invul2", true);
272                 sb_face_invis_invuln = Draw_CachePic ("gfx/face_inv2", true);
273                 sb_face_quad = Draw_CachePic ("gfx/face_quad", true);
274
275                 sb_sbar = Draw_CachePic ("gfx/sbar", true);
276                 sb_ibar = Draw_CachePic ("gfx/ibar", true);
277                 sb_scorebar = Draw_CachePic ("gfx/scorebar", true);
278
279         //MED 01/04/97 added new hipnotic weapons
280                 if (gamemode == GAME_HIPNOTIC)
281                 {
282                         hsb_weapons[0][0] = Draw_CachePic ("gfx/inv_laser", true);
283                         hsb_weapons[0][1] = Draw_CachePic ("gfx/inv_mjolnir", true);
284                         hsb_weapons[0][2] = Draw_CachePic ("gfx/inv_gren_prox", true);
285                         hsb_weapons[0][3] = Draw_CachePic ("gfx/inv_prox_gren", true);
286                         hsb_weapons[0][4] = Draw_CachePic ("gfx/inv_prox", true);
287
288                         hsb_weapons[1][0] = Draw_CachePic ("gfx/inv2_laser", true);
289                         hsb_weapons[1][1] = Draw_CachePic ("gfx/inv2_mjolnir", true);
290                         hsb_weapons[1][2] = Draw_CachePic ("gfx/inv2_gren_prox", true);
291                         hsb_weapons[1][3] = Draw_CachePic ("gfx/inv2_prox_gren", true);
292                         hsb_weapons[1][4] = Draw_CachePic ("gfx/inv2_prox", true);
293
294                         for (i = 0;i < 5;i++)
295                         {
296                                 hsb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_laser",i+1), true);
297                                 hsb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_mjolnir",i+1), true);
298                                 hsb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_gren_prox",i+1), true);
299                                 hsb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_prox_gren",i+1), true);
300                                 hsb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_prox",i+1), true);
301                         }
302
303                         hsb_items[0] = Draw_CachePic ("gfx/sb_wsuit", true);
304                         hsb_items[1] = Draw_CachePic ("gfx/sb_eshld", true);
305                 }
306                 else if (gamemode == GAME_ROGUE)
307                 {
308                         rsb_invbar[0] = Draw_CachePic ("gfx/r_invbar1", true);
309                         rsb_invbar[1] = Draw_CachePic ("gfx/r_invbar2", true);
310
311                         rsb_weapons[0] = Draw_CachePic ("gfx/r_lava", true);
312                         rsb_weapons[1] = Draw_CachePic ("gfx/r_superlava", true);
313                         rsb_weapons[2] = Draw_CachePic ("gfx/r_gren", true);
314                         rsb_weapons[3] = Draw_CachePic ("gfx/r_multirock", true);
315                         rsb_weapons[4] = Draw_CachePic ("gfx/r_plasma", true);
316
317                         rsb_items[0] = Draw_CachePic ("gfx/r_shield1", true);
318                         rsb_items[1] = Draw_CachePic ("gfx/r_agrav1", true);
319
320         // PGM 01/19/97 - team color border
321                         rsb_teambord = Draw_CachePic ("gfx/r_teambord", true);
322         // PGM 01/19/97 - team color border
323
324                         rsb_ammo[0] = Draw_CachePic ("gfx/r_ammolava", true);
325                         rsb_ammo[1] = Draw_CachePic ("gfx/r_ammomulti", true);
326                         rsb_ammo[2] = Draw_CachePic ("gfx/r_ammoplasma", true);
327                 }
328         }
329
330         sb_ranking = Draw_CachePic ("gfx/ranking", true);
331         sb_complete = Draw_CachePic ("gfx/complete", true);
332         sb_inter = Draw_CachePic ("gfx/inter", true);
333         sb_finale = Draw_CachePic ("gfx/finale", true);
334 }
335
336 void sbar_shutdown(void)
337 {
338 }
339
340 void sbar_newmap(void)
341 {
342 }
343
344 void Sbar_Init (void)
345 {
346         Cmd_AddCommand("+showscores", Sbar_ShowScores, "show scoreboard");
347         Cmd_AddCommand("-showscores", Sbar_DontShowScores, "hide scoreboard");
348         Cvar_RegisterVariable(&showfps);
349         Cvar_RegisterVariable(&showtime);
350         Cvar_RegisterVariable(&showtime_format);
351         Cvar_RegisterVariable(&showdate);
352         Cvar_RegisterVariable(&showdate_format);
353         Cvar_RegisterVariable(&sbar_alpha_bg);
354         Cvar_RegisterVariable(&sbar_alpha_fg);
355         Cvar_RegisterVariable(&cl_deathscoreboard);
356
357         Cvar_RegisterVariable(&crosshair_color_red);
358         Cvar_RegisterVariable(&crosshair_color_green);
359         Cvar_RegisterVariable(&crosshair_color_blue);
360         Cvar_RegisterVariable(&crosshair_color_alpha);
361         Cvar_RegisterVariable(&crosshair_size);
362
363         R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
364 }
365
366
367 //=============================================================================
368
369 // drawing routines are relative to the status bar location
370
371 int sbar_x, sbar_y;
372
373 /*
374 =============
375 Sbar_DrawPic
376 =============
377 */
378 void Sbar_DrawPic (int x, int y, cachepic_t *pic)
379 {
380         DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
381 }
382
383 void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
384 {
385         DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, alpha, 0);
386 }
387
388 /*
389 ================
390 Sbar_DrawCharacter
391
392 Draws one solid graphics character
393 ================
394 */
395 void Sbar_DrawCharacter (int x, int y, int num)
396 {
397         DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
398 }
399
400 /*
401 ================
402 Sbar_DrawString
403 ================
404 */
405 void Sbar_DrawString (int x, int y, char *str)
406 {
407         DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0);
408 }
409
410 /*
411 =============
412 Sbar_DrawNum
413 =============
414 */
415 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
416 {
417         char str[32], *ptr;
418         int l, frame;
419
420         l = sprintf(str, "%i", num);
421         ptr = str;
422         if (l > digits)
423                 ptr += (l-digits);
424         if (l < digits)
425                 x += (digits-l)*24;
426
427         while (*ptr)
428         {
429                 if (*ptr == '-')
430                         frame = STAT_MINUS;
431                 else
432                         frame = *ptr -'0';
433
434                 Sbar_DrawPic (x, y, sb_nums[color][frame]);
435                 x += 24;
436
437                 ptr++;
438         }
439 }
440
441 /*
442 =============
443 Sbar_DrawXNum
444 =============
445 */
446
447 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
448 {
449         char str[32], *ptr;
450         int l, frame;
451
452         l = sprintf(str, "%i", num);
453         ptr = str;
454         if (l > digits)
455                 ptr += (l-digits);
456         if (l < digits)
457                 x += (digits-l) * lettersize;
458
459         while (*ptr)
460         {
461                 if (*ptr == '-')
462                         frame = STAT_MINUS;
463                 else
464                         frame = *ptr -'0';
465
466                 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame],lettersize,lettersize,r,g,b,a * sbar_alpha_fg.value,flags);
467                 x += lettersize;
468
469                 ptr++;
470         }
471 }
472
473 //=============================================================================
474
475
476 int Sbar_IsTeammatch()
477 {
478         // currently only nexuiz uses the team score board
479         return ((gamemode == GAME_NEXUIZ)
480                 && (teamplay.integer > 0));
481 }
482
483 /*
484 ===============
485 Sbar_SortFrags
486 ===============
487 */
488 static int fragsort[MAX_SCOREBOARD];
489 static int scoreboardlines;
490
491 //[515]: Sbar_GetPlayer for csqc "getplayerkey" func
492 int Sbar_GetPlayer (int index)
493 {
494         if(index < 0)
495         {
496                 index = -1-index;
497                 if(index >= scoreboardlines)
498                         return -1;
499                 index = fragsort[index];
500         }
501         if(index >= scoreboardlines)
502                 return -1;
503         return index;
504 }
505
506 static scoreboard_t teams[MAX_SCOREBOARD];
507 static int teamsort[MAX_SCOREBOARD];
508 static int teamlines;
509 void Sbar_SortFrags (void)
510 {
511         int i, j, k, color;
512
513         // sort by frags
514         scoreboardlines = 0;
515         for (i=0 ; i<cl.maxclients ; i++)
516         {
517                 if (cl.scores[i].name[0])
518                 {
519                         fragsort[scoreboardlines] = i;
520                         scoreboardlines++;
521                 }
522         }
523
524         for (i=0 ; i<scoreboardlines ; i++)
525                 for (j=0 ; j<scoreboardlines-1-i ; j++)
526                         if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
527                         {
528                                 k = fragsort[j];
529                                 fragsort[j] = fragsort[j+1];
530                                 fragsort[j+1] = k;
531                         }
532
533         teamlines = 0;
534         if (Sbar_IsTeammatch ())
535         {
536                 // now sort players by teams.
537                 for (i=0 ; i<scoreboardlines ; i++)
538                 {
539                         for (j=0 ; j<scoreboardlines-1-i ; j++)
540                         {
541                                 if (cl.scores[fragsort[j]].colors < cl.scores[fragsort[j+1]].colors)
542                                 {
543                                         k = fragsort[j];
544                                         fragsort[j] = fragsort[j+1];
545                                         fragsort[j+1] = k;
546                                 }
547                         }
548                 }
549
550                 // calculate team scores
551                 color = -1;
552                 for (i=0 ; i<scoreboardlines ; i++)
553                 {
554                         if (color != (cl.scores[fragsort[i]].colors & 15))
555                         {
556                                 color = cl.scores[fragsort[i]].colors & 15;
557                                 teamlines++;
558
559                                 if (color == 4)
560                                         strcpy(teams[teamlines-1].name, "^1Red Team");
561                                 else if (color == 13)
562                                         strcpy(teams[teamlines-1].name, "^4Blue Team");
563                                 else if (color == 9)
564                                         strcpy(teams[teamlines-1].name, "^6Pink Team");
565                                 else if (color == 12)
566                                         strcpy(teams[teamlines-1].name, "^3Yellow Team");
567                                 else
568                                         strcpy(teams[teamlines-1].name, "Total Team Score");
569
570                                 teams[teamlines-1].frags = 0;
571                                 teams[teamlines-1].colors = color + 16 * color;
572                         }
573
574                         if (cl.scores[fragsort[i]].frags != -666)
575                         {
576                                 // do not add spedcators
577                                 // (ugly hack for nexuiz)
578                                 teams[teamlines-1].frags += cl.scores[fragsort[i]].frags;
579                         }
580                 }
581
582                 // now sort teams by scores.
583                 for (i=0 ; i<teamlines ; i++)
584                         teamsort[i] = i;
585                 for (i=0 ; i<teamlines ; i++)
586                 {
587                         for (j=0 ; j<teamlines-1-i ; j++)
588                         {
589                                 if (teams[teamsort[j]].frags < teams[teamsort[j+1]].frags)
590                                 {
591                                         k = teamsort[j];
592                                         teamsort[j] = teamsort[j+1];
593                                         teamsort[j+1] = k;
594                                 }
595                         }
596                 }
597         }
598 }
599
600 /*
601 ===============
602 Sbar_SoloScoreboard
603 ===============
604 */
605 void Sbar_SoloScoreboard (void)
606 {
607         char    str[80];
608         int             minutes, seconds, tens, units;
609         int             l;
610
611         if (gamemode != GAME_NEXUIZ) {
612                 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
613                 Sbar_DrawString (8, 4, str);
614
615                 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
616                 Sbar_DrawString (8, 12, str);
617         }
618
619 // time
620         minutes = (int)(cl.time / 60);
621         seconds = (int)(cl.time - 60*minutes);
622         tens = seconds / 10;
623         units = seconds - 10*tens;
624         sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
625         Sbar_DrawString (184, 4, str);
626
627 // draw level name
628         if (gamemode == GAME_NEXUIZ) {
629                 l = (int) strlen (cl.worldmodel->name);
630                 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
631         } else {
632                 l = (int) strlen (cl.levelname);
633                 Sbar_DrawString (232 - l*4, 12, cl.levelname);
634         }
635 }
636
637 /*
638 ===============
639 Sbar_DrawScoreboard
640 ===============
641 */
642 void Sbar_DrawScoreboard (void)
643 {
644         Sbar_SoloScoreboard ();
645         // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
646         //if (cl.gametype == GAME_DEATHMATCH)
647         if (!cl.islocalgame)
648                 Sbar_DeathmatchOverlay ();
649 }
650
651 //=============================================================================
652
653 // AK to make DrawInventory smaller
654 static void Sbar_DrawWeapon(int nr, float fade, int active)
655 {
656         // width = 300, height = 100
657         const int w_width = 300, w_height = 100, w_space = 10;
658         const float w_scale = 0.4;
659
660         DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, sb_weapons[0][nr], w_width * w_scale, w_height * w_scale, (active) ? 1 : 0.6, active ? 1 : 0.6, active ? 1 : 1, fade * sbar_alpha_fg.value, DRAWFLAG_ADDITIVE);
661         //DrawQ_String(vid_conwidth.integer - (w_space + font_size ), (w_height + w_space) * w_scale * nr + w_space, va("%i",nr+1), 0, font_size, font_size, 1, 0, 0, fade, 0);
662
663         if (active)
664                 DrawQ_Pic(vid_conwidth.integer - (w_width + w_space) * w_scale, (w_height + w_space) * w_scale * nr + w_space, NULL, w_width * w_scale, w_height * w_scale, 0.3, 0.3, 0.3, fade * sbar_alpha_fg.value, DRAWFLAG_ADDITIVE);
665 }
666
667 /*
668 ===============
669 Sbar_DrawInventory
670 ===============
671 */
672 void Sbar_DrawInventory (void)
673 {
674         int i;
675         char num[6];
676         float time;
677         int flashon;
678
679         if (gamemode == GAME_ROGUE)
680         {
681                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
682                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
683                 else
684                         Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
685         }
686         else
687                 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
688
689         // weapons
690         for (i=0 ; i<7 ; i++)
691         {
692                 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
693                 {
694                         time = cl.item_gettime[i];
695                         flashon = (int)((cl.time - time)*10);
696                         if (flashon >= 10)
697                         {
698                                 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i)  )
699                                         flashon = 1;
700                                 else
701                                         flashon = 0;
702                         }
703                         else
704                                 flashon = (flashon%5) + 2;
705
706                         Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
707                 }
708         }
709
710         // MED 01/04/97
711         // hipnotic weapons
712         if (gamemode == GAME_HIPNOTIC)
713         {
714                 int grenadeflashing=0;
715                 for (i=0 ; i<4 ; i++)
716                 {
717                         if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
718                         {
719                                 time = cl.item_gettime[hipweapons[i]];
720                                 flashon = (int)((cl.time - time)*10);
721                                 if (flashon >= 10)
722                                 {
723                                         if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i])  )
724                                                 flashon = 1;
725                                         else
726                                                 flashon = 0;
727                                 }
728                                 else
729                                         flashon = (flashon%5) + 2;
730
731                                 // check grenade launcher
732                                 if (i==2)
733                                 {
734                                         if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
735                                         {
736                                                 if (flashon)
737                                                 {
738                                                         grenadeflashing = 1;
739                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
740                                                 }
741                                         }
742                                 }
743                                 else if (i==3)
744                                 {
745                                         if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
746                                         {
747                                                 if (!grenadeflashing)
748                                                         Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
749                                         }
750                                         else
751                                                 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
752                                 }
753                                 else
754                                         Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
755                         }
756                 }
757         }
758
759         if (gamemode == GAME_ROGUE)
760         {
761                 // check for powered up weapon.
762                 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
763                         for (i=0;i<5;i++)
764                                 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
765                                         Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
766         }
767
768         // ammo counts
769         for (i=0 ; i<4 ; i++)
770         {
771                 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
772                 if (num[0] != ' ')
773                         Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
774                 if (num[1] != ' ')
775                         Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
776                 if (num[2] != ' ')
777                         Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
778         }
779
780         // items
781         for (i=0 ; i<6 ; i++)
782                 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
783                 {
784                         //MED 01/04/97 changed keys
785                         if (gamemode != GAME_HIPNOTIC || (i>1))
786                                 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
787                 }
788
789         //MED 01/04/97 added hipnotic items
790         // hipnotic items
791         if (gamemode == GAME_HIPNOTIC)
792         {
793                 for (i=0 ; i<2 ; i++)
794                         if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
795                                 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
796         }
797
798         if (gamemode == GAME_ROGUE)
799         {
800                 // new rogue items
801                 for (i=0 ; i<2 ; i++)
802                         if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
803                                 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
804         }
805         else
806         {
807                 // sigils
808                 for (i=0 ; i<4 ; i++)
809                         if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
810                                 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
811         }
812 }
813
814 //=============================================================================
815
816 /*
817 ===============
818 Sbar_DrawFrags
819 ===============
820 */
821 void Sbar_DrawFrags (void)
822 {
823         int i, k, l, x, f;
824         char num[12];
825         scoreboard_t *s;
826         unsigned char *c;
827
828         Sbar_SortFrags ();
829
830         // draw the text
831         l = min(scoreboardlines, 4);
832
833         x = 23 * 8;
834
835         for (i = 0;i < l;i++)
836         {
837                 k = fragsort[i];
838                 s = &cl.scores[k];
839
840                 // draw background
841                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
842                 DrawQ_Pic (sbar_x + x + 10, sbar_y     - 23, NULL, 28, 4, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
843                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
844                 DrawQ_Pic (sbar_x + x + 10, sbar_y + 4 - 23, NULL, 28, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
845
846                 // draw number
847                 f = s->frags;
848                 sprintf (num, "%3i",f);
849
850                 if (k == cl.viewentity - 1)
851                 {
852                         Sbar_DrawCharacter ( x      + 2, -24, 16);
853                         Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
854                 }
855                 Sbar_DrawCharacter (x +  8, -24, num[0]);
856                 Sbar_DrawCharacter (x + 16, -24, num[1]);
857                 Sbar_DrawCharacter (x + 24, -24, num[2]);
858                 x += 32;
859         }
860 }
861
862 //=============================================================================
863
864
865 /*
866 ===============
867 Sbar_DrawFace
868 ===============
869 */
870 void Sbar_DrawFace (void)
871 {
872         int f;
873
874 // PGM 01/19/97 - team color drawing
875 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
876         if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
877         {
878                 char num[12];
879                 scoreboard_t *s;
880                 unsigned char *c;
881
882                 s = &cl.scores[cl.viewentity - 1];
883                 // draw background
884                 Sbar_DrawPic (112, 0, rsb_teambord);
885                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
886                 DrawQ_Pic (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, NULL, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
887                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
888                 DrawQ_Pic (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, NULL, 22, 9, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
889
890                 // draw number
891                 f = s->frags;
892                 sprintf (num, "%3i",f);
893
894                 if ((s->colors & 0xf0)==0)
895                 {
896                         if (num[0] != ' ')
897                                 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
898                         if (num[1] != ' ')
899                                 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
900                         if (num[2] != ' ')
901                                 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
902                 }
903                 else
904                 {
905                         Sbar_DrawCharacter ( 109, 3, num[0]);
906                         Sbar_DrawCharacter ( 116, 3, num[1]);
907                         Sbar_DrawCharacter ( 123, 3, num[2]);
908                 }
909
910                 return;
911         }
912 // PGM 01/19/97 - team color drawing
913
914         if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
915                 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
916         else if (cl.stats[STAT_ITEMS] & IT_QUAD)
917                 Sbar_DrawPic (112, 0, sb_face_quad );
918         else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
919                 Sbar_DrawPic (112, 0, sb_face_invis );
920         else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
921                 Sbar_DrawPic (112, 0, sb_face_invuln);
922         else
923         {
924                 f = cl.stats[STAT_HEALTH] / 20;
925                 f = bound(0, f, 4);
926                 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
927         }
928 }
929
930 void Sbar_ShowFPS(void)
931 {
932         float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
933         char fpsstring[32];
934         char timestring[32];
935         char datestring[32];
936         qboolean red = false;
937         fpsstring[0] = 0;
938         timestring[0] = 0;
939         datestring[0] = 0;
940         if (showfps.integer)
941         {
942                 float calc;
943                 static double nexttime = 0, lasttime = 0;
944                 static double framerate = 0;
945                 static int framecount = 0;
946                 double newtime;
947                 newtime = Sys_DoubleTime();
948                 if (newtime >= nexttime)
949                 {
950                         framerate = framecount / (newtime - lasttime);
951                         lasttime = newtime;
952                         nexttime = max(nexttime + 1, lasttime - 1);
953                         framecount = 0;
954                 }
955                 framecount++;
956                 calc = framerate;
957
958                 if ((red = (calc < 1.0f)))
959                         dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
960                 else
961                         dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
962         }
963         if (showtime.integer)
964                 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
965         if (showdate.integer)
966                 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
967         if (fpsstring[0] || timestring[0])
968         {
969                 fps_scalex = 12;
970                 fps_scaley = 12;
971                 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
972                 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
973                 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
974                 fps_y = vid_conheight.integer - fps_height;
975                 if (fpsstring[0])
976                 {
977                         fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
978                         DrawQ_Pic(fps_x, fps_y, NULL, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
979                         if (red)
980                                 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0);
981                         else
982                                 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
983                         fps_y += fps_scaley;
984                 }
985                 if (timestring[0])
986                 {
987                         fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
988                         DrawQ_Pic(fps_x, fps_y, NULL, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
989                         DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
990                         fps_y += fps_scaley;
991                 }
992                 if (datestring[0])
993                 {
994                         fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
995                         DrawQ_Pic(fps_x, fps_y, NULL, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
996                         DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0);
997                         fps_y += fps_scaley;
998                 }
999         }
1000 }
1001
1002 void Sbar_DrawGauge(float x, float y, cachepic_t *pic, float width, float height, float rangey, float rangeheight, float c1, float c2, float c1r, float c1g, float c1b, float c1a, float c2r, float c2g, float c2b, float c2a, float c3r, float c3g, float c3b, float c3a, int drawflags)
1003 {
1004         float r[5];
1005         c2 = bound(0, c2, 1);
1006         c1 = bound(0, c1, 1 - c2);
1007         r[0] = 0;
1008         r[1] = rangey + rangeheight * (c2 + c1);
1009         r[2] = rangey + rangeheight * (c2);
1010         r[3] = rangey;
1011         r[4] = height;
1012         if (r[1] > r[0])
1013                 DrawQ_SuperPic(x, y + r[0], pic, width, (r[1] - r[0]), 0,(r[0] / height), c3r,c3g,c3b,c3a, 1,(r[0] / height), c3r,c3g,c3b,c3a, 0,(r[1] / height), c3r,c3g,c3b,c3a, 1,(r[1] / height), c3r,c3g,c3b,c3a, drawflags);
1014         if (r[2] > r[1])
1015                 DrawQ_SuperPic(x, y + r[1], pic, width, (r[2] - r[1]), 0,(r[1] / height), c1r,c1g,c1b,c1a, 1,(r[1] / height), c1r,c1g,c1b,c1a, 0,(r[2] / height), c1r,c1g,c1b,c1a, 1,(r[2] / height), c1r,c1g,c1b,c1a, drawflags);
1016         if (r[3] > r[2])
1017                 DrawQ_SuperPic(x, y + r[2], pic, width, (r[3] - r[2]), 0,(r[2] / height), c2r,c2g,c2b,c2a, 1,(r[2] / height), c2r,c2g,c2b,c2a, 0,(r[3] / height), c2r,c2g,c2b,c2a, 1,(r[3] / height), c2r,c2g,c2b,c2a, drawflags);
1018         if (r[4] > r[3])
1019                 DrawQ_SuperPic(x, y + r[3], pic, width, (r[4] - r[3]), 0,(r[3] / height), c3r,c3g,c3b,c3a, 1,(r[3] / height), c3r,c3g,c3b,c3a, 0,(r[4] / height), c3r,c3g,c3b,c3a, 1,(r[4] / height), c3r,c3g,c3b,c3a, drawflags);
1020 }
1021
1022 /*
1023 ===============
1024 Sbar_Draw
1025 ===============
1026 */
1027 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
1028 extern cvar_t v_kicktime;
1029 void Sbar_Draw (void)
1030 {
1031         cachepic_t *pic;
1032
1033         if(cl.csqc_vidvars.drawenginesbar)      //[515]: csqc drawsbar
1034         {
1035                 if (cl.intermission == 1)
1036                 {
1037                         Sbar_IntermissionOverlay();
1038                         return;
1039                 }
1040                 else if (cl.intermission == 2)
1041                 {
1042                         Sbar_FinaleOverlay();
1043                         return;
1044                 }
1045
1046                 if (gamemode == GAME_NETHERWORLD)
1047                 {
1048                 }
1049                 else if (gamemode == GAME_SOM)
1050                 {
1051                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1052                                 Sbar_DrawScoreboard ();
1053                         else if (sb_lines)
1054                         {
1055                                 // this is the top left of the sbar area
1056                                 sbar_x = 0;
1057                                 sbar_y = vid_conheight.integer - 24*3;
1058
1059                                 // armor
1060                                 if (cl.stats[STAT_ARMOR])
1061                                 {
1062                                         if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1063                                                 Sbar_DrawPic(0, 0, somsb_armor[2]);
1064                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1065                                                 Sbar_DrawPic(0, 0, somsb_armor[1]);
1066                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1067                                                 Sbar_DrawPic(0, 0, somsb_armor[0]);
1068                                         Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1069                                 }
1070
1071                                 // health
1072                                 Sbar_DrawPic(0, 24, somsb_health);
1073                                 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1074
1075                                 // ammo icon
1076                                 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1077                                         Sbar_DrawPic(0, 48, somsb_ammo[0]);
1078                                 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1079                                         Sbar_DrawPic(0, 48, somsb_ammo[1]);
1080                                 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1081                                         Sbar_DrawPic(0, 48, somsb_ammo[2]);
1082                                 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1083                                         Sbar_DrawPic(0, 48, somsb_ammo[3]);
1084                                 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1085                                 if (cl.stats[STAT_SHELLS])
1086                                         Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1087                         }
1088                 }
1089                 else if (gamemode == GAME_NEXUIZ)
1090                 {
1091                         sbar_y = vid_conheight.integer - 47;
1092                         sbar_x = (vid_conwidth.integer - 640)/2;
1093
1094                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1095                         {
1096                                 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1097                                 Sbar_DrawScoreboard ();
1098                         }
1099                         else if (sb_lines)
1100                         {
1101                                 int i;
1102                                 double time;
1103                                 float fade;
1104
1105                                 // we have a max time 2s (min time = 0)
1106                                 if ((time = cl.time - cl.weapontime) < 2)
1107                                 {
1108                                         fade = (1.0 - 0.5 * time);
1109                                         fade *= fade;
1110                                         for (i = 0; i < 8;i++)
1111                                                 if (cl.stats[STAT_ITEMS] & (1 << i))
1112                                                         Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1113
1114                                         if((cl.stats[STAT_ITEMS] & (1<<12)))
1115                                                 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1116                                 }
1117
1118                                 //if (!cl.islocalgame)
1119                                 //      Sbar_DrawFrags ();
1120
1121                                 if (sb_lines > 24)
1122                                         Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1123                                 else
1124                                         Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1125
1126                                 // special items
1127                                 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1128                                 {
1129                                         // Nexuiz has no anum pics
1130                                         //Sbar_DrawNum (36, 0, 666, 3, 1);
1131                                         // Nexuiz has no disc pic
1132                                         //Sbar_DrawPic (0, 0, sb_disc);
1133                                 }
1134
1135                                 // armor
1136                                 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1137
1138                                 // health
1139                                 if(cl.stats[STAT_HEALTH] > 100)
1140                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1141                                 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1142                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1143                                 else
1144                                         Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1145
1146                                 // AK dont draw ammo for the laser
1147                                 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1148                                 {
1149                                         if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1150                                                 Sbar_DrawPic (519, 0, sb_ammo[0]);
1151                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1152                                                 Sbar_DrawPic (519, 0, sb_ammo[1]);
1153                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1154                                                 Sbar_DrawPic (519, 0, sb_ammo[2]);
1155                                         else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1156                                                 Sbar_DrawPic (519, 0, sb_ammo[3]);
1157
1158                                         if(cl.stats[STAT_AMMO] <= 10)
1159                                                 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1160                                         else
1161                                                 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1162
1163                                 }
1164
1165                                 if (sb_lines > 24)
1166                                         DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1167                         }
1168
1169                         //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1170                         //      Sbar_MiniDeathmatchOverlay (0, 17);
1171                 }
1172                 else if (gamemode == GAME_ZYMOTIC)
1173                 {
1174 #if 1
1175                         float scale = 64.0f / 256.0f;
1176                         float kickoffset[3];
1177                         VectorClear(kickoffset);
1178                         if (v_dmg_time > 0)
1179                         {
1180                                 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1181                                 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1182                         }
1183                         sbar_x = (int)((vid_conwidth.integer - 256 * scale)/2 + kickoffset[0]);
1184                         sbar_y = (int)((vid_conheight.integer - 256 * scale)/2 + kickoffset[1]);
1185                         // left1 16, 48 : 126 -66
1186                         // left2 16, 128 : 196 -66
1187                         // right 176, 48 : 196 -136
1188                         Sbar_DrawGauge(sbar_x +  16 * scale, sbar_y +  48 * scale, zymsb_crosshair_left1, 64*scale,  80*scale, 78*scale,  -66*scale, cl.stats[STAT_AMMO]  * (1.0 / 200.0), cl.stats[STAT_SHELLS]  * (1.0 / 200.0), 0.8f,0.8f,0.0f,1.0f, 0.8f,0.5f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1189                         Sbar_DrawGauge(sbar_x +  16 * scale, sbar_y + 128 * scale, zymsb_crosshair_left2, 64*scale,  80*scale, 68*scale,  -66*scale, cl.stats[STAT_NAILS] * (1.0 / 200.0), cl.stats[STAT_ROCKETS] * (1.0 / 200.0), 0.8f,0.8f,0.0f,1.0f, 0.8f,0.5f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1190                         Sbar_DrawGauge(sbar_x + 176 * scale, sbar_y +  48 * scale, zymsb_crosshair_right, 64*scale, 160*scale, 148*scale, -136*scale, cl.stats[STAT_ARMOR]  * (1.0 / 300.0), cl.stats[STAT_HEALTH]  * (1.0 / 300.0), 0.0f,0.5f,1.0f,1.0f, 1.0f,0.0f,0.0f,1.0f, 0.3f,0.3f,0.3f,1.0f, DRAWFLAG_NORMAL);
1191                         DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1192 #else
1193                         float scale = 128.0f / 256.0f;
1194                         float healthstart, healthheight, healthstarttc, healthendtc;
1195                         float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1196                         float ammostart, ammoheight, ammostarttc, ammoendtc;
1197                         float clipstart, clipheight, clipstarttc, clipendtc;
1198                         float kickoffset[3], offset;
1199                         VectorClear(kickoffset);
1200                         if (v_dmg_time > 0)
1201                         {
1202                                 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1203                                 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1204                         }
1205                         sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1206                         sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1207                         offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1208                         DrawQ_SuperPic(sbar_x +  120           * scale, sbar_y + ( 88 - offset) * scale, zymsb_crosshair_line, 16 * scale, 36 * scale, 0,0, 1,1,1,1, 1,0, 1,1,1,1, 0,1, 1,1,1,1, 1,1, 1,1,1,1, 0);
1209                         DrawQ_SuperPic(sbar_x + (132 + offset) * scale, sbar_y + 120            * scale, zymsb_crosshair_line, 36 * scale, 16 * scale, 0,1, 1,1,1,1, 0,0, 1,1,1,1, 1,1, 1,1,1,1, 1,0, 1,1,1,1, 0);
1210                         DrawQ_SuperPic(sbar_x +  120           * scale, sbar_y + (132 + offset) * scale, zymsb_crosshair_line, 16 * scale, 36 * scale, 1,1, 1,1,1,1, 0,1, 1,1,1,1, 1,0, 1,1,1,1, 0,0, 1,1,1,1, 0);
1211                         DrawQ_SuperPic(sbar_x + ( 88 - offset) * scale, sbar_y + 120            * scale, zymsb_crosshair_line, 36 * scale, 16 * scale, 1,0, 1,1,1,1, 1,1, 1,1,1,1, 0,0, 1,1,1,1, 0,1, 1,1,1,1, 0);
1212                         healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1213                         shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1214                         healthstart = 204 - healthheight;
1215                         shieldstart = healthstart - shieldheight;
1216                         healthstarttc = healthstart * (1.0f / 256.0f);
1217                         healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1218                         shieldstarttc = shieldstart * (1.0f / 256.0f);
1219                         shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1220                         ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1221                         ammostart = 114 - ammoheight;
1222                         ammostarttc = ammostart * (1.0f / 256.0f);
1223                         ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1224                         clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1225                         clipstart = 190 - clipheight;
1226                         clipstarttc = clipstart * (1.0f / 256.0f);
1227                         clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1228                         if (healthheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + healthstart * scale, zymsb_crosshair_health, 256 * scale, healthheight * scale, 0,healthstarttc, 1.0f,0.0f,0.0f,1.0f, 1,healthstarttc, 1.0f,0.0f,0.0f,1.0f, 0,healthendtc, 1.0f,0.0f,0.0f,1.0f, 1,healthendtc, 1.0f,0.0f,0.0f,1.0f, DRAWFLAG_NORMAL);
1229                         if (shieldheight > 0) DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + shieldstart * scale, zymsb_crosshair_health, 256 * scale, shieldheight * scale, 0,shieldstarttc, 0.0f,0.5f,1.0f,1.0f, 1,shieldstarttc, 0.0f,0.5f,1.0f,1.0f, 0,shieldendtc, 0.0f,0.5f,1.0f,1.0f, 1,shieldendtc, 0.0f,0.5f,1.0f,1.0f, DRAWFLAG_NORMAL);
1230                         if (ammoheight > 0)   DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + ammostart   * scale, zymsb_crosshair_ammo,   256 * scale, ammoheight   * scale, 0,ammostarttc,   0.8f,0.8f,0.0f,1.0f, 1,ammostarttc,   0.8f,0.8f,0.0f,1.0f, 0,ammoendtc,   0.8f,0.8f,0.0f,1.0f, 1,ammoendtc,   0.8f,0.8f,0.0f,1.0f, DRAWFLAG_NORMAL);
1231                         if (clipheight > 0)   DrawQ_SuperPic(sbar_x + 0 * scale, sbar_y + clipstart   * scale, zymsb_crosshair_clip,   256 * scale, clipheight   * scale, 0,clipstarttc,   1.0f,1.0f,0.0f,1.0f, 1,clipstarttc,   1.0f,1.0f,0.0f,1.0f, 0,clipendtc,   1.0f,1.0f,0.0f,1.0f, 1,clipendtc,   1.0f,1.0f,0.0f,1.0f, DRAWFLAG_NORMAL);
1232                         DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1233                         DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1234 #endif
1235                 }
1236                 else // Quake and others
1237                 {
1238                         sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1239                         // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1240                         //if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1241                         if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1242                                 sbar_x = 0;
1243                         else
1244                                 sbar_x = (vid_conwidth.integer - 320)/2;
1245
1246                         if (sb_lines > 24)
1247                         {
1248                                 if (gamemode != GAME_GOODVSBAD2)
1249                                         Sbar_DrawInventory ();
1250                                 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1251                                         Sbar_DrawFrags ();
1252                         }
1253
1254                         if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1255                         {
1256                                 if (gamemode != GAME_GOODVSBAD2)
1257                                         Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1258                                 Sbar_DrawScoreboard ();
1259                         }
1260                         else if (sb_lines)
1261                         {
1262                                 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1263
1264                                 // keys (hipnotic only)
1265                                 //MED 01/04/97 moved keys here so they would not be overwritten
1266                                 if (gamemode == GAME_HIPNOTIC)
1267                                 {
1268                                         if (cl.stats[STAT_ITEMS] & IT_KEY1)
1269                                                 Sbar_DrawPic (209, 3, sb_items[0]);
1270                                         if (cl.stats[STAT_ITEMS] & IT_KEY2)
1271                                                 Sbar_DrawPic (209, 12, sb_items[1]);
1272                                 }
1273                                 // armor
1274                                 if (gamemode != GAME_GOODVSBAD2)
1275                                 {
1276                                         if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1277                                         {
1278                                                 Sbar_DrawNum (24, 0, 666, 3, 1);
1279                                                 Sbar_DrawPic (0, 0, sb_disc);
1280                                         }
1281                                         else
1282                                         {
1283                                                 if (gamemode == GAME_ROGUE)
1284                                                 {
1285                                                         Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1286                                                         if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1287                                                                 Sbar_DrawPic (0, 0, sb_armor[2]);
1288                                                         else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1289                                                                 Sbar_DrawPic (0, 0, sb_armor[1]);
1290                                                         else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1291                                                                 Sbar_DrawPic (0, 0, sb_armor[0]);
1292                                                 }
1293                                                 else
1294                                                 {
1295                                                         Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1296                                                         if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1297                                                                 Sbar_DrawPic (0, 0, sb_armor[2]);
1298                                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1299                                                                 Sbar_DrawPic (0, 0, sb_armor[1]);
1300                                                         else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1301                                                                 Sbar_DrawPic (0, 0, sb_armor[0]);
1302                                                 }
1303                                         }
1304                                 }
1305
1306                                 // face
1307                                 Sbar_DrawFace ();
1308
1309                                 // health
1310                                 Sbar_DrawNum (154, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1311
1312                                 // ammo icon
1313                                 if (gamemode == GAME_ROGUE)
1314                                 {
1315                                         if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1316                                                 Sbar_DrawPic (224, 0, sb_ammo[0]);
1317                                         else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1318                                                 Sbar_DrawPic (224, 0, sb_ammo[1]);
1319                                         else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1320                                                 Sbar_DrawPic (224, 0, sb_ammo[2]);
1321                                         else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1322                                                 Sbar_DrawPic (224, 0, sb_ammo[3]);
1323                                         else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1324                                                 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1325                                         else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1326                                                 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1327                                         else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1328                                                 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1329                                 }
1330                                 else
1331                                 {
1332                                         if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1333                                                 Sbar_DrawPic (224, 0, sb_ammo[0]);
1334                                         else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1335                                                 Sbar_DrawPic (224, 0, sb_ammo[1]);
1336                                         else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1337                                                 Sbar_DrawPic (224, 0, sb_ammo[2]);
1338                                         else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1339                                                 Sbar_DrawPic (224, 0, sb_ammo[3]);
1340                                 }
1341
1342                                 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1343
1344                         }
1345
1346                         // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1347                         //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1348                         if (!cl.islocalgame && vid_conwidth.integer > 320)
1349                         {
1350                                 if (gamemode == GAME_TRANSFUSION)
1351                                         Sbar_MiniDeathmatchOverlay (0, 0);
1352                                 else
1353                                         Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1354                         }
1355                 }
1356         }
1357
1358         Sbar_ShowFPS();
1359
1360         if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && crosshair.integer <= NUMCROSSHAIRS && !cl.intermission && !r_letterbox.value && (pic = r_crosshairs[crosshair.integer]))
1361                 DrawQ_Pic((vid_conwidth.integer - pic->width * crosshair_size.value) * 0.5f, (vid_conheight.integer - pic->height * crosshair_size.value) * 0.5f, pic, pic->width * crosshair_size.value, pic->height * crosshair_size.value, crosshair_color_red.value, crosshair_color_green.value, crosshair_color_blue.value, crosshair_color_alpha.value, 0);
1362
1363         if (cl_prydoncursor.integer)
1364                 DrawQ_Pic((cl.cmd.cursor_screen[0] + 1) * 0.5 * vid_conwidth.integer, (cl.cmd.cursor_screen[1] + 1) * 0.5 * vid_conheight.integer, Draw_CachePic(va("gfx/prydoncursor%03i", cl_prydoncursor.integer), true), 0, 0, 1, 1, 1, 1, 0);
1365 }
1366
1367 //=============================================================================
1368
1369 /*
1370 ==================
1371 Sbar_DeathmatchOverlay
1372
1373 ==================
1374 */
1375 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1376 {
1377         int minutes;
1378         unsigned char *c;
1379         minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
1380         if (s->qw_spectator)
1381         {
1382                 if (s->qw_ping || s->qw_packetloss)
1383                         DrawQ_ColoredString(x, y, va("%4i %3i %4i spect %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1384                 else
1385                         DrawQ_ColoredString(x, y, va("         %4i spect %-4s %c%s", minutes, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1386         }
1387         else
1388         {
1389                 // draw colors behind score
1390                 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1391                 DrawQ_Pic(x + 14*8, y+1, NULL, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1392                 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1393                 DrawQ_Pic(x + 14*8, y+4, NULL, 40, 3, c[0] * (1.0f / 255.0f), c[1] * (1.0f / 255.0f), c[2] * (1.0f / 255.0f), c[3] * (1.0f / 255.0f) * sbar_alpha_fg.value, 0);
1394                 // print the text
1395                 //DrawQ_String(x, y, va("%c%4i %s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', (int) s->frags, s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1396                 if (s->qw_ping || s->qw_packetloss)
1397                         DrawQ_ColoredString(x, y, va("%4i %3i %4i %5i %-4s %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1398                 else
1399                         DrawQ_ColoredString(x, y, va("         %4i %5i %-4s %c%s", minutes,(int) s->frags, cl.qw_teamplay ? s->qw_team : "", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1400         }
1401         return 8;
1402 }
1403
1404 void Sbar_DeathmatchOverlay (void)
1405 {
1406         int i, x, y;
1407
1408         // request new ping times every two second
1409         if (cl.last_ping_request < realtime - 2 && cls.netcon)
1410         {
1411                 cl.last_ping_request = realtime;
1412                 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1413                 {
1414                         MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
1415                         MSG_WriteString(&cls.netcon->message, "pings");
1416                 }
1417                 else if (cls.protocol == PROTOCOL_QUAKE || cls.protocol == PROTOCOL_QUAKEDP || cls.protocol == PROTOCOL_NEHAHRAMOVIE || cls.protocol == PROTOCOL_DARKPLACES1 || cls.protocol == PROTOCOL_DARKPLACES2 || cls.protocol == PROTOCOL_DARKPLACES3 || cls.protocol == PROTOCOL_DARKPLACES4 || cls.protocol == PROTOCOL_DARKPLACES5 || cls.protocol == PROTOCOL_DARKPLACES6 || cls.protocol == PROTOCOL_DARKPLACES7)
1418                 {
1419                         // these servers usually lack the pings command and so a less efficient "ping" command must be sent, which on modern DP servers will also reply with a pingplreport command after the ping listing
1420                         cl.parsingtextexpectingpingforscores = true; // hide the output of the next ping report
1421                         MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
1422                         MSG_WriteString(&cls.netcon->message, "ping");
1423                 }
1424                 else
1425                 {
1426                         // newer server definitely has pings command, so use it for more efficiency
1427                         MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
1428                         MSG_WriteString(&cls.netcon->message, "pings");
1429                 }
1430         }
1431
1432         DrawQ_Pic ((vid_conwidth.integer - sb_ranking->width)/2, 8, sb_ranking, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1433
1434         // scores
1435         Sbar_SortFrags ();
1436         // draw the text
1437         x = (vid_conwidth.integer - (6 + 18 + 15) * 8) / 2;
1438         y = 40;
1439         DrawQ_ColoredString(x, y, va("ping pl%% time frags team  name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL );
1440         y += 8;
1441
1442         if (Sbar_IsTeammatch ())
1443         {
1444                 // show team scores first
1445                 for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
1446                         y += (int)Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
1447                 y += 5;
1448         }
1449
1450         for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1451                 y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1452 }
1453
1454 /*
1455 ==================
1456 Sbar_DeathmatchOverlay
1457
1458 ==================
1459 */
1460 void Sbar_MiniDeathmatchOverlay (int x, int y)
1461 {
1462         int i, numlines;
1463
1464         // decide where to print
1465         if (gamemode == GAME_TRANSFUSION)
1466                 numlines = (vid_conwidth.integer - x + 127) / 128;
1467         else
1468                 numlines = (vid_conheight.integer - y + 7) / 8;
1469
1470         // give up if there isn't room
1471         if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1472                 return;
1473
1474         // scores
1475         Sbar_SortFrags ();
1476
1477         //find us
1478         for (i = 0; i < scoreboardlines; i++)
1479                 if (fragsort[i] == cl.playerentity - 1)
1480                         break;
1481
1482         // figure out start
1483         i -= numlines/2;
1484         i = min(i, scoreboardlines - numlines);
1485         i = max(i, 0);
1486
1487         if (gamemode == GAME_TRANSFUSION)
1488         {
1489                 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1490                         x += 128 + (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1491         }
1492         else
1493         {
1494                 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1495                         y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1496         }
1497 }
1498
1499 /*
1500 ==================
1501 Sbar_IntermissionOverlay
1502
1503 ==================
1504 */
1505 void Sbar_IntermissionOverlay (void)
1506 {
1507         int             dig;
1508         int             num;
1509
1510         // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1511         //if (cl.gametype == GAME_DEATHMATCH)
1512         if (!cl.islocalgame)
1513         {
1514                 Sbar_DeathmatchOverlay ();
1515                 return;
1516         }
1517
1518         sbar_x = (vid_conwidth.integer - 320) >> 1;
1519         sbar_y = (vid_conheight.integer - 200) >> 1;
1520
1521         DrawQ_Pic (sbar_x + 64, sbar_y + 24, sb_complete, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1522         DrawQ_Pic (sbar_x + 0, sbar_y + 56, sb_inter, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1523
1524 // time
1525         dig = (int)cl.completed_time / 60;
1526         Sbar_DrawNum (160, 64, dig, 3, 0);
1527         num = (int)cl.completed_time - dig*60;
1528         if (gamemode != GAME_NEXUIZ)
1529                 Sbar_DrawPic (234,64,sb_colon);
1530         Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1531         Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1532
1533         Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1534         if (gamemode != GAME_NEXUIZ)
1535                 Sbar_DrawPic (232, 104, sb_slash);
1536         Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1537
1538         Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1539         if (gamemode != GAME_NEXUIZ)
1540                 Sbar_DrawPic (232, 144, sb_slash);
1541         Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1542
1543 }
1544
1545
1546 /*
1547 ==================
1548 Sbar_FinaleOverlay
1549
1550 ==================
1551 */
1552 void Sbar_FinaleOverlay (void)
1553 {
1554         DrawQ_Pic((vid_conwidth.integer - sb_finale->width)/2, 16, sb_finale, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1555 }
1556