2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // sbar.c -- status bar code
26 #define STAT_MINUS 10 // num frame for '-' stats digit
27 cachepic_t *sb_nums[2][11];
28 cachepic_t *sb_colon, *sb_slash;
31 cachepic_t *sb_scorebar;
32 // AK only used by NEX
33 cachepic_t *sb_sbar_minimal;
34 cachepic_t *sb_sbar_overlay;
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];
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];
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;
52 qboolean sb_showscores;
54 int sb_lines; // scan lines to draw
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
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];
70 cachepic_t *somsb_health;
71 cachepic_t *somsb_ammo[4];
72 cachepic_t *somsb_armor[3];
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;
84 cachepic_t *sb_ranking;
85 cachepic_t *sb_complete;
87 cachepic_t *sb_finale;
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"};
97 cvar_t cl_deathscoreboard = {0, "cl_deathscoreboard", "1", "shows scoreboard (+showscores) while dead"};
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"};
105 void Sbar_MiniDeathmatchOverlay (int x, int y);
106 void Sbar_DeathmatchOverlay (void);
107 void Sbar_IntermissionOverlay (void);
108 void Sbar_FinaleOverlay (void);
118 void Sbar_ShowScores (void)
122 sb_showscores = true;
132 void Sbar_DontShowScores (void)
134 sb_showscores = false;
137 void sbar_start(void)
141 if (gamemode == GAME_NETHERWORLD)
144 else if (gamemode == GAME_SOM)
146 sb_disc = Draw_CachePic("gfx/disc", true);
148 for (i = 0;i < 10;i++)
149 sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
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);
160 else if (gamemode == GAME_NEXUIZ)
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);
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);
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);
176 sb_items[11] = Draw_CachePic ("gfx/sb_flag_red_taken", true);
177 sb_items[12] = Draw_CachePic ("gfx/sb_flag_red_lost", true);
178 sb_items[13] = Draw_CachePic ("gfx/sb_flag_red_carrying", true);
179 sb_items[14] = Draw_CachePic ("gfx/sb_key_carrying", true);
180 sb_items[15] = Draw_CachePic ("gfx/sb_flag_blue_taken", true);
181 sb_items[16] = Draw_CachePic ("gfx/sb_flag_blue_lost", true);
182 sb_items[17] = Draw_CachePic ("gfx/sb_flag_blue_carrying", true);
184 sb_sbar = Draw_CachePic("gfx/sbar", true);
185 sb_sbar_minimal = Draw_CachePic("gfx/sbar_minimal", true);
186 sb_sbar_overlay = Draw_CachePic("gfx/sbar_overlay", true);
188 for(i = 0; i < 9;i++)
189 sb_weapons[0][i] = Draw_CachePic(va("gfx/inv_weapon%i",i), true);
191 else if (gamemode == GAME_ZYMOTIC)
193 zymsb_crosshair_center = Draw_CachePic ("gfx/hud/crosshair_center", true);
194 zymsb_crosshair_line = Draw_CachePic ("gfx/hud/crosshair_line", true);
195 zymsb_crosshair_health = Draw_CachePic ("gfx/hud/crosshair_health", true);
196 zymsb_crosshair_clip = Draw_CachePic ("gfx/hud/crosshair_clip", true);
197 zymsb_crosshair_ammo = Draw_CachePic ("gfx/hud/crosshair_ammo", true);
198 zymsb_crosshair_background = Draw_CachePic ("gfx/hud/crosshair_background", true);
199 zymsb_crosshair_left1 = Draw_CachePic ("gfx/hud/crosshair_left1", true);
200 zymsb_crosshair_left2 = Draw_CachePic ("gfx/hud/crosshair_left2", true);
201 zymsb_crosshair_right = Draw_CachePic ("gfx/hud/crosshair_right", true);
205 sb_disc = Draw_CachePic("gfx/disc", true);
207 for (i = 0;i < 10;i++)
209 sb_nums[0][i] = Draw_CachePic (va("gfx/num_%i",i), true);
210 sb_nums[1][i] = Draw_CachePic (va("gfx/anum_%i",i), true);
213 sb_nums[0][10] = Draw_CachePic ("gfx/num_minus", true);
214 sb_nums[1][10] = Draw_CachePic ("gfx/anum_minus", true);
216 sb_colon = Draw_CachePic ("gfx/num_colon", true);
217 sb_slash = Draw_CachePic ("gfx/num_slash", true);
219 sb_weapons[0][0] = Draw_CachePic ("gfx/inv_shotgun", true);
220 sb_weapons[0][1] = Draw_CachePic ("gfx/inv_sshotgun", true);
221 sb_weapons[0][2] = Draw_CachePic ("gfx/inv_nailgun", true);
222 sb_weapons[0][3] = Draw_CachePic ("gfx/inv_snailgun", true);
223 sb_weapons[0][4] = Draw_CachePic ("gfx/inv_rlaunch", true);
224 sb_weapons[0][5] = Draw_CachePic ("gfx/inv_srlaunch", true);
225 sb_weapons[0][6] = Draw_CachePic ("gfx/inv_lightng", true);
227 sb_weapons[1][0] = Draw_CachePic ("gfx/inv2_shotgun", true);
228 sb_weapons[1][1] = Draw_CachePic ("gfx/inv2_sshotgun", true);
229 sb_weapons[1][2] = Draw_CachePic ("gfx/inv2_nailgun", true);
230 sb_weapons[1][3] = Draw_CachePic ("gfx/inv2_snailgun", true);
231 sb_weapons[1][4] = Draw_CachePic ("gfx/inv2_rlaunch", true);
232 sb_weapons[1][5] = Draw_CachePic ("gfx/inv2_srlaunch", true);
233 sb_weapons[1][6] = Draw_CachePic ("gfx/inv2_lightng", true);
235 for (i = 0;i < 5;i++)
237 sb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_shotgun",i+1), true);
238 sb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_sshotgun",i+1), true);
239 sb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_nailgun",i+1), true);
240 sb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_snailgun",i+1), true);
241 sb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_rlaunch",i+1), true);
242 sb_weapons[2+i][5] = Draw_CachePic (va("gfx/inva%i_srlaunch",i+1), true);
243 sb_weapons[2+i][6] = Draw_CachePic (va("gfx/inva%i_lightng",i+1), true);
246 sb_ammo[0] = Draw_CachePic ("gfx/sb_shells", true);
247 sb_ammo[1] = Draw_CachePic ("gfx/sb_nails", true);
248 sb_ammo[2] = Draw_CachePic ("gfx/sb_rocket", true);
249 sb_ammo[3] = Draw_CachePic ("gfx/sb_cells", true);
251 sb_armor[0] = Draw_CachePic ("gfx/sb_armor1", true);
252 sb_armor[1] = Draw_CachePic ("gfx/sb_armor2", true);
253 sb_armor[2] = Draw_CachePic ("gfx/sb_armor3", true);
255 sb_items[0] = Draw_CachePic ("gfx/sb_key1", true);
256 sb_items[1] = Draw_CachePic ("gfx/sb_key2", true);
257 sb_items[2] = Draw_CachePic ("gfx/sb_invis", true);
258 sb_items[3] = Draw_CachePic ("gfx/sb_invuln", true);
259 sb_items[4] = Draw_CachePic ("gfx/sb_suit", true);
260 sb_items[5] = Draw_CachePic ("gfx/sb_quad", true);
262 sb_sigil[0] = Draw_CachePic ("gfx/sb_sigil1", true);
263 sb_sigil[1] = Draw_CachePic ("gfx/sb_sigil2", true);
264 sb_sigil[2] = Draw_CachePic ("gfx/sb_sigil3", true);
265 sb_sigil[3] = Draw_CachePic ("gfx/sb_sigil4", true);
267 sb_faces[4][0] = Draw_CachePic ("gfx/face1", true);
268 sb_faces[4][1] = Draw_CachePic ("gfx/face_p1", true);
269 sb_faces[3][0] = Draw_CachePic ("gfx/face2", true);
270 sb_faces[3][1] = Draw_CachePic ("gfx/face_p2", true);
271 sb_faces[2][0] = Draw_CachePic ("gfx/face3", true);
272 sb_faces[2][1] = Draw_CachePic ("gfx/face_p3", true);
273 sb_faces[1][0] = Draw_CachePic ("gfx/face4", true);
274 sb_faces[1][1] = Draw_CachePic ("gfx/face_p4", true);
275 sb_faces[0][0] = Draw_CachePic ("gfx/face5", true);
276 sb_faces[0][1] = Draw_CachePic ("gfx/face_p5", true);
278 sb_face_invis = Draw_CachePic ("gfx/face_invis", true);
279 sb_face_invuln = Draw_CachePic ("gfx/face_invul2", true);
280 sb_face_invis_invuln = Draw_CachePic ("gfx/face_inv2", true);
281 sb_face_quad = Draw_CachePic ("gfx/face_quad", true);
283 sb_sbar = Draw_CachePic ("gfx/sbar", true);
284 sb_ibar = Draw_CachePic ("gfx/ibar", true);
285 sb_scorebar = Draw_CachePic ("gfx/scorebar", true);
287 //MED 01/04/97 added new hipnotic weapons
288 if (gamemode == GAME_HIPNOTIC)
290 hsb_weapons[0][0] = Draw_CachePic ("gfx/inv_laser", true);
291 hsb_weapons[0][1] = Draw_CachePic ("gfx/inv_mjolnir", true);
292 hsb_weapons[0][2] = Draw_CachePic ("gfx/inv_gren_prox", true);
293 hsb_weapons[0][3] = Draw_CachePic ("gfx/inv_prox_gren", true);
294 hsb_weapons[0][4] = Draw_CachePic ("gfx/inv_prox", true);
296 hsb_weapons[1][0] = Draw_CachePic ("gfx/inv2_laser", true);
297 hsb_weapons[1][1] = Draw_CachePic ("gfx/inv2_mjolnir", true);
298 hsb_weapons[1][2] = Draw_CachePic ("gfx/inv2_gren_prox", true);
299 hsb_weapons[1][3] = Draw_CachePic ("gfx/inv2_prox_gren", true);
300 hsb_weapons[1][4] = Draw_CachePic ("gfx/inv2_prox", true);
302 for (i = 0;i < 5;i++)
304 hsb_weapons[2+i][0] = Draw_CachePic (va("gfx/inva%i_laser",i+1), true);
305 hsb_weapons[2+i][1] = Draw_CachePic (va("gfx/inva%i_mjolnir",i+1), true);
306 hsb_weapons[2+i][2] = Draw_CachePic (va("gfx/inva%i_gren_prox",i+1), true);
307 hsb_weapons[2+i][3] = Draw_CachePic (va("gfx/inva%i_prox_gren",i+1), true);
308 hsb_weapons[2+i][4] = Draw_CachePic (va("gfx/inva%i_prox",i+1), true);
311 hsb_items[0] = Draw_CachePic ("gfx/sb_wsuit", true);
312 hsb_items[1] = Draw_CachePic ("gfx/sb_eshld", true);
314 else if (gamemode == GAME_ROGUE)
316 rsb_invbar[0] = Draw_CachePic ("gfx/r_invbar1", true);
317 rsb_invbar[1] = Draw_CachePic ("gfx/r_invbar2", true);
319 rsb_weapons[0] = Draw_CachePic ("gfx/r_lava", true);
320 rsb_weapons[1] = Draw_CachePic ("gfx/r_superlava", true);
321 rsb_weapons[2] = Draw_CachePic ("gfx/r_gren", true);
322 rsb_weapons[3] = Draw_CachePic ("gfx/r_multirock", true);
323 rsb_weapons[4] = Draw_CachePic ("gfx/r_plasma", true);
325 rsb_items[0] = Draw_CachePic ("gfx/r_shield1", true);
326 rsb_items[1] = Draw_CachePic ("gfx/r_agrav1", true);
328 // PGM 01/19/97 - team color border
329 rsb_teambord = Draw_CachePic ("gfx/r_teambord", true);
330 // PGM 01/19/97 - team color border
332 rsb_ammo[0] = Draw_CachePic ("gfx/r_ammolava", true);
333 rsb_ammo[1] = Draw_CachePic ("gfx/r_ammomulti", true);
334 rsb_ammo[2] = Draw_CachePic ("gfx/r_ammoplasma", true);
338 sb_ranking = Draw_CachePic ("gfx/ranking", true);
339 sb_complete = Draw_CachePic ("gfx/complete", true);
340 sb_inter = Draw_CachePic ("gfx/inter", true);
341 sb_finale = Draw_CachePic ("gfx/finale", true);
344 void sbar_shutdown(void)
348 void sbar_newmap(void)
352 void Sbar_Init (void)
354 Cmd_AddCommand("+showscores", Sbar_ShowScores, "show scoreboard");
355 Cmd_AddCommand("-showscores", Sbar_DontShowScores, "hide scoreboard");
356 Cvar_RegisterVariable(&showfps);
357 Cvar_RegisterVariable(&showtime);
358 Cvar_RegisterVariable(&showtime_format);
359 Cvar_RegisterVariable(&showdate);
360 Cvar_RegisterVariable(&showdate_format);
361 Cvar_RegisterVariable(&sbar_alpha_bg);
362 Cvar_RegisterVariable(&sbar_alpha_fg);
363 Cvar_RegisterVariable(&cl_deathscoreboard);
365 Cvar_RegisterVariable(&crosshair_color_red);
366 Cvar_RegisterVariable(&crosshair_color_green);
367 Cvar_RegisterVariable(&crosshair_color_blue);
368 Cvar_RegisterVariable(&crosshair_color_alpha);
369 Cvar_RegisterVariable(&crosshair_size);
371 R_RegisterModule("sbar", sbar_start, sbar_shutdown, sbar_newmap);
375 //=============================================================================
377 // drawing routines are relative to the status bar location
386 void Sbar_DrawPic (int x, int y, cachepic_t *pic)
388 DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, sbar_alpha_fg.value, 0);
391 void Sbar_DrawAlphaPic (int x, int y, cachepic_t *pic, float alpha)
393 DrawQ_Pic (sbar_x + x, sbar_y + y, pic, 0, 0, 1, 1, 1, alpha, 0);
400 Draws one solid graphics character
403 void Sbar_DrawCharacter (int x, int y, int num)
405 DrawQ_String (sbar_x + x + 4 , sbar_y + y, va("%c", num), 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, true);
413 void Sbar_DrawString (int x, int y, char *str)
415 DrawQ_String (sbar_x + x, sbar_y + y, str, 0, 8, 8, 1, 1, 1, sbar_alpha_fg.value, 0, NULL, false);
423 void Sbar_DrawNum (int x, int y, int num, int digits, int color)
428 l = sprintf(str, "%i", num);
442 Sbar_DrawPic (x, y, sb_nums[color][frame]);
455 void Sbar_DrawXNum (int x, int y, int num, int digits, int lettersize, float r, float g, float b, float a, int flags)
460 l = sprintf(str, "%i", num);
465 x += (digits-l) * lettersize;
474 DrawQ_Pic (sbar_x + x, sbar_y + y, sb_nums[0][frame],lettersize,lettersize,r,g,b,a * sbar_alpha_fg.value,flags);
481 //=============================================================================
484 int Sbar_IsTeammatch()
486 // currently only nexuiz uses the team score board
487 return ((gamemode == GAME_NEXUIZ)
488 && (teamplay.integer > 0));
496 static int fragsort[MAX_SCOREBOARD];
497 static int scoreboardlines;
499 //[515]: Sbar_GetPlayer for csqc "getplayerkey" func
500 int Sbar_GetPlayer (int index)
505 if(index >= scoreboardlines)
507 index = fragsort[index];
509 if(index >= scoreboardlines)
514 static scoreboard_t teams[MAX_SCOREBOARD];
515 static int teamsort[MAX_SCOREBOARD];
516 static int teamlines;
517 void Sbar_SortFrags (void)
523 for (i=0 ; i<cl.maxclients ; i++)
525 if (cl.scores[i].name[0])
527 fragsort[scoreboardlines] = i;
532 for (i=0 ; i<scoreboardlines ; i++)
533 for (j=0 ; j<scoreboardlines-1-i ; j++)
534 if (cl.scores[fragsort[j]].frags < cl.scores[fragsort[j+1]].frags)
537 fragsort[j] = fragsort[j+1];
542 if (Sbar_IsTeammatch ())
544 // now sort players by teams.
545 for (i=0 ; i<scoreboardlines ; i++)
547 for (j=0 ; j<scoreboardlines-1-i ; j++)
549 if (cl.scores[fragsort[j]].colors < cl.scores[fragsort[j+1]].colors)
552 fragsort[j] = fragsort[j+1];
558 // calculate team scores
560 for (i=0 ; i<scoreboardlines ; i++)
562 if (color != (cl.scores[fragsort[i]].colors & 15))
564 const char* teamname;
566 color = cl.scores[fragsort[i]].colors & 15;
572 teamname = "^1Red Team";
575 teamname = "^4Blue Team";
578 teamname = "^6Pink Team";
581 teamname = "^3Yellow Team";
584 teamname = "Total Team Score";
587 strlcpy(teams[teamlines-1].name, teamname, sizeof(teams[teamlines-1].name));
589 teams[teamlines-1].frags = 0;
590 teams[teamlines-1].colors = color + 16 * color;
593 if (cl.scores[fragsort[i]].frags != -666)
595 // do not add spedcators
596 // (ugly hack for nexuiz)
597 teams[teamlines-1].frags += cl.scores[fragsort[i]].frags;
601 // now sort teams by scores.
602 for (i=0 ; i<teamlines ; i++)
604 for (i=0 ; i<teamlines ; i++)
606 for (j=0 ; j<teamlines-1-i ; j++)
608 if (teams[teamsort[j]].frags < teams[teamsort[j+1]].frags)
611 teamsort[j] = teamsort[j+1];
624 void Sbar_SoloScoreboard (void)
627 char str[80], timestr[40];
629 int minutes, seconds;
632 t = (cl.intermission ? cl.completed_time : cl.time);
633 minutes = (int)(t / 60);
634 seconds = (int)(t - 60*floor(t/60));
636 // monsters and secrets are now both on the top row
637 if (cl.stats[STAT_TOTALMONSTERS])
638 Sbar_DrawString(8, 4, va("Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]));
639 if (cl.stats[STAT_TOTALSECRETS])
640 Sbar_DrawString(8+22*8, 4, va("Secrets:%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]));
642 // figure out the map's filename without path or extension
643 strlcpy(str, FS_FileWithoutPath(cl.worldmodel ? cl.worldmodel->name : ""), sizeof(str));
644 if (strrchr(str, '.'))
645 *(strrchr(str, '.')) = 0;
647 // append a : separator and then the full title
648 strlcat(str, ":", sizeof(str));
649 strlcat(str, cl.levelname, sizeof(str));
651 // if there's a newline character, terminate the string there
652 if (strchr(str, '\n'))
653 *(strchr(str, '\n')) = 0;
655 // make the time string
656 timelen = sprintf(timestr, " %i:%02i", minutes, seconds);
658 // truncate the level name if necessary to make room for time
660 if ((int)strlen(str) > max)
663 // print the filename and message
664 Sbar_DrawString(8, 12, str);
667 Sbar_DrawString(8 + max*8, 12, timestr);
671 int minutes, seconds, tens, units;
674 if (gamemode != GAME_NEXUIZ) {
675 sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
676 Sbar_DrawString (8, 4, str);
678 sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]);
679 Sbar_DrawString (8, 12, str);
683 minutes = (int)(cl.time / 60);
684 seconds = (int)(cl.time - 60*minutes);
686 units = seconds - 10*tens;
687 sprintf (str,"Time :%3i:%i%i", minutes, tens, units);
688 Sbar_DrawString (184, 4, str);
691 if (gamemode == GAME_NEXUIZ) {
692 l = (int) strlen (cl.worldmodel->name);
693 Sbar_DrawString (232 - l*4, 12, cl.worldmodel->name);
695 l = (int) strlen (cl.levelname);
696 Sbar_DrawString (232 - l*4, 12, cl.levelname);
706 void Sbar_DrawScoreboard (void)
708 Sbar_SoloScoreboard ();
709 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
710 //if (cl.gametype == GAME_DEATHMATCH)
712 Sbar_DeathmatchOverlay ();
715 //=============================================================================
717 // AK to make DrawInventory smaller
718 static void Sbar_DrawWeapon(int nr, float fade, int active)
720 // width = 300, height = 100
721 const int w_width = 300, w_height = 100, w_space = 10;
722 const float w_scale = 0.4;
724 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_NORMAL);
725 //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, NULL, true);
733 void Sbar_DrawInventory (void)
740 if (gamemode == GAME_ROGUE)
742 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
743 Sbar_DrawAlphaPic (0, -24, rsb_invbar[0], sbar_alpha_bg.value);
745 Sbar_DrawAlphaPic (0, -24, rsb_invbar[1], sbar_alpha_bg.value);
748 Sbar_DrawAlphaPic (0, -24, sb_ibar, sbar_alpha_bg.value);
751 for (i=0 ; i<7 ; i++)
753 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
755 time = cl.item_gettime[i];
756 flashon = (int)(max(0, cl.time - time)*10);
759 if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
765 flashon = (flashon%5) + 2;
767 Sbar_DrawAlphaPic (i*24, -16, sb_weapons[flashon][i], sbar_alpha_bg.value);
773 if (gamemode == GAME_HIPNOTIC)
775 int grenadeflashing=0;
776 for (i=0 ; i<4 ; i++)
778 if (cl.stats[STAT_ITEMS] & (1<<hipweapons[i]) )
780 time = max(0, cl.item_gettime[hipweapons[i]]);
781 flashon = (int)((cl.time - time)*10);
784 if ( cl.stats[STAT_ACTIVEWEAPON] == (1<<hipweapons[i]) )
790 flashon = (flashon%5) + 2;
792 // check grenade launcher
795 if (cl.stats[STAT_ITEMS] & HIT_PROXIMITY_GUN)
800 Sbar_DrawPic (96, -16, hsb_weapons[flashon][2]);
806 if (cl.stats[STAT_ITEMS] & (IT_SHOTGUN<<4))
808 if (!grenadeflashing)
809 Sbar_DrawPic (96, -16, hsb_weapons[flashon][3]);
812 Sbar_DrawPic (96, -16, hsb_weapons[flashon][4]);
815 Sbar_DrawPic (176 + (i*24), -16, hsb_weapons[flashon][i]);
820 if (gamemode == GAME_ROGUE)
822 // check for powered up weapon.
823 if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
825 if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
826 Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]);
830 for (i=0 ; i<4 ; i++)
832 sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] );
834 Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
836 Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
838 Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
842 for (i=0 ; i<6 ; i++)
843 if (cl.stats[STAT_ITEMS] & (1<<(17+i)))
845 //MED 01/04/97 changed keys
846 if (gamemode != GAME_HIPNOTIC || (i>1))
847 Sbar_DrawPic (192 + i*16, -16, sb_items[i]);
850 //MED 01/04/97 added hipnotic items
852 if (gamemode == GAME_HIPNOTIC)
854 for (i=0 ; i<2 ; i++)
855 if (cl.stats[STAT_ITEMS] & (1<<(24+i)))
856 Sbar_DrawPic (288 + i*16, -16, hsb_items[i]);
859 if (gamemode == GAME_ROGUE)
862 for (i=0 ; i<2 ; i++)
863 if (cl.stats[STAT_ITEMS] & (1<<(29+i)))
864 Sbar_DrawPic (288 + i*16, -16, rsb_items[i]);
869 for (i=0 ; i<4 ; i++)
870 if (cl.stats[STAT_ITEMS] & (1<<(28+i)))
871 Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]);
875 //=============================================================================
882 void Sbar_DrawFrags (void)
892 l = min(scoreboardlines, 4);
896 for (i = 0;i < l;i++)
902 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
903 DrawQ_Fill (sbar_x + x + 10, sbar_y - 23, 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);
904 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
905 DrawQ_Fill (sbar_x + x + 10, sbar_y + 4 - 23, 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);
909 sprintf (num, "%3i",f);
911 if (k == cl.viewentity - 1)
913 Sbar_DrawCharacter ( x + 2, -24, 16);
914 Sbar_DrawCharacter ( x + 32 - 4, -24, 17);
916 Sbar_DrawCharacter (x + 8, -24, num[0]);
917 Sbar_DrawCharacter (x + 16, -24, num[1]);
918 Sbar_DrawCharacter (x + 24, -24, num[2]);
923 //=============================================================================
931 void Sbar_DrawFace (void)
935 // PGM 01/19/97 - team color drawing
936 // PGM 03/02/97 - fixed so color swatch only appears in CTF modes
937 if (gamemode == GAME_ROGUE && !cl.islocalgame && (teamplay.integer > 3) && (teamplay.integer < 7))
943 s = &cl.scores[cl.viewentity - 1];
945 Sbar_DrawPic (112, 0, rsb_teambord);
946 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
947 DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+3, 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);
948 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
949 DrawQ_Fill (sbar_x + 113, vid_conheight.integer-SBAR_HEIGHT+12, 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);
953 sprintf (num, "%3i",f);
955 if ((s->colors & 0xf0)==0)
958 Sbar_DrawCharacter(109, 3, 18 + num[0] - '0');
960 Sbar_DrawCharacter(116, 3, 18 + num[1] - '0');
962 Sbar_DrawCharacter(123, 3, 18 + num[2] - '0');
966 Sbar_DrawCharacter ( 109, 3, num[0]);
967 Sbar_DrawCharacter ( 116, 3, num[1]);
968 Sbar_DrawCharacter ( 123, 3, num[2]);
973 // PGM 01/19/97 - team color drawing
975 if ( (cl.stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) )
976 Sbar_DrawPic (112, 0, sb_face_invis_invuln);
977 else if (cl.stats[STAT_ITEMS] & IT_QUAD)
978 Sbar_DrawPic (112, 0, sb_face_quad );
979 else if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
980 Sbar_DrawPic (112, 0, sb_face_invis );
981 else if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
982 Sbar_DrawPic (112, 0, sb_face_invuln);
985 f = cl.stats[STAT_HEALTH] / 20;
987 Sbar_DrawPic (112, 0, sb_faces[f][cl.time <= cl.faceanimtime]);
991 void Sbar_ShowFPS(void)
993 float fps_x, fps_y, fps_scalex, fps_scaley, fps_height;
997 qboolean red = false;
1001 if (showfps.integer)
1004 static double nexttime = 0, lasttime = 0;
1005 static double framerate = 0;
1006 static int framecount = 0;
1009 if (newtime >= nexttime)
1011 framerate = framecount / (newtime - lasttime);
1013 nexttime = max(nexttime + 1, lasttime - 1);
1019 if ((red = (calc < 1.0f)))
1020 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i spf", (int)(1.0f / calc + 0.5));
1022 dpsnprintf(fpsstring, sizeof(fpsstring), "%4i fps", (int)(calc + 0.5));
1024 if (showtime.integer)
1025 strlcpy(timestring, Sys_TimeString(showtime_format.string), sizeof(timestring));
1026 if (showdate.integer)
1027 strlcpy(datestring, Sys_TimeString(showdate_format.string), sizeof(datestring));
1028 if (fpsstring[0] || timestring[0])
1032 fps_height = fps_scaley * ((fpsstring[0] != 0) + (timestring[0] != 0) + (datestring[0] != 0));
1033 //fps_y = vid_conheight.integer - sb_lines; // yes this may draw over the sbar
1034 //fps_y = bound(0, fps_y, vid_conheight.integer - fps_height);
1035 fps_y = vid_conheight.integer - fps_height;
1038 fps_x = vid_conwidth.integer - fps_scalex * strlen(fpsstring);
1039 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(fpsstring), fps_scaley, 0, 0, 0, 0.5, 0);
1041 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 0, 0, 1, 0, NULL, true);
1043 DrawQ_String(fps_x, fps_y, fpsstring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
1044 fps_y += fps_scaley;
1048 fps_x = vid_conwidth.integer - fps_scalex * strlen(timestring);
1049 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(timestring), fps_scaley, 0, 0, 0, 0.5, 0);
1050 DrawQ_String(fps_x, fps_y, timestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
1051 fps_y += fps_scaley;
1055 fps_x = vid_conwidth.integer - fps_scalex * strlen(datestring);
1056 DrawQ_Fill(fps_x, fps_y, fps_scalex * strlen(datestring), fps_scaley, 0, 0, 0, 0.5, 0);
1057 DrawQ_String(fps_x, fps_y, datestring, 0, fps_scalex, fps_scaley, 1, 1, 1, 1, 0, NULL, true);
1058 fps_y += fps_scaley;
1063 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)
1066 c2 = bound(0, c2, 1);
1067 c1 = bound(0, c1, 1 - c2);
1069 r[1] = rangey + rangeheight * (c2 + c1);
1070 r[2] = rangey + rangeheight * (c2);
1074 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);
1076 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);
1078 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);
1080 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);
1088 extern float v_dmg_time, v_dmg_roll, v_dmg_pitch;
1089 extern cvar_t v_kicktime;
1090 void Sbar_Draw (void)
1094 if(cl.csqc_vidvars.drawenginesbar) //[515]: csqc drawsbar
1097 Sbar_DrawScoreboard ();
1098 else if (cl.intermission == 1)
1100 if(gamemode == GAME_NEXUIZ) // display full scoreboard (that is, show scores + map name)
1102 Sbar_DrawScoreboard();
1105 Sbar_IntermissionOverlay();
1107 else if (cl.intermission == 2)
1108 Sbar_FinaleOverlay();
1109 else if (gamemode == GAME_NETHERWORLD)
1112 else if (gamemode == GAME_SOM)
1114 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1115 Sbar_DrawScoreboard ();
1118 // this is the top left of the sbar area
1120 sbar_y = vid_conheight.integer - 24*3;
1123 if (cl.stats[STAT_ARMOR])
1125 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1126 Sbar_DrawPic(0, 0, somsb_armor[2]);
1127 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1128 Sbar_DrawPic(0, 0, somsb_armor[1]);
1129 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1130 Sbar_DrawPic(0, 0, somsb_armor[0]);
1131 Sbar_DrawNum(24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1135 Sbar_DrawPic(0, 24, somsb_health);
1136 Sbar_DrawNum(24, 24, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1139 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1140 Sbar_DrawPic(0, 48, somsb_ammo[0]);
1141 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1142 Sbar_DrawPic(0, 48, somsb_ammo[1]);
1143 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1144 Sbar_DrawPic(0, 48, somsb_ammo[2]);
1145 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1146 Sbar_DrawPic(0, 48, somsb_ammo[3]);
1147 Sbar_DrawNum(24, 48, cl.stats[STAT_AMMO], 3, false);
1148 if (cl.stats[STAT_SHELLS])
1149 Sbar_DrawNum(24 + 3*24, 48, cl.stats[STAT_SHELLS], 1, true);
1152 else if (gamemode == GAME_NEXUIZ)
1154 sbar_y = vid_conheight.integer - 47;
1155 sbar_x = (vid_conwidth.integer - 640)/2;
1157 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1159 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1160 Sbar_DrawScoreboard ();
1166 int redflag, blueflag;
1168 // calculate intensity to draw weapons bar at
1169 fade = 3 - 2 * (cl.time - cl.weapontime);
1172 fade = min(fade, 1);
1173 for (i = 0; i < 8;i++)
1174 if (cl.stats[STAT_ITEMS] & (1 << i))
1175 Sbar_DrawWeapon(i + 1, fade, (i + 2 == cl.stats[STAT_ACTIVEWEAPON]));
1177 if((cl.stats[STAT_ITEMS] & (1<<12)))
1178 Sbar_DrawWeapon(0, fade, (cl.stats[STAT_ACTIVEWEAPON] == 1));
1181 //if (!cl.islocalgame)
1182 // Sbar_DrawFrags ();
1185 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_fg.value);
1187 Sbar_DrawAlphaPic (0, 0, sb_sbar_minimal, sbar_alpha_fg.value);
1190 redflag = ((cl.stats[STAT_ITEMS]>>15) & 3);
1191 blueflag = ((cl.stats[STAT_ITEMS]>>17) & 3);
1192 if (redflag == 3 && blueflag == 3)
1194 // The Impossible Combination[tm]
1195 // Can only happen in Key Hunt mode...
1196 Sbar_DrawPic (10 - sbar_x, -179, sb_items[14]);
1201 Sbar_DrawPic (10 - sbar_x, -109, sb_items[redflag+10]);
1203 Sbar_DrawPic (10 - sbar_x, -169, sb_items[blueflag+14]);
1207 Sbar_DrawXNum ((340-3*24), 12, cl.stats[STAT_ARMOR], 3, 24, 0.6,0.7,0.8,1,0);
1210 if(cl.stats[STAT_HEALTH] > 100)
1211 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,1,1,1,1,0);
1212 else if(cl.stats[STAT_HEALTH] <= 25 && cl.time - (int)cl.time > 0.5)
1213 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.7,0,0,1,0);
1215 Sbar_DrawXNum((154-3*24),12,cl.stats[STAT_HEALTH],3,24,0.6,0.7,0.8,1,0);
1217 // AK dont draw ammo for the laser
1218 if(cl.stats[STAT_ACTIVEWEAPON] != 12)
1220 if (cl.stats[STAT_ITEMS] & NEX_IT_SHELLS)
1221 Sbar_DrawPic (519, 0, sb_ammo[0]);
1222 else if (cl.stats[STAT_ITEMS] & NEX_IT_BULLETS)
1223 Sbar_DrawPic (519, 0, sb_ammo[1]);
1224 else if (cl.stats[STAT_ITEMS] & NEX_IT_ROCKETS)
1225 Sbar_DrawPic (519, 0, sb_ammo[2]);
1226 else if (cl.stats[STAT_ITEMS] & NEX_IT_CELLS)
1227 Sbar_DrawPic (519, 0, sb_ammo[3]);
1229 if(cl.stats[STAT_AMMO] <= 10)
1230 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.7, 0,0,1,0);
1232 Sbar_DrawXNum ((519-3*24), 12, cl.stats[STAT_AMMO], 3, 24, 0.6, 0.7,0.8,1,0);
1237 DrawQ_Pic(sbar_x,sbar_y,sb_sbar_overlay,0,0,1,1,1,1,DRAWFLAG_MODULATE);
1240 //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1241 // Sbar_MiniDeathmatchOverlay (0, 17);
1243 else if (gamemode == GAME_ZYMOTIC)
1246 float scale = 64.0f / 256.0f;
1247 float kickoffset[3];
1248 VectorClear(kickoffset);
1251 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1252 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1254 sbar_x = (int)((vid_conwidth.integer - 256 * scale)/2 + kickoffset[0]);
1255 sbar_y = (int)((vid_conheight.integer - 256 * scale)/2 + kickoffset[1]);
1256 // left1 16, 48 : 126 -66
1257 // left2 16, 128 : 196 -66
1258 // right 176, 48 : 196 -136
1259 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);
1260 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);
1261 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);
1262 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1264 float scale = 128.0f / 256.0f;
1265 float healthstart, healthheight, healthstarttc, healthendtc;
1266 float shieldstart, shieldheight, shieldstarttc, shieldendtc;
1267 float ammostart, ammoheight, ammostarttc, ammoendtc;
1268 float clipstart, clipheight, clipstarttc, clipendtc;
1269 float kickoffset[3], offset;
1270 VectorClear(kickoffset);
1273 kickoffset[0] = (v_dmg_time/v_kicktime.value*v_dmg_roll) * 10 * scale;
1274 kickoffset[1] = (v_dmg_time/v_kicktime.value*v_dmg_pitch) * 10 * scale;
1276 sbar_x = (vid_conwidth.integer - 256 * scale)/2 + kickoffset[0];
1277 sbar_y = (vid_conheight.integer - 256 * scale)/2 + kickoffset[1];
1278 offset = 0; // TODO: offset should be controlled by recoil (question: how to detect firing?)
1279 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);
1280 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);
1281 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);
1282 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);
1283 healthheight = cl.stats[STAT_HEALTH] * (152.0f / 300.0f);
1284 shieldheight = cl.stats[STAT_ARMOR] * (152.0f / 300.0f);
1285 healthstart = 204 - healthheight;
1286 shieldstart = healthstart - shieldheight;
1287 healthstarttc = healthstart * (1.0f / 256.0f);
1288 healthendtc = (healthstart + healthheight) * (1.0f / 256.0f);
1289 shieldstarttc = shieldstart * (1.0f / 256.0f);
1290 shieldendtc = (shieldstart + shieldheight) * (1.0f / 256.0f);
1291 ammoheight = cl.stats[STAT_SHELLS] * (62.0f / 200.0f);
1292 ammostart = 114 - ammoheight;
1293 ammostarttc = ammostart * (1.0f / 256.0f);
1294 ammoendtc = (ammostart + ammoheight) * (1.0f / 256.0f);
1295 clipheight = cl.stats[STAT_AMMO] * (122.0f / 200.0f);
1296 clipstart = 190 - clipheight;
1297 clipstarttc = clipstart * (1.0f / 256.0f);
1298 clipendtc = (clipstart + clipheight) * (1.0f / 256.0f);
1299 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);
1300 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);
1301 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);
1302 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);
1303 DrawQ_Pic(sbar_x + 0 * scale, sbar_y + 0 * scale, zymsb_crosshair_background, 256 * scale, 256 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1304 DrawQ_Pic(sbar_x + 120 * scale, sbar_y + 120 * scale, zymsb_crosshair_center, 16 * scale, 16 * scale, 1, 1, 1, 1, DRAWFLAG_NORMAL);
1307 else // Quake and others
1309 sbar_y = vid_conheight.integer - SBAR_HEIGHT;
1310 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1311 //if (cl.gametype == GAME_DEATHMATCH && gamemode != GAME_TRANSFUSION)
1312 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1315 sbar_x = (vid_conwidth.integer - 320)/2;
1319 if (gamemode != GAME_GOODVSBAD2)
1320 Sbar_DrawInventory ();
1321 if (!cl.islocalgame && gamemode != GAME_TRANSFUSION)
1325 if (sb_showscores || (cl.stats[STAT_HEALTH] <= 0 && cl_deathscoreboard.integer))
1327 if (gamemode != GAME_GOODVSBAD2)
1328 Sbar_DrawAlphaPic (0, 0, sb_scorebar, sbar_alpha_bg.value);
1329 Sbar_DrawScoreboard ();
1333 Sbar_DrawAlphaPic (0, 0, sb_sbar, sbar_alpha_bg.value);
1335 // keys (hipnotic only)
1336 //MED 01/04/97 moved keys here so they would not be overwritten
1337 if (gamemode == GAME_HIPNOTIC)
1339 if (cl.stats[STAT_ITEMS] & IT_KEY1)
1340 Sbar_DrawPic (209, 3, sb_items[0]);
1341 if (cl.stats[STAT_ITEMS] & IT_KEY2)
1342 Sbar_DrawPic (209, 12, sb_items[1]);
1345 if (gamemode != GAME_GOODVSBAD2)
1347 if (cl.stats[STAT_ITEMS] & IT_INVULNERABILITY)
1349 Sbar_DrawNum (24, 0, 666, 3, 1);
1350 Sbar_DrawPic (0, 0, sb_disc);
1354 if (gamemode == GAME_ROGUE)
1356 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1357 if (cl.stats[STAT_ITEMS] & RIT_ARMOR3)
1358 Sbar_DrawPic (0, 0, sb_armor[2]);
1359 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR2)
1360 Sbar_DrawPic (0, 0, sb_armor[1]);
1361 else if (cl.stats[STAT_ITEMS] & RIT_ARMOR1)
1362 Sbar_DrawPic (0, 0, sb_armor[0]);
1366 Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, cl.stats[STAT_ARMOR] <= 25);
1367 if (cl.stats[STAT_ITEMS] & IT_ARMOR3)
1368 Sbar_DrawPic (0, 0, sb_armor[2]);
1369 else if (cl.stats[STAT_ITEMS] & IT_ARMOR2)
1370 Sbar_DrawPic (0, 0, sb_armor[1]);
1371 else if (cl.stats[STAT_ITEMS] & IT_ARMOR1)
1372 Sbar_DrawPic (0, 0, sb_armor[0]);
1381 Sbar_DrawNum (136, 0, cl.stats[STAT_HEALTH], 3, cl.stats[STAT_HEALTH] <= 25);
1384 if (gamemode == GAME_ROGUE)
1386 if (cl.stats[STAT_ITEMS] & RIT_SHELLS)
1387 Sbar_DrawPic (224, 0, sb_ammo[0]);
1388 else if (cl.stats[STAT_ITEMS] & RIT_NAILS)
1389 Sbar_DrawPic (224, 0, sb_ammo[1]);
1390 else if (cl.stats[STAT_ITEMS] & RIT_ROCKETS)
1391 Sbar_DrawPic (224, 0, sb_ammo[2]);
1392 else if (cl.stats[STAT_ITEMS] & RIT_CELLS)
1393 Sbar_DrawPic (224, 0, sb_ammo[3]);
1394 else if (cl.stats[STAT_ITEMS] & RIT_LAVA_NAILS)
1395 Sbar_DrawPic (224, 0, rsb_ammo[0]);
1396 else if (cl.stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
1397 Sbar_DrawPic (224, 0, rsb_ammo[1]);
1398 else if (cl.stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
1399 Sbar_DrawPic (224, 0, rsb_ammo[2]);
1403 if (cl.stats[STAT_ITEMS] & IT_SHELLS)
1404 Sbar_DrawPic (224, 0, sb_ammo[0]);
1405 else if (cl.stats[STAT_ITEMS] & IT_NAILS)
1406 Sbar_DrawPic (224, 0, sb_ammo[1]);
1407 else if (cl.stats[STAT_ITEMS] & IT_ROCKETS)
1408 Sbar_DrawPic (224, 0, sb_ammo[2]);
1409 else if (cl.stats[STAT_ITEMS] & IT_CELLS)
1410 Sbar_DrawPic (224, 0, sb_ammo[3]);
1413 Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, cl.stats[STAT_AMMO] <= 10);
1417 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1418 //if (vid_conwidth.integer > 320 && cl.gametype == GAME_DEATHMATCH)
1419 if (!cl.islocalgame && vid_conwidth.integer > 320)
1421 if (gamemode == GAME_TRANSFUSION)
1422 Sbar_MiniDeathmatchOverlay (0, 0);
1424 Sbar_MiniDeathmatchOverlay (324, vid_conheight.integer - sb_lines);
1431 if (cl.csqc_vidvars.drawcrosshair && crosshair.integer >= 1 && crosshair.integer <= NUMCROSSHAIRS && !cl.intermission && !r_letterbox.value && (pic = r_crosshairs[crosshair.integer]))
1432 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);
1434 if (cl_prydoncursor.integer)
1435 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);
1438 //=============================================================================
1442 Sbar_DeathmatchOverlay
1446 float Sbar_PrintScoreboardItem(scoreboard_t *s, float x, float y)
1450 minutes = (int)((cl.intermission ? cl.completed_time - s->qw_entertime : cl.time - s->qw_entertime) / 60.0);
1451 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1453 if (s->qw_spectator)
1455 if (s->qw_ping || s->qw_packetloss)
1456 DrawQ_String(x, y, va("%4i %3i %4i spectator %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1458 DrawQ_String(x, y, va(" %4i spectator %c%s", minutes, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1462 // draw colors behind score
1463 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1464 DrawQ_Fill(x + 14*8, y+1, 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);
1465 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1466 DrawQ_Fill(x + 14*8, y+4, 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);
1468 //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, NULL, true);
1469 if (s->qw_ping || s->qw_packetloss)
1470 DrawQ_String(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, false );
1472 DrawQ_String(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, false );
1477 if (s->qw_spectator)
1479 if (s->qw_ping || s->qw_packetloss)
1480 DrawQ_String(x, y, va("%4i %3i spect %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1482 DrawQ_String(x, y, va(" spect %c%s", (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1486 // draw colors behind score
1487 c = (unsigned char *)&palette_complete[(s->colors & 0xf0) + 8];
1488 DrawQ_Fill(x + 9*8, y+1, 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);
1489 c = (unsigned char *)&palette_complete[((s->colors & 15)<<4) + 8];
1490 DrawQ_Fill(x + 9*8, y+4, 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);
1492 //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, NULL, true);
1493 if (s->qw_ping || s->qw_packetloss)
1494 DrawQ_String(x, y, va("%4i %3i %5i %c%s", bound(0, s->qw_ping, 9999), bound(0, s->qw_packetloss, 99), (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1496 DrawQ_String(x, y, va(" %5i %c%s", (int) s->frags, (s - cl.scores) == cl.playerentity - 1 ? 13 : ' ', s->name), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1502 void Sbar_DeathmatchOverlay (void)
1506 // request new ping times every two second
1507 if (cl.last_ping_request < realtime - 2 && cls.netcon)
1509 cl.last_ping_request = realtime;
1510 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1512 MSG_WriteByte(&cls.netcon->message, qw_clc_stringcmd);
1513 MSG_WriteString(&cls.netcon->message, "pings");
1515 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*/)
1517 // 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
1518 static int ping_anyway_counter = 0;
1519 if(cl.parsingtextexpectingpingforscores == 1)
1521 Con_DPrintf("want to send ping, but still waiting for other reply\n");
1522 if(++ping_anyway_counter >= 5)
1523 cl.parsingtextexpectingpingforscores = 0;
1525 if(cl.parsingtextexpectingpingforscores != 1)
1527 ping_anyway_counter = 0;
1528 cl.parsingtextexpectingpingforscores = 1; // hide the output of the next ping report
1529 MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
1530 MSG_WriteString(&cls.netcon->message, "ping");
1535 // newer server definitely has pings command, so use it for more efficiency, avoids ping reports spamming the console if they are misparsed, and saves a little bandwidth
1536 MSG_WriteByte(&cls.netcon->message, clc_stringcmd);
1537 MSG_WriteString(&cls.netcon->message, "pings");
1541 DrawQ_Pic ((vid_conwidth.integer - sb_ranking->width)/2, 8, sb_ranking, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1547 if (cls.protocol == PROTOCOL_QUAKEWORLD)
1549 x = (vid_conwidth.integer - (26 + 15) * 8) / 2; // 26 characters until name, then we assume 15 character names (they can be longer but usually aren't)
1550 DrawQ_String(x, y, va("ping pl%% time frags team name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1554 x = (vid_conwidth.integer - (16 + 15) * 8) / 2; // 16 characters until name, then we assume 15 character names (they can be longer but usually aren't)
1555 DrawQ_String(x, y, va("ping pl%% frags name"), 0, 8, 8, 1, 1, 1, 1 * sbar_alpha_fg.value, 0, NULL, false );
1559 if (Sbar_IsTeammatch ())
1561 // show team scores first
1562 for (i = 0;i < teamlines && y < vid_conheight.integer;i++)
1563 y += (int)Sbar_PrintScoreboardItem((teams + teamsort[i]), x, y);
1567 for (i = 0;i < scoreboardlines && y < vid_conheight.integer;i++)
1568 y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1573 Sbar_DeathmatchOverlay
1577 void Sbar_MiniDeathmatchOverlay (int x, int y)
1581 // decide where to print
1582 if (gamemode == GAME_TRANSFUSION)
1583 numlines = (vid_conwidth.integer - x + 127) / 128;
1585 numlines = (vid_conheight.integer - y + 7) / 8;
1587 // give up if there isn't room
1588 if (x >= vid_conwidth.integer || y >= vid_conheight.integer || numlines < 1)
1595 for (i = 0; i < scoreboardlines; i++)
1596 if (fragsort[i] == cl.playerentity - 1)
1601 i = min(i, scoreboardlines - numlines);
1604 if (gamemode == GAME_TRANSFUSION)
1606 for (;i < scoreboardlines && x < vid_conwidth.integer;i++)
1607 x += 128 + (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1611 for (;i < scoreboardlines && y < vid_conheight.integer;i++)
1612 y += (int)Sbar_PrintScoreboardItem(cl.scores + fragsort[i], x, y);
1618 Sbar_IntermissionOverlay
1622 void Sbar_IntermissionOverlay (void)
1627 // LordHavoc: changed to draw the deathmatch overlays in any multiplayer mode
1628 //if (cl.gametype == GAME_DEATHMATCH)
1629 if (!cl.islocalgame)
1631 Sbar_DeathmatchOverlay ();
1635 sbar_x = (vid_conwidth.integer - 320) >> 1;
1636 sbar_y = (vid_conheight.integer - 200) >> 1;
1638 DrawQ_Pic (sbar_x + 64, sbar_y + 24, sb_complete, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1639 DrawQ_Pic (sbar_x + 0, sbar_y + 56, sb_inter, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);
1642 dig = (int)cl.completed_time / 60;
1643 Sbar_DrawNum (160, 64, dig, 3, 0);
1644 num = (int)cl.completed_time - dig*60;
1645 if (gamemode != GAME_NEXUIZ)
1646 Sbar_DrawPic (234,64,sb_colon);
1647 Sbar_DrawPic (246,64,sb_nums[0][num/10]);
1648 Sbar_DrawPic (266,64,sb_nums[0][num%10]);
1650 Sbar_DrawNum (160, 104, cl.stats[STAT_SECRETS], 3, 0);
1651 if (gamemode != GAME_NEXUIZ)
1652 Sbar_DrawPic (232, 104, sb_slash);
1653 Sbar_DrawNum (240, 104, cl.stats[STAT_TOTALSECRETS], 3, 0);
1655 Sbar_DrawNum (160, 144, cl.stats[STAT_MONSTERS], 3, 0);
1656 if (gamemode != GAME_NEXUIZ)
1657 Sbar_DrawPic (232, 144, sb_slash);
1658 Sbar_DrawNum (240, 144, cl.stats[STAT_TOTALMONSTERS], 3, 0);
1669 void Sbar_FinaleOverlay (void)
1671 DrawQ_Pic((vid_conwidth.integer - sb_finale->width)/2, 16, sb_finale, 0, 0, 1, 1, 1, 1 * sbar_alpha_fg.value, 0);